Notifications
Clear all

[Closed] Increase Skin Weight

 MZ1

I want to create a function to increase vertex weight by five percent exactly like what the button in the Skin Weight Tool is doing.

SkinWeightTool

From Max Help about this button:

+/-
Increases/decreases each selected vertex's weight by five percent.

And this is my first try:

fn PrepareModifyPanel Obj Md: =
(
	if selection.count != 1 or selection[1] != Obj do select Obj
	max modify mode
	if Md != unsupplied and Md != undefined and modPanel.getCurrentObject() != Md do modPanel.setCurrentObject Md
	resumeEditing()
	classof Obj
)

Obj = $LForeArm
MyBoneID = 2
Md = Obj.Skin
PrepareModifyPanel Obj Md:Md
VertsCount = skinops.getNumberVertices Md
for v = 1 to VertsCount do
(
	Weights = #()
	BoneIDs = #()
	for i = 1 to skinOps.GetVertexWeightCount Md v do
	(
		append Weights (skinOps.GetVertexWeight Md v i)
		append BoneIDs (skinOps.GetVertexWeightBoneID Md v i)
	)
	BoneID = finditem BoneIDs MyBoneID
	if BoneID != 0 do
	(
		Weight = Weights[BoneID]
		Weight = Weight + (Weight * 0.05)
		if Weight > 1 do Weight = 1
		Weights[BoneID] = Weight
	)
	skinOps.ReplaceVertexWeights Md v BoneIDs Weights
)

It seems this code works as expected, but when I compare it with the button, result is not the same.

2 Replies

If I change the line with skinOps.ReplaceVertexWeights with SetVertexWeights then it works as you intend. Note that I also use BoneID and Weight and not the arrays. See below.I think the problem is that you were adding 5% to your target bone, but not subtracting 5% from the rest of the bones.

In general, use ReplaceVertexWeights when you want to remove or add bone’s influence to a vertex, and use SetVertexWeights when you just want to change weighting of existing influence bones.


skinOps.SetVertexWeights Md v BoneID Weight

I also took a stab at making the script a little faster:


(
	t1 = timestamp()
	
	MyBoneID = 2
	
	--Bookmark functions in the vertex loop
	GetVertexWeightCount = skinOps.GetVertexWeightCount
	GetVertexWeight = skinOps.GetVertexWeight
	GetVertexWeightBoneID = skinOps.GetVertexWeightBoneID
	SetVertexWeights = skinOps.SetVertexWeights

	Md = modPanel.getCurrentObject()
	
	if classof Md == Skin do
	(
		--Close WeightTool to speed up the script
		wTool = skinOps.isWeightToolOpen Md
		if wTool do skinOps.closeWeightTool Md
		
		VertsCount = skinops.getNumberVertices Md
		
		for v = 1 to VertsCount do
		(
			for i = 1 to (GetVertexWeightCount Md v) where (BoneID = (GetVertexWeightBoneID Md v i)) == MyBoneID do
			(
				SetVertexWeights Md v BoneID ((GetVertexWeight Md v i) * 1.05)
			)
		)
		
		--Open the tool if it was open
		if wTool do skinOps.WeightTool Md
	)
	
	
	t2 = timestamp()
	
	format "%ms
" (t2-t1)
)

1 Reply
 MZ1
(@mz1)
Joined: 11 months ago

Posts: 0

Nice explanation and optimization Thank You! I didn’t know calling function from a structure in loop takes that much time.