3dmax skin copy paste

it’s simple task, but none of the actual skinning information is carried over.

Array loop(

1: Get object
2: copy skin
3: collapse stacks
4.paste skin
)

On Looping pressed do (

	varArrayMainsel = selection as array
	
for obj in varArrayMainsel do (
	lModifier = copy obj.modifiers[#Skin] --copy
	objname=obj.name
	format "% select  and copy \n" objname 
	
	maxOps.CollapseNode obj off --Collapse stacks
		format "% modifiers callapsed  \n" objname 
	
	
	addModifier obj lModifier --paste
			format "% skin pasted  \n" objname 
	)
	
)

How can I change it?
Right click of more than 500 objects is painful :cold_sweat:

What version of max are you using?
The only thing I can think of is that you shouldn’t need to copy the skin modifier.
Just storing a reference to the instance should work.

Maybe you can use “skin wrap” and and a second mesh.

Skin wrap can be very inconsistent in transfering identical skin weights.
It might be an update issue, try calling redrawViews() before applying the skin modifier back onto the object.

using 2016
Is there any other way?

You could try a variety of the following:

-- make the modify panel active, as the skin modifier is fussy like that:
SetCommandPanelTaskMode #Modify
-- cache Selection as we will be selecting objects in the for loop,
-- otherwise you don't need to cache it as it is already itterable:
sel = Selection as array.
for obj in sel do
(
    -- only need a reference to the skin modifier:
    local skinMod = obj.Modifiers[Skin]
    if skinMod != Undefined do
    (
        -- option 1: convert to an editable poly or mesh with editable_mesh:
        ConvertTo obj editable_poly 
        -- option 2: collapse all modifiers below the skin modifier.
        -- Not sure if that is what you want. Just need to get the index of
        -- the skin modifier, but it is safe to assume it is at the top, so 1:
        MaxOps.CollapseNodeTo obj 1 True
        -- option 3: your current code:
        MaxOps.CollapseNode obj False
        -- enable for options 1 and 3:
        -- Select obj
        -- AddModifier obj skinMod
        -- try forcing a viewport redraw:
        -- RedrawViews()
    )
)

If you are going with option 1 or 3, you might want to wrap the for loop in a with Redraw False context manager to speed things up:

with Redraw False
(
    -- code here
)

You can also cache any struct based method calls outside of the for loop to further improved performance:

ColNodeTo = MaxOps.CollapseNodeTo
ColNode = MaxOps.CollapseNode

I hope its fine to reply here 2 years later…

Got the same Issue. Munkybutts options worked partly for me. All of them are slighty messing up the weights(i think) of my model. However if i do it manually(copy skin, collapse, paste skin), then it works like intended.

This is how it looks like:
9008bb4bdd1cb875c5a5c311e149716a

However it should look like this:

Anyone got any idea? :confused:

As your model is very low poly, you can copy and paste the weights directly, this requires no change to topology or vert order though.
Here are two functions written in mxs for testing performance in my skinning plugin that will allow you to do that:
https://github.com/munkybutt/SkinPlusPlus/blob/main/test/test.ms#L3

fn mxsGetSkinWeights node = (
	skops = SkinOps()
	skopGetVertexWeight = skops.GetVertexWeight
	skopGetVertexWeightCount = skops.GetVertexWeightCount
	skopGetVertexWeightBoneID = skops.GetVertexWeightBoneID
	-- skopReplaceVertexWeights = skops.ReplaceVertexWeights
	-- skinOps.ReplaceVertexWeights <Skin> <vertex_integer> \ ( <vertex_bone_integer> | <vertex_bone_array> ) \
 	-- ( <weight_float> | <weight_array> )  [(node:<node> | name:<string>)]
	skinModifier = node.Modifiers[Skin]
	vertexCount = skops.GetNumberVertices(skinModifier)
	skinWeights = #()
	skinBoneIDs = #()
	for vertexIndex = 1 to vertexCount do
	(
		influenceCount = skopGetVertexWeightCount skinModifier vertexIndex
		vertexWeights = for influenceIndex = 1 to influenceCount collect skopGetVertexWeight skinModifier vertexIndex influenceIndex
		vertexBoneIDs = for influenceIndex = 1 to influenceCount collect skopGetVertexWeightBoneID skinModifier vertexIndex influenceIndex
		Append skinWeights vertexWeights
		Append skinBoneIDs vertexBoneIDs
	)

	#(skinWeights, skinBoneIDs)
)

fn mxsSetSkinWeights node boneIDs weights = (
	skops = SkinOps()
	skopGetVertexWeight = skops.GetVertexWeight
	skopGetVertexWeightCount = skops.GetVertexWeightCount
	skopGetVertexWeightBoneID = skops.GetVertexWeightBoneID
	skopReplaceVertexWeights = skops.ReplaceVertexWeights
	-- skinOps.ReplaceVertexWeights <Skin> <vertex_integer> \ ( <vertex_bone_integer> | <vertex_bone_array> ) \
 	-- ( <weight_float> | <weight_array> )  [(node:<node> | name:<string>)]
	skinModifier = node.Modifiers[Skin]
	vertexCount = skops.GetNumberVertices(skinModifier)
	for vertexIndex = 1 to vertexCount do
	(
		skopReplaceVertexWeights skinModifier vertexIndex boneIDs[vertexIndex] weights[vertexIndex]
	)
)

Thanks, it works well :slight_smile:

Nps - glad it helped