MaxScript skinOps.ReplaceVertexWeights unexpected behavior

python
max

#1

Hi,

From the docs: “Any influence weights for the bone(s) that are not specified are erased”.

However unspecified influences do not really have their weight removed… I’ve played with normalization and such, but nothing seems to help much.

I’d like to get the method to work like advertised, since alternate approaches seem to require additional calls, which take time

Cheers,
Sune


#2

Known issue. It was finally fixed in 3dsMax 2017. There’s a patch available for 2016 but if you’re in 2015 you’re out of luck.

Having to make additional calls is the least of your worries… the real issue is having to focus the UI between any interactions with the modifier/skinops, especially if you have to alternate nodes.


#3

Thanks Claudio, great to know!

By focusing the UI between interactions, do you mean having the correct obj and skin mod seleced, as well as being on the modifier panel, or something else?


#4

I was also having some problems with ReplaceVertexWeights. What worked for me is setting the vertex weight to 100% on one of the bones before replacing the weights, like this:

skinOps.ReplaceVertexWeights targetSkinMod targetVertex targetVertexBoneIdList[1] 1.0
skinOps.ReplaceVertexWeights targetSkinMod targetVertex targetVertexBoneIdList sourceVertexWeightList

I haven’t tested it, but if you’re using 2016 they did an update to ReplaceVertexWeights in SP3: http://up.autodesk.com/2016/3DSMAX/3dsMax2016_SP3_Readme_enu.htm?_ga=1.167123518.1412264389.1441042546

The summary just says they fixed “skinOps.ReplaceVertexWeights not working” so not sure what they fixed :):


#5

Why not just pick the source from the Max 2017 SDK samples ( bonesdef etc… ) and backport it to Max 2015 yourself? In this case it even would be only the fixed code modules which would have to be backported. I did so already for other plugins - even for skin once - and it’s not really too much work. Of course deploying that rebuilt plugin in a whole studio is another question …


#6

[QUOTE=Sune;30224]Thanks Claudio, great to know!

By focusing the UI between interactions, do you mean having the correct obj and skin mod seleced, as well as being on the modifier panel, or something else?[/QUOTE]

Precisely. The methods are somehow tied to the UI which boggles the mind…


#7

@spacefrog: Ahh, I didn’t know the samples are the actual plugs in use, nice. Looking at the source for 2015 and 2017, it was pretty easy to spot the culprit :slight_smile:

2015:

// this is same as setVertexWeights - correct? should we call bmd->VertexData[vert]->ZeroWeights() for each vert in vertID?
bmod->SetVertices(bmd,vertID, b, v);

2017

bmd->VertexData[vertID]->ZeroWeights();
bmod->SetVertices(bmd,vertID, b, v;

All working now. This should be a great starting point for doing my own stuff too.

Thanks everyone :slight_smile:


#8

Great :wink:
This way I even successfully backported the dual quaternion skin code ( introduced with Max 2016’s skin modifier ) from the 2016 SDK samples to older 3ds Max versions …
But i guess releasing those improved skin plugins would break some EULA …


#9

Well I decided to roll my own in C++ (things are just so slow and ugly using skinOps…)

However I’ve hit a small wall (being a Max and C++ noob and all). I’ve created an interface and am exposing functions to MSX with FPInterfaceDesc. For one of my functions I’d like to return a tab of tabs (Tab< Tab<int> >) but I’m not sure how to do that.

This is how I currently define my MSX function signature:

FN_1(get_weights, TYPE_INT_TAB,  GetWeights, TYPE_INODE)

As you can see, not a Tab of Tabs :slight_smile:

An alternative might be to return a custom (if possible), though it needs to be something that will flow through to Python as well, using MaxPlus.EvalMaxScript. Hmm… Any pointers?


#10

For speed, I wanted to get the weights of all points in one go. As it turns out, it’s fast enough asking for each vert individually, especially if I do it inside a MaxScript function, that I then call from python.

FYI; Here is a speed comparison of doing many calls to a C++ function exposed to MaxScript in different ways:

Native MaxScript: 0.26 sec
pymxs.runtime (new in 2017): 1.27 sec
MaxPlus.Core.EvalMAXScript: 4.41 sec

The real world difference when reading and writing skin weights is substantial.