I'd like to do the following in max (version 7)
In the skin modifier, select a vert and hit a button that creates a data set of all bones and weights of that vert.
Then select another vert, and hit paste - the data gets copied.
There would be a mirror option too, if if was enabled the the bones used would be mirrored, so L_Clavicle would become R_Clavicle etc.
Any ideas?
First things first. This code will select a specic vert:
skinOps.SelectVertices $.modifiers[#Skin] #{XXX}
where XXX is the vert I want selected. I cant seem to select a vert however, and have max tell me the id number of the vert I have selected.
I need that because this:
skinOps.GetVertexWeightCount $.modifiers[#Skin] XXX
Tells me how many bones that vert is weighted to.
THen once I know how many, I can use this:
skinOps.GetVertexWeightBoneID
to get the id numbers of those bones
skinOps.SetVertexWeights will be used to set the weight
So, i've tried to doa little work, but I'm stuck at hte start.
Any help?
Replies
<font class="small">Code:</font><hr /><pre>skinMod = selection[1].modifiers[#Skin]
n = skinOps.getNumberVertices skinMod
selVert = 0
for i = 1 to n do (if skinops.isVertexSelected skinMod i == 1 then selVert = i)
selVert</pre><hr />
In the interest of meing nice, here is the script too.
Why did I write this? Well, max 7 has a skin weight mirror facility. Unfortunatley the scale I have to work at means that the threshold value is often too small, and I always have a few weights that won't copy - 0.001 is too small, 0.002 is too big.
This script will let you select a vert, press copy, then select a vert and press paste. It automatically mirrors.
you MAY need to change the mirroring section depending on your bones names.
global BoneArray
global BoneNArray
global WeightArray
global PasteArray
-- Pass the vert id to extract all the weights to arrays
fn CopyWeight theVert =
(
-- Empty the arrays
BoneArray = #()
BoneNArray =#()
WeightArray = #()
theSkin = $.modifiers[#skin]
BNumber = skinOps.getVertexWeightCount theSkin theVert
BN = BNumber as string
for i = 1 to BNumber do
(
boneID = skinOps.getVertexWeightBoneId theSkin theVert i
boneName = skinOps.GetBoneName theSkin boneID 0
boneWeight = skinOps.getVertexWeight theSkin theVert i
append BoneArray boneID
append BoneNArray boneName
append WeightArray boneWeight
)
)
fn PasteWeight pVert =
(
disableSceneredraw()
theSkin = $.modifiers[#skin]
print "these are the stored arrays for copying"
print pastearray
print weightarray
skinOps.ReplaceVertexWeights theskin pVert pasteArray WeightArray
enableSceneredraw()
redrawViews()
)
fn find_mirror arrayIndex =
(
-- Build arrays of all the bones in the system
theSkin = $.modifiers[#skin]
totalbones = skinops.getnumberbones theSkin
totalBoneNArray =#()
for i = 1 to totalbones do
(
boneName = skinOps.GetBoneName theSkin i 0
append totalBoneNArray boneName
)
-- Now we know all the bones, lets parse of list of weighted bones
SB = BoneNArray[arrayIndex] as string
boneToFind=SB
-- Find bone names beginning with CHAR
if (substring SB 1 4 == "Char") then
(
BNprefix=substring SB 1 7 as string
BNsuffix= substring SB 8 255 as string
newPrefix=BNprefix
if BNprefix == "Char L " then newPrefix= "Char R "
if BNprefix == "Char R " then newPrefix= "Char L "
boneToFind = newPrefix + BNsuffix
)
if (substring SB 2 1 == " ") then
(
BNprefix=substring SB 1 2 as string
BNsuffix= substring SB 3 255 as string
newPrefix=BNprefix
if BNprefix == "L " then newPrefix= "R "
if BNprefix == "R " then newPrefix= "L "
boneToFind = newPrefix + BNsuffix
)
-- ok, at this stage we have an arracy of bone names, and we know what name
-- we are looking for. so cycle the array and find the index!
theIndex = 0
-- Do we need to find a new bone?
if (boneToFind != SB) then
(
print bonearray
for i = 1 to totalbones do
(
thecheck= totalBoneNArray as string
if thecheck == bonetofind then theIndex = i
)
pasteArray[arrayIndex]=theIndex
)
)
rollout blank "Single Skin Copy and Paste"
(
label lbl1 "Select vert, press copy, then select vert and press paste." pos:[9,8] width:197 height:48
button ButtonC "Copy" pos:[18,40] width:75 height:24
button ButtonP "Paste" pos:[110,40] width:75 height:24
on ButtonP pressed do
(
theSkin = selection[1].modifiers[#Skin]
n = skinOps.getNumberVertices theSkin
selVert=0
for i = 1 to n do
(
if (skinops.isVertexSelected theSkin i == 1) then
(
selVert=i
)
)
-- Call the copy function
PasteWeight selVert
)
on ButtonC pressed do
(
-- Get vert id
theSkin = selection[1].modifiers[#Skin]
n = skinOps.getNumberVertices theSkin
selVert=0
for i = 1 to n do
(
if (skinops.isVertexSelected theSkin i == 1) then
(
selVert=i
)
)
-- Call the copy function
CopyWeight selVert
-- We now have 3 arrays - bone id, bone name, and bone weight.
-- some of the bones might need to be mirrored so for each bone, find the possible mirror
n = BoneArray.count
pastearray = bonearray
for i = 1 to n do
(
find_mirror i
)
)
)
-- Create floater
theNewFloater = newRolloutFloater "Rollout title" 220 100
-- Add the rollout section
addRollout blank theNewFloater