This one is doing my head in.
Ive posted this in the Discreet Area (why its no longer just support, I dunno
.)
Due to the scale I'm working at, the Max skin mirroring won't work (no, I can't change scale).
I've written a working mirror script, where I select a vert, copy it, then select a vert to paste to and it correctly mirrors the bones and weights. However, this is a bit slow, so what I thought was I could select a bunch of verts, where the odd numbered selection was the 'copy from' vert, and the even numbers are the 'paste to'. Then I could loop through the list, copying 1 to 2, 3 to 4, etc.
However, even though the listener can show me my selected vert array, I cannot seem to access this information.
this is what I get in the listener when I select two verts
skinOps.SelectVertices $.modifiers[#Skin] #{502, 510}
I must be able to extract that array somehow?
Replies
Skin2Physique
Mirror Physique
To answer your question directly. There's no function to get an array of selected vertices in skin, so you can make one.
<font class="small">Code:</font><hr /><pre>fn GetSelectedSkinVerts =
(
vSkinVertArray = #()
for v = 1 to skinOps.GetNumberVertices $.skin do
(
if skinOps.IsVertexSelected $.skin v == 1 do
(
append vSkinVertArray v
)
)
return vSkinVertArray
)</pre><hr />
Also make sure it's not something simple that's screws the mirror mode up, like reseting x-forms or the model not centered on X.
<font class="small">Code:</font><hr /><pre>
skinMod = modPanel.getCurrentObject()
numVerts = skinOps.getNumberVertices skinMod
vertsArr = #{}
for i = 1 to numVerts do (
if (skinops.isVertexSelected skinMod i) == 1 then append vertsArr i
)
</pre><hr />
Why there's no "skinOps.getSelectedVertices" command I have no idea.
1. Uncheck "always deform" in the advanced options of the skin modifier.
2. Scale your selection, (only binded mesh ), with the "rescale world units" utility like 100x bigger, (scaling numeric would work, too probably, but I always used the utiliy ).
3. Mirror your skinweights. Should work fine now. If not try to scale up your mesh even more or check if you need to mirror your envelopes first.
4. Rescale to your original size, (x0,01 for this example). 5. Check "always deform" again.
Anyway, I've come up with a possible solution, which is a work in progress...I'll explain it after ranting
Basically, what I want cannot be done - maxscript has holes. The solutions posted are the same as the one I have already - select a vert, then cycle through all the verts in the skin modifier to see if I have got them selected.
This method works, but its an ugly hack, since in the maxscript listener it tells me what verts I have selected, so MAX KNOWS! It's there, in text, on the screen. It's taunting me.
The reason the loop won't work is that I have to select the verts in order, and store them in array, so I pick the source vert then the target, then another source and another target etc. With this array I copy 1 to 2, 3 to 4, 5 to 6 etc. Using the looping method reorders all the verts.
Now, the vert ids are the same in the skin modifier as they are in the poly/mesh, but guess what - when in skin you can't use the poly/mesh vert identification methods any more.
At the moment the script I have written requires you to select a vert, press copy, select a vert, press paste. It works perfectly but it is slow.
Now, my solution to the problem.
I want to be able to mirror whilst the mesh is deforming, so that I can check the mirror has worked.
So, I have 2 buttons in my rollout - create emesh and perform copy. Create emesh sticks an edit mesh modifer on the stack above my skin modifier, so I can see all the deformation. I can select my array of pairs of weights here.
I already have working copy and paste functions (with mirror) in my current script, they just take a vert id.
So now, after I've selected all my weights, I press the 'perform copy' It sotres my vert selection in an array, deletes the mesh modifier and goes back to the skin modifier. Then its just a simple loop - get the information from vert 1, calculate the mirrorbones, paste that to vert number 2. Then 3 to 4, 5 to 6 etc.
It works.
But it'd be a lot cleaner if there was just a skinop.getvertselection command.
I just remembered I was facing the same ordeal about a year ago. What I did was make a script that made a dummy at every bone. Scaled up a cloned model and the dummy bone system. Reset X-forms on the clone. Weighted my cloned model to the dummies. Used my Skin2Physique to save the weights out by vertex number, and import them on the little one. Same shit, different pile.
The joys of rigging...
<font class="small">Code:</font><hr /><pre>
vHalfVertCount = VertArray.count/2
for vert = 1 to vHalfVertCount do
(
pastweight vert (vert + vHalfVertCount)
)
</pre><hr />
It would take a little reworking of your script bit it seams it would be much faster afterwards.
Just a suggestion. So no need call out my ignorance if I misunderstood something.
And cutting the array in half seemed like a good idea at first, but then I thought the user would have to remember in what order he selected the first half and select the second half in the same order. Probably tough to do after a certain number of verts, but still doable. Good idea if it can work.