importing weights + effectors

Discussions concerning programming of SOFTIMAGE©
bergj
Posts: 36
Joined: 06 May 2012, 03:58

importing weights + effectors

Post by bergj » 24 Jun 2012, 23:06

I've been working on getting the 'Pinocchio' heatbind method into SI. Although I've come extremely close, I can only successfully weight a mesh that has a single chain.

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)


User avatar
Mathaeus
Posts: 1778
Joined: 08 Jun 2009, 19:11
Location: Zagreb, Croatia

Re: importing weights + effectors

Post by Mathaeus » 25 Jun 2012, 00:21

you can't remove effector from bone chain. However, as you probably know, in Softimage ( and 3d Studio Max as well, btw), you can assign envelope to nulls too, or anything that have kinematics property. So there is a chance you'll get it cleaner if you use only nulls. Default weight assignment is different than with bones (spherical instead of cylindrical influence), but you're already importing the weights.

BTW if this is the same heat bone thing as in Blender, well maybe it's good idea to take look at Softimage's weight painting ans smoothing tools, instead...

EricTRocks
Moderator
Posts: 754
Joined: 25 Nov 2009, 00:41

Re: importing weights + effectors

Post by EricTRocks » 25 Jun 2012, 04:06

Mathaeus got it head on. Pinnochio is built from a Maya type method of bones / joints where the root / effector has no affect on the envelope. In xsi default joint chains, the root and effector get added to the envelope (though hidden in the tools). Through scripting if you print them out you'll see them. You can also remove them through scripting but will see the adverse affects. In XSI you get that nice stretch by default.

However it is highly recommended for rigs to use null objects as envelope deformers instead of joints as joint chains can kill performance the more and more you have. Not to mention getting deformed meshes from package to package is much easier if you do it this way as well as the skinning will be accurate across them.
Eric Thivierge
Lead Kraken Developer, Fabric Engine
http://fabric-engine.github.io/Kraken

bergj
Posts: 36
Joined: 06 May 2012, 03:58

Re: importing weights + effectors

Post by bergj » 25 Jun 2012, 17:29

Thanks for the replies, guys. I re-wrote some and made it so that it would zero all the weights before applying the new ones. In fact, Im certain that because I didnt do this before, I was just getting the same linear envelope that I initially set. Im also looking into setting values more accurately in the weight editor.
Mathaeus wrote: BTW if this is the same heat bone thing as in Blender, well maybe it's good idea to take look at Softimage's weight painting ans smoothing tools, instead...
Well. this skinning method has been added to Maya 2013 by AD and Modo 601 and is far superior to linear skinning in the many tests I have done with it and in the projects I have worked on. Im trying to add it here so I wont have to go back to linear skinning when I use XSI

grahamef
Posts: 281
Joined: 23 Jun 2009, 19:01

Re: importing weights + effectors

Post by grahamef » 03 Jul 2012, 18:48

bergj wrote:
Mathaeus wrote: BTW if this is the same heat bone thing as in Blender, well maybe it's good idea to take look at Softimage's weight painting ans smoothing tools, instead...
Well. this skinning method has been added to Maya 2013 by AD and Modo 601 and is far superior to linear skinning in the many tests I have done with it and in the projects I have worked on. Im trying to add it here so I wont have to go back to linear skinning when I use XSI
Bone heat weighting is not an alternative to linear blend skinning, it's just a different way to calculate the initial weight assignment. But if you're going to be repainting and tweaking all the weights anyway, as you might well need to do in production, the initial values are not that important.