How to create morphs attenuated by weight maps?

Hi, 

Recently I've been creating joint controlled morphs that affect both the base figure and a graft on that figure.
Moreover, as I want the morphs to be controlled by both left and right joints, this effectively means that each obj file needs to be processed into 4 separate morphs (i.e. left and right versions for both the base and the graft).

After a good deal of experience doing this manually (and still having more morphs planned), I've decided to try to automate this process.


After some time learning about Daz scripting (this is my first time scripting in Daz, but I'm fairly proficient with Python, and have non negligible experience with Javascript), I think I've figured out how to automate most steps, but I'm having trouble with spliting morphs into left and right versions. More precisely, the way I do this manually is by using the "Attenuate By" option in Morph Loader Pro with the attenuation given by a weight map on a DFormer on the figure. However, the Daz script documentation on how to attenuate morphs seems rather lacking.

Thanks in advance for any assistance.

 

Comments

  • I'm not sure that Morph loader pro is exposed to scripting, so you'd have to write your own attenuation code - you should be able to get the deltas and attenuate them (that is, reduce them - though from your description I suspect you just need to seelctively zero them) and use the verteices' position to figure out if they are left or right. Shape Splitter can do it, and I think that's a script rather than a plug-in (or was initially). I did once start a similar splitting script in DS 3 and although it didn't get far it was possible, or at least looking possible.

  • LAPLAP Posts: 3
    edited February 2021

    Hi Richard, thanks for your time and insight.

    After playing around with this, I'm half convinced that internally the Morph Loader Pro is just passing settings to the DzMorphLoader() object, for the following reasons: most settings in Morph Loader Pro correspond to DzMorphLoader settings in obvious ways and; when setting up a morph incorrectly (either due to wrong settings or incompatible geometry in the obj file), one gets the exact same error messages in Morph Loader Pro as in DzMorphLoader().
    The only non-obvious part is how to feed the "Attenuate By" data from a weight map into DzMorphLoader(). The natural (and only) guess is that this is done via the setAttenuateMapPath method for DzMorphLoader(), but this method requires as input a string "mapPath", and I could find no usable information as to what this path should look like.

    So after banging my head on the wall trying to see if I could find a mapPath somewhere for reference, I went along the lines of what you suggested and wrote my own attenuation code. The keys were a MCasual script, which taught me how to modify morphs at the level of deltas, and a bit more digging on the documentation to track down how to read weights.

    In the hopes that this will help the next guy who runs into a similar issue, here's a no frills script for attenuating an already existing morph by an existing weight map in a DFormer.

    P.S.: After some testing, it seems like the code below attenuates a morph in the exact same way as the Morph Loader Pro does (i.e. this code and "Attenuate By" produce exactly the same morph), so that's neat.
     

    // Script for attenuating an existing morph// according to a weight map stored on a DFormer// With the figure/prop selected,// the following finds the deltas for// an existing morph "initial_morph"var node = Scene.getPrimarySelection();var obj = node.getObject();var morph = obj.findModifier( "initial_morph" );var deltas = morph.getDeltas();// Given the DFormer "my_DFormer" (not the base nor the field),// the following finds the weights associated to the DFormervar deformer = Scene.findNodeByLabel("my_DFormer")var modifier = deformer.getModifier(0)var weights = modifier.getInfluenceWeights()// The following creates the deltas for the new morph "new_morph",// attenuated by the field on the DFormervar newDeltas = new DzMorphDeltas();for (i=0; i<deltas.getNumDeltas(); i++){var idx = deltas.getDeltaIndex( i ); // this converts the indexing on the deltas to the index on verticesvar v = deltas. getDeltaVec( i );v.x *= weights.getFloatWeight(idx)v.y *= weights.getFloatWeight(idx)v.z *= weights.getFloatWeight(idx)newDeltas.addDelta(idx, v );};// This creates the attenuated morph from the new deltasvar mod = new DzMorph( newDeltas );mod.setLabel( "new_morph" );mod.setName( "new_morph" );obj.addModifier( mod );

     

    Post edited by LAP on
  • Richard Haseltine said:

    I'm not sure that Morph loader pro is exposed to scripting, so you'd have to write your own attenuation code - you should be able to get the deltas and attenuate them (that is, reduce them - though from your description I suspect you just need to seelctively zero them) and use the verteices' position to figure out if they are left or right. Shape Splitter can do it, and I think that's a script rather than a plug-in (or was initially). I did once start a similar splitting script in DS 3 and although it didn't get far it was possible, or at least looking possible.

    I was wrong to say that Morph Loader isn't exposed to scripting:

    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/file_io/import_obj_morph_loader_silent/start
    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/morphloaderbatch_dz
    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/morphloader_dz

  • LAPLAP Posts: 3

    Richard Haseltine said:

    Richard Haseltine said:

    I'm not sure that Morph loader pro is exposed to scripting, so you'd have to write your own attenuation code - you should be able to get the deltas and attenuate them (that is, reduce them - though from your description I suspect you just need to seelctively zero them) and use the verteices' position to figure out if they are left or right. Shape Splitter can do it, and I think that's a script rather than a plug-in (or was initially). I did once start a similar splitting script in DS 3 and although it didn't get far it was possible, or at least looking possible.

    I was wrong to say that Morph Loader isn't exposed to scripting:

    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/file_io/import_obj_morph_loader_silent/start
    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/morphloaderbatch_dz
    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/morphloader_dz

    Thanks again for your time.

    And yeah, I was aware of those (I had been using the import_obj_morph_loader_silent as a reference), but technically your statement was that the "Morph Loader Pro" (rather than just Morph Loader) wasn't exposed to scripting, and I think that's technically correct (at least I currently don't know how to run "Morph Loader Pro" itself via Daz scripting).
    As I detailed in my previous post, my issue boils down to not knowing how to feed a "Morph Loader Pro" setting into DzMorphLoader.

  • luisalexandrepereira said:

    Richard Haseltine said:

    Richard Haseltine said:

    I'm not sure that Morph loader pro is exposed to scripting, so you'd have to write your own attenuation code - you should be able to get the deltas and attenuate them (that is, reduce them - though from your description I suspect you just need to seelctively zero them) and use the verteices' position to figure out if they are left or right. Shape Splitter can do it, and I think that's a script rather than a plug-in (or was initially). I did once start a similar splitting script in DS 3 and although it didn't get far it was possible, or at least looking possible.

    I was wrong to say that Morph Loader isn't exposed to scripting:

    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/samples/file_io/import_obj_morph_loader_silent/start
    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/morphloaderbatch_dz
    http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/morphloader_dz

    Thanks again for your time.

    And yeah, I was aware of those (I had been using the import_obj_morph_loader_silent as a reference), but technically your statement was that the "Morph Loader Pro" (rather than just Morph Loader) wasn't exposed to scripting, and I think that's technically correct (at least I currently don't know how to run "Morph Loader Pro" itself via Daz scripting).
    As I detailed in my previous post, my issue boils down to not knowing how to feed a "Morph Loader Pro" setting into DzMorphLoader.

    I am told:

    DzMorphLoaderBatch and DzMorphLoader ARE the "Morph Loader Pro" backend - the "Morph Loader Pro" dialog literally uses these classes and provides a UI to control it.

  • LAPLAP Posts: 3

    I am told:

    DzMorphLoaderBatch and DzMorphLoader ARE the "Morph Loader Pro" backend - the "Morph Loader Pro" dialog literally uses these classes and provides a UI to control it.

    Yeah, that's what I was thinking, but thanks for the confirmation. Just today I was learning how to automate saving morphs (following the sample script in the documentation), and in that case I'm able to call the UI options for saving via the script, and then have the script print which settings were changed by the UI options. So my problem with the Morph Loader Pro boils down to not being able to call its UI via script, and thus not seeing which settings "Attenuate by" affects.
    Though either way my manual workaround does the exact same thing as the "Attenuate by" in MLP, so doing it the hard way actually taught me more. Finally ready to put all pieces together and finish my script. Thanks again!

Sign In or Register to comment.