Home Technical Talk

Maxscript query

polycounter lvl 18
Offline / Send Message
Rick Stirling polycounter lvl 18
This one is doing my head in.

I’ve posted this in the Discreet ‘Area’ (why it’s 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

  • monster
    Options
    Offline / Send Message
    monster polycounter
    Could you happen to use Phsique? My Skin2Physique can convert the weighting you have already done. Then use my mirror_physique script, then convert back to Skin using the Skin2Physique tool.

    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.
  • FatAssasin
    Options
    Offline / Send Message
    FatAssasin polycounter lvl 18
    This is how I get the selected verts in the Skin modifier:
    <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.
  • Noren
    Options
    Offline / Send Message
    Noren polycounter lvl 19
    Not an answer to your script-question but a workaround:

    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.
  • Rick Stirling
    Options
    Offline / Send Message
    Rick Stirling polycounter lvl 18
    Can't use Physique, cos then I'd be popping in between the two. And physique is guff.

    Anyway, I've come up with a possible solution, which is a work in progress...I'll explain it after ranting smile.gif

    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.
  • monster
    Options
    Offline / Send Message
    monster polycounter
    Yeah, it's a pain. Take comfort in the fact that if there was skinOp.GetVertexSelection that it would return a bitArray in numerical order and not in your selected order, so it wouldn't work anyway. tongue.gif

    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...
  • FatAssasin
    Options
    Offline / Send Message
    FatAssasin polycounter lvl 18
    So how are you getting an array that lists the verts in the order they're selected? All the ways I know of to get vert selections return an array or bitarray in numeric order, not in selection order.
  • Rick Stirling
    Options
    Offline / Send Message
    Rick Stirling polycounter lvl 18
    A coder helped me, I think he is using Callbacks
  • monster
    Options
    Offline / Send Message
    monster polycounter
    Just an idea, because it pains me to think you have to select a verts back and forth (left,right,left,right...). You could select all the ones on the left, then the ones on the right and then get the array count and divide it by 2.

    <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.
  • FatAssasin
    Options
    Offline / Send Message
    FatAssasin polycounter lvl 18
    I'm guessing he's using a viewport redraw callback. That makes sense. I'll have to try that.

    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.
  • Rick Stirling
    Options
    Offline / Send Message
    Rick Stirling polycounter lvl 18
    Yup, the multiple selection might work, but the user would probably screw it up after a few verts. I would, I can't remember what I had for breakfast. Did I have breakfast?
Sign In or Register to comment.