[Closed] Skin modifier – applying the vertex weights
Let the ‘myWeights’ array be the predefined weights for the mesh. I want to set the weight of the n-th vertex to the n-th index of this array. In this example I create a box and a bone – the final result is supposed to be the box, where the bottom four vertices move twice slower than the top ones, while these are twice slower than the movement of my bone. Despite the fact, that the box is pretty much deformed after running the script ( I want it to be the normal box, just the way it’s being created ), I have to manually enter the proper weights via the Weight Table for my vertices to move correctly. Why is that so?
Here’s my script. I’m running it under 3DS Max 9:
myWeights = #(0.25, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5)
-- to ensure the fresh and clean test scene
delete objects
myBox = Box length:40 height:50 width: 80
convertToMesh myBox
myBone = Dummy position:[0,0,25] size:60
mySkin = Skin()
addModifier myBox mySkin
max modify mode
modPanel.setCurrentObject mySkin
--add a bone
skinOps.addBone mySkin myBone 1
--now, every vertex as default has the weight of 1.0
--let's reapply the weights:
for v in 1 to myBox.numVerts do
(
--unnormalize the vertex - otherwise it's going to sum up straight to the 1.0 ( for whatever reason )
skinOps.unNormalizeVertex mySkin v true
skinOps.SetVertexWeights mySkin v 1 myWeights[v]
)
Any ideas covering my script and/or why is it not working as it should, will be much appreciated.
Thomas
just replace the line:
skinOps.SetVertexWeights mySkin v 1 myWeights[v]
with:
skinOps.ReplaceVertexWeights mySkin v 1 myWeights[v]
Thanks! It works like a charm now.
I have one question though: can vertex have a multiple weights to a single bone? I’m asking, because … my test model has it :surprised While looping through the vertex weights I’ve come into this listing:
Vertex 132
Bone 3 Dummy_RFoot 0.24248
Bone 3 Dummy_RFoot 0.25752
Bone 2 Dummy_RArm 0.5
… so the vertex has three weights applied. It would be normal if the first two weights weren’t the same bone :curious: How is it even possible? And … how can I, don’t know, “merge” these two weights into a single one ( I suppose the result will be just the same, right? )?
it’s not possible. It seems like the vertex is assigned to 3 bones, but two of them have the same name “Dummy_RFoot”
i’ve never seen it before but it’s possible!
well… here is how to find the multi-bone referencing case and fix it:
fn findSkinMultiRef sk: =
(
if sk == unsupplied do sk = modpanel.getcurrentobject()
local verts = #{}, bones = #{}
for v=1 to (skinops.GetNumberVertices sk) do
(
bones = #{}
out = off
for b=1 to (skinOps.GetVertexWeightCount sk v) while not out do
(
i = skinOps.GetVertexWeightBoneID sk v b
if bones[i] then verts[v] = out = on else bones[i] = on
)
)
verts
)
fn fixSkinMultiRef sk: =
(
if sk == unsupplied do sk = modpanel.getcurrentobject()
local bones = (), weights = #()
for v in (findSkinMultiRef sk:sk) do
(
count = skinOps.GetVertexWeightCount sk v
bones = #()
weights = #()
for b=1 to count do
(
i = skinOps.GetVertexWeightBoneID sk v b
appendifunique bones i
k = finditem bones i
w = skinOps.GetVertexWeight sk v b
if weights[k] == undefined then weights[k] = w else weights[k] += w
)
skinOps.ReplaceVertexWeights sk v bones weights
)
)
Not possible either. I’ve just run this code:
myObjects = ($Dummy*) as array
for obj in myObjects do print obj.name
… the result list:
"Dummy_Head"
"Dummy_LArm"
"Dummy_LFoot"
"Dummy_RArm"
"Dummy_RFoot"
… so there is nothing wrong with my bones. So it seems I made the impossible! Yeeeah, normally I’d be satisfied, not in this case though. I can send you a scene file if necessary. I need to find out what did I screw up :shrug: And I’ve double checked, it’s not a misspelling. Probably I might have done it manually ( or by accident, since this is the only vertex with the multiple weights ), but if it’s not possible, then … ?
I haven’t encountered it for a while but i can vaguely remember having a problem in the past where i had the same bone in the skin modifier more than once. At the time atfer some testing it seeme as if it was done via maxscript, so I made my bone adding to skin modifier scripting a bit more robust and havent encountered it since.
Thanks! It does exactly what I wanted ( I only had to define appendifunique function, since Max 9.0 doesn’t have it implemented ). I have yet another question of “how is it possible” sort, see the screen shot:
As you can see, I have 5 bones added. However, in the Weight Table the PARENTS of those bones are listed. I don’t know whether it’s just for show ( and in fact they point to the correct bones but Weight Table is messed up ) or not ( and those weights are really associated with the parent bones ). I’ve opened up a listener and put these lines:
mySkin = $.modifiers["skin"]
skinOps.addBone mySkin $tag_origin 1
… and of course a new bone is added. As you can see on the schematic view ( in my screen shot ), this bone is the parent of each bone on the scene. On the modifiers panel the new bone “tag_origin” was added, on the Weight Table however, a new column appeared with … “Scene Root” as a bone at the top of it. When I start the fresh new scene, such a problem does not occur! Only when I use my importer … oh yeah, I forgot to mention it.
I’m writing an importer for one model format so it can import the model, its skeleton, UVs etc. and show it on the scene. Only the skin is left to implement, and I’m struggling with it for weeks already. May running the macro script cause such problems because that’s case here?
PS. Just like before, I’m willing to send a scene file to anyone willing to help me :wavey: Just for you to think I’m not a poser :shrug: Cheers