Notifications
Clear all

[Closed] MaxScript print all vertex weights

Hi,

i try to make a Max Script that prints all vertex weights into a file to load animations. Here is what i got so far:

f = sysinfo.currentDir+"\\file.vw"

rollout progressBarRollout "Progres Bar" width:600
(
	label fileNameLabel f
	button selectFileButton "File"
	button startButton "Start"
	progressbar progress
	
	on selectFileButton pressed do
	(
		f = getSaveFileName caption:"Choose File Name" types:"Vertex Weights(*.vw)"
		if f != undefined then
			fileNameLabel.text = f
	)
	on startButton pressed do
	(
		createFile f
		file = (openFile f mode:"w")
		
		for sel in objects do (
			if((classof sel) == PolyMeshObject) then (
				objSkin = sel.modifiers[#skin]
				boneCountTotal = skinops.getnumberbones objSkin
				vertexCount = sel.numverts
		
				for cvertex = 1 to vertexCount do
				(
					boneCount = skinops.getvertexweightcount objSkin cvertex
					str = ""
					for cbone = 1 to boneCount do
					(
						boneWeight = (skinops.getvertexweight objSkin cvertex cbone)
						boneID = skinops.getvertexweightboneid objSkin cvertex cbone
						if cbone > 1 do
							str = str+" "
						str = str+(boneID as string)+":"+(boneWeight as string)
					)
					print str to:file
					progress.value = 100.0*cvertex/vertexCount
				)
			)
		)
		close file
	)
)

createdialog progressBarRollout

The problem is, that i have to print all boneID and there corresponding names at the beginning of the file. How can i iterate through all existing bones and get their bone name and id?
By running this script i also got some weird output stating that some vertices have two different bone-weights for the same bone id that add up to a bone-weight of 1.

Sorry for the probably bad code, i am new to Max Script.

6 Replies

from mxs help:

skinOps.GetBoneName <Skin> <bone_integer> <nameflag_index>

[left]Returns the name of the indexed bone as a string. where nameflag_index can be 0 or 1. If nameflag_index = 0 the node that holds the transform for this bone is returned; = 1 the name that exists in the list box is returned. If a Bones system is used for the Skin bones, the transform for a bone is held by its parent.

(
	if iskindof (sk = modpanel.getcurrentobject()) Skin do
	(
		for v=1 to skinops.getnumbervertices sk do
		(
			count = skinops.getvertexweightcount sk v 
			format "% => weights:%
" v count
			for k=1 to count do
			(
				weight = skinops.getvertexweight sk v k
				boneid = skinops.getvertexweightboneid sk v k
				bonename = skinops.getbonename sk boneid 0
				format "	weight:% name:% id:%
" weight bonename boneid 
			)
		)
	)
)

[/left]

One question performance: whether it is necessary to put all skinOps methods in local variable as polyOp struct before we use them inside for-loop?

2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

the answer is YES. it will help with performance and as always save the memory.

(@gazybara)
Joined: 11 months ago

Posts: 0

Ok. Thanks. Optimized code

(
	  if iskindof (sk = modpanel.getcurrentobject()) Skin do
	  (
		local skinVerts = skinops.getnumbervertices sk
		local getVertsWC = skinops.getvertexweightcount
		local getVWeight = skinops.getvertexweight
		local getBoneID = skinops.getvertexweightboneid
		local getBoneName = skinops.getbonename
		  for v=1 to skinVerts do
		  (
			  count = getVertsWC sk v 
			  format "% => weights:%
" v count
			  for k=1 to count do
			  (
				  boneid = getBoneID sk v k
				  format "	weight:% name:% id:%
" (getVWeight sk v k) (getBoneName sk boneid 0) boneid 
			  )
		  )
	  )
)

Wow, thanks for the quick reply! The code works!

hi to all
i am trying to load weights and bones form arrays to vertexs in skin modifiers .
the problems is the bones id when i get from vertex and also when i set from list bones
is not mached with Replace function,

when i get bone id from vertex like this

skinops.getvertexweightboneid $.skin 1 1 –== > 35
skinops.getvertexweightboneid $.skin 1 2 –==> 34
i create another arrays like this
name_ID = #(#(“Name_B_2”,14,35),#(“Name_B_1”,12,34))

skinOps.ReplaceVertexWeights $.skin 1 #(49,50) #(0.2,0.8)

i use this way to solve deleted nodes and to find sorted index of bone in list

Name_Stor = #()
Ne_Pos = #()
for i = 1 to ((skinOps.GetNumberBones Skin_Mod) + 20) do
(
try
(
bonename = skinops.getbonename Skin_Mod i 0
Append Name_Stor #(bonename , i)
Append Ne_Pos bonename
sort Ne_Pos
)
catch()
)
for i = 1 to Name_Stor.count do for j = 1 to Ne_Pos.count where Ne_Pos[j] == Name_Stor[i][1] do Name_Stor[i][3] = j

i use name_ID[?][2] for skinOps.ReplaceVertexWeights this works
sometime but some times there is no way findout what is relation bettwen
the getvertexweightboneid and ReplaceVertexWeights for use
can any one help me to …?!