error with G9 facs expressions

Issue #1675 resolved
Alessandro Padovani created an issue

daz studio 4.21.0.5, blender 3.6.1, diffeomorphic 1.7.2.1725

There’s an error if we load G9 with expressions. Be sure to have the console open because sometime the error only appears in the console and is not reported in the error window, not sure why.

Please note that for G9 expressions are not part of the base pack and are provided separately in the daz shop. Not sure if this makes the difference. Anyway the error appears both with and without the expressions pack installed.

steps:

  1. import G9 and merge rigs
  2. import facs and facs expressions

alternate steps:

  1. easy import G9 with facs and facs expressions

Error: Python: Traceback (most recent call last):
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\error.py", line 222, in execute
self.run(context)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\morphing.py", line 1061, in run
self.loadMorphType(context, self.useFacsexpr, "Facsexpr", "Face")
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\morphing.py", line 1083, in loadMorphType
self.loadStandardMorphs()
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\morphing.py", line 740, in loadStandardMorphs
self.loadAllMorphs(namepaths)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\load_morph.py", line 129, in loadAllMorphs
self.makeMissingMorphs(0)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\load_morph.py", line 767, in makeMissingMorphs
self.makeAllMorphs(namepaths, False)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\load_morph.py", line 165, in makeAllMorphs
char = self.makeSingleMorph(name, path, bodypart, force)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\load_morph.py", line 182, in makeSingleMorph
if self.alreadyLoaded(asset):
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\load_morph.py", line 208, in alreadyLoaded
parent = self.getGraftParent(asset)
File "C:\Users\Alessandro\AppData\Roaming\Blender Foundation\Blender\3.6\scripts\addons\import_daz\load_morph.py", line 351, in getGraftParent
self.mesh.data.DazVertexCount == asset.vertex_count and
AttributeError: 'ChannelAsset' object has no attribute 'vertex_count'

Comments (28)

  1. Thomas Larsson repo owner

    Fixed in last commit. However, I discovered a new bug with transfer to the eyelids for some shapekeys.

  2. Alessandro Padovani reporter

    Commit 051cd09 works fine for the reported bug. Now the expressions load fine.

    A couple notes.

    1. transfer shapekeys. We already discussed this and that’s why the “only vertex groups“ option was implemented. The concept is, corrective shapekeys are used to correct the weightmaps, thus if there’s no weightmap in the target then we don’t transfer the shapekey.

    Explained another way. We don’t transfer shapekeys, we transfer morphs. So we first check if the morph affects the target bones, if yes then we transfer the morph shapekeys, otherwise we don’t. Apart vendor morphs that are always loaded.

    We make it better with an example. The jaw morphs only affect the mouth bones, they don’t affect the eye bones. So there’s no need to transfer the jaw shapekeys to the eyelashes, because they affect nothing.

    This is an important concept, if we bloat the figure with tons of unnecessary shapekeys then we degrade performances other than wasting memory. Then I understand it may be complex to implement and it’s easier to always transfer everything. Let me know what you think.

    # transfer shapekeys
    for each morph
        if there's a vendor morph for the target
            load the vendor shapekeys
        else if the morph affects the target bones
            transfer the morph shapekeys
    

    note: prune shapekeys. Another way to do this could be to first transfer all shapekeys as it is now, then compare the shapekeys with the original mesh, if the shapekey doesn’t deform the mesh then we can prune it. This is very time consuming though since we first transfer all then compare all, it would be much better to avoid transferring unnecessary shapekeys to start with.

    2. morph limits. I always load the figures with no limits since most poses remove the limits anyway and also limits don’t work fine for fk/ik snapping. But I noticed that morphs seem to always respect the bone limits, even when they are disabled in the daz figure.

    Below an example. In daz studio I disabled locks and limits on the figure, then I applied the fear expression on G9. With no limits the eyelid rotates -15 x, while in blender with no limits the eyelid rotates -45 x.

    Please note that a pose will load with no liimits, it’s only the morphs that seem to respect limits even if they are disabled.

    Now I didn’t test this extensively, so I’m not sure if there are other factors involved, also I understand that applying bone limits to the drivers is expensive. So I’m not sure if it’s worth to fix this since it seems to happen only in a few cases that the daz morphs exceed the bone limits. Let me know what you think.

  3. Thomas Larsson repo owner

    The transfer tool already checks if the boundary boxes of the shapekey and the target mesh overlap, and if not skips the shapekey. The boundary box of the shapekey is the region where it moves one vertex at least 0.1 mm. If the threshold is raised to 1.5 mm the jaw-open shapekey is skipped, but 1.0 mm was not enough.

    Shapekeys are already pruned. You can see in the terminal how the shapekey was transferred:

    * Vendor morph
    + Transferred, nonzero result
    - Transfer attempted, zero result, shapekey ignored.
    0 Boundary boxes don't overlap, ignored.
    

    Looking at vertex groups could be an idea, but remember that many facs morphs are pure shapekeys that don’t depend on any bone at all. Except maybe that pivots are moved, but that info is not available unless ERC morphs are enabled.

  4. Alessandro Padovani reporter

    I don’t follow. Here “jaw open” is transferred to eyelashes as “+ nonzero“ but doesn’t produce any visible deformation, even if I use a 10x multiplier, where by your measure should be more than 1 cm offset. Same for the other jaw facs. Are you sure you’re reading the distance right ? I mean what you think is 1.0 mm could be 0.1 mm or less.

    p.s. Unless you sum up all the offsets to get the final measure, that’s not correct you should get the max, not the sum.

    p.p.s. Unless you mean the vertex offset is considered to compute the boundary box by vertex cloud. But this is ineffective not a good method to prune shapekeys, or not enough. What I mean is a different pruning, where you compute the offset on the target after transferring. You could use first the boundary box before transfer, then the target offset after transfer.

    As for pure shapekey morphs, if it’s a pure shapekey then it’s not a corrective by definition, because there’s no bone deformation to correct. In this case yes I agree we have to transfer by boundary box unless there’s a vendor morph. But I doubt that most facs are pure shapekeys since facs drive bones first.

    As for moving pivots, they’re not necessarily ERC morphs. I mean face bones move the pivot in pose mode, not in edit mode, in this case it’s not a morphing armature but simply a bone translation. Unless I misunderstand what you mean by ERC morph.

  5. Alessandro Padovani reporter

    note. alternatives to transfer.

    Of course, as already noted for prebended figures, instead of transferring shapekeys we can use shrinkwrap or surface deform. But these will not consider vendor morphs so the effect is limited to transferred shapes. In particular, surface deform practically does the same as transfer nearest face, but without using shapekeys or drivers that’s a great deal.

    Below we see the pear figure “transferred“ to the outfit by surface deform.

  6. Alessandro Padovani reporter

    note. nearest face vs legacy. possible optimization or bug ?

    I noticed that if we transfer the jaw shapekeys from g9 to eyelashes in legacy mode, then no shapekeys are transferred. This could mean that legacy is somehow smarter and recognizes that jaw shapekeys have no effect on eyelashes thus doesn’t transfer them. Didn’t test extensively though so this may be a bug instead.

    Let me kow what you think.

  7. Thomas Larsson repo owner

    It turned out that I had forgotten to prune the shapekeys for the Nearest face method. The legacy method was made first, and when I made the implementation wtih numpy I had forgotten about pruning. Now none of the jaw shapekeys are transferred to the eyelashes. Two of them, face_bs_JawOpen and face_bs_JawOpenWide, are transferred to the brows, because some part of the brows near the temples actually move.

    Hm. The Basic shapekey seems to be missing for the brows.

    A new tool, Setup > Advanced > Morphs > Visualize Shapekeys is useful to see where the shapekey is. It creates a vertex group which can be viewed in weight paint mode. Picture below is the Jaw Open morph. We see that the boundary box method isn’t good enough to rule out the shapekeys, because the temples and the nose define a box which includes the lashes. The actual pruning does the job, though.

  8. Alessandro Padovani reporter

    Commit 5c3eaba works great, thank you for the fix.

    If I understand correctly, since you prune the shapekeys, there’s no more need for “only vertex groups“ since pruning does the same. As noted above, “only vertex groups“ would be smarter though since it “prunes” before transferring, and also only needs to check the weighmap/bone names that’s faster than computing the bounding box then pruning after transfer.

    Actually I’m confused how “only vertex groups“ works together with pruning. But I can mark as resolved since everything works fine now. Let me know what you think.

    Below the weightmaps/bones for the G9 eyelashes.

  9. Thomas Larsson repo owner

    I had forgotten about the “only vertex groups” option, so probably nobody else is using it either.

    The bounding box trick is a very fast way to prune many shapekeys, and that is important with the legacy method which is slow. The numpy method is much faster, but it is still slower than checking bounding boxes, I think.

    The issue is not resolved since the morph limit issue remains.

  10. Alessandro Padovani reporter

    Ok, please verify the morph limit issue since I didn’t test it extensively and I’m not sure if other factors come into play. Also it seems to happen rarely so we may also just fix it by hand when it happens. Let us know.

    p.s. If “only vertex groups“ is not used then we may remove the option, unless you plan to fix or improve it.

  11. Gabriele

    daz studio 4.21.0.5, blender 3.6.1, diffeomorphic 1.7.2.1726

    hi everybody, sorry about that (maybe wrong posting)

    i don’t know if its the same problem but, on FACS , and FACS expressions the tongue morphs not workin' also

    and g9 mouth have not shapekeys transfered.

    thanks for your incredibly work

  12. Alessandro Padovani reporter

    Yes I can confirm that tongue facs don’t work and no facs are transferred to the mouth. I recall there was an issue loading morphs on multiple meshes so we only loaded them on the main mesh then transferred to submeshes. May be this is the culprit.

    p.s. That no facs are transferred to the mouth is probably fine since teeth don’t deform with the face. Though the tongue should have its facs.

  13. Alessandro Padovani reporter

    update. workaround for G9 tongue.

    Meanwhile a quick workaround is to import the tongue facs as custom morphs, that always works.

    p.s. In a way this makes sense, because standard morphs are intended for main figures, not for secondary figures. In G9 secondary figures are used for facial shapes and the mouth, that’s a terrible way to do rigs and specific to daz, you will not find anything this horrible in any other place than daz studio, that’s also why we merge rigs. But once we merge rigs, we must consider that some standard morphs may be loaded on secondary figures too, that’s specific by genesis generation.

  14. Gabriele

    Hi Alessandro,

    nothin' happens, but its my fault i think

    steps:

    • import g9
    • merge rigs g9
    • import FACS, FACS expressions,FACS details and so on

    then

    • g9 mesh selected

    • create custom morph: import from Data->Genesis9->Base->Morphs->DAZ3d->Facs

    facs_ctrl_TongueLeft.dsf

    facs_ctrl_TongueRight.dsf

    facs_ctrl_TongueTipBend.dsf

    etc etc

    what’s wrong?

  15. Thomas Larsson repo owner

    The limit issue should be fixed in the last commit, like this:

    1. When a bone is made posable, the driven bone keeps the limit constraints.
    2. Locks and limits cannot be disabled for driven bones.

    This keeps limits for morphs, which affect the driven bones, and limits can be disabled for the posable bone.

    The drawback is that we double the contraint, which perhaps comes with a performance penalty, although I don’t think it is big. Alternatively, one could have added a new driver that clamps the result, but the web of drivers is too complex already and I don’t want to touch it unless absolutely necessary.

  16. Alessandro Padovani reporter

    @Gabriele To import custom morphs for the tongue you have to select the tongue mesh, not the figure mesh, as usual.

  17. Alessandro Padovani reporter

    @Thomas Can you please make this optional ? I understand this fixes the morphs issue but as you noted it is also a performance penalty and we may not be interested in limiting morphs as daz does. We may have a global option in the rigging section. Let us know what you think.

    global option (default on): “driven bones locks and limits“

    tooltip: “imports locks and limits for driven bones so that morphs are always limited same as daz studio”

  18. Alessandro Padovani reporter

    Commit 18b48de doesn’t seem to work.

    steps:

    1. in global settings disable limits
    2. import G9 and merge rigs
    3. import the fear facs expression with makes bones posable
    4. set the fear expression

    alternate steps:

    1. in global settings disable limits
    2. easy import G9 with facs and facs expressions
    3. set the fear expression

    There’s no bone constraint added to the driven bones. Unless you mean we always have to import locks and limits for this to work, that also means always adding bone constraints to all bones. Instead we may keep locks and limits as custom properties and use them on driven bones constraints when necessary. Or read locks and limits from the duf file when adding driven bones.

    Let us know what you think.

    update. enabling limits in global settings works fine.

    If I enable limits in the global settings then everything works as intended, so I understand this is what we have to do. It may be good as it is, that’s a “all or nothing“ choice. Then having custom properties may be more flexible allowing an option to keep constraints only for driven bones.

  19. Gabriele

    @Alessandro it was my mistake, i said so

    g9 mouth selected: everythin' goes perfect

    many thanks to you ( and your patience hehehe) and Thomas for great work!

  20. Thomas Larsson repo owner

    Yes, if limits are disabled in the global settings, no limit constraints are generated at all.

    We could make the extra constraints optional with some global setting if one is worried about performance. Or we could a button that mutes the limit constraints, instead of setting the influence to zero. I imagine that a disabled constraint costs essentially nothing, but an enabled constraint must be evaluated even if the influence is zero.

  21. Thomas Larsson repo owner

    Gabriele, I think it used to be possible to import facs morphs to the mouth, not as custom morphs but as regular facs morphs. The plugin has data files with info about where to find standard morphs for the G9 mouth, eyes, lashes and tears (in the data/paths directory). For some reason we disabled this possibility, and only allow standard morphs to be loaded to the genesis meshes.

  22. Alessandro Padovani reporter

    Thomas, as for limits I guess it’s fine. If one wants limits then gets them both for poses and morphs, otherwise there’s none.

    As for tongue facs, I recall you disabled loading standard morphs on submeshes because it caused issues. Before the fix I had to select the figure mesh instead of the armature, otherwise something broke when transferring morphs, then you decided to load standard morphs only on the figure. Eventually we could re-enable it then we’ll open another issue if this doesn’t work. Or we could enable submeshes only for the G9 tongue.

    update.

    Ok I found the issue, it’s #1590.

    When you select the rig morphs are loaded to all recognized meshes, not only the body but also lashes and tears. You can see that if you import facs with the lashes selected. The extra brow down morph comes from the lashes. In the lashes file facs_bs_BrowDownLeft_div2.dsf, the id, name and label of the morph are all facs_bs_BrowDownLeft_div2. Not good, standard morphs should be loaded to the lashes, but transferred from the main mesh. Now morphs are only imported to the main mesh.

  23. Thomas Larsson repo owner

    Hm. I think we have a problem here. The idea was that adding morphs was a two-step process:

    1. Import morphs to the body mesh.
    2. Transfer shapekeys to submeshes. That will pick up vendor morphs if those exist.

    However, this doesn’t work for G9 facs, specifically not for the tongue morphs. The problem is that the body mesh has no tongue shapekeys, so nothing is transferred in the second step. However, the facs sliders exist but they do nothing. What actually works is this:

    1. Import tongue facs morphs to the body.
    2. Import the tongue facs morphs as custom morphs to the mouth.

    Then the tongue sliders appear in two places, facs and custom morphs, but they do the same thing.

  24. Alessandro Padovani reporter

    I believe the difference is that G8 submeshes don’t have extra bones, that is, all the bones in the submeshes are already in the main figure. The G9 mouth is a submesh with extra bones that are not included in the main figure, where the extra bones is the tongue.

    In your explanation above you said “when you select the rig morphs are loaded to all recognized meshes“, that’s how it worked before, or didn’t work before. I believe it should be “when you select the rig morphs are loaded to the main figure, plus all recognized meshes having extra bones“. Or you could make a custom fix for G9, that is, import facs will behave differently depending on the genesis generation.

    Hope this helps.

  25. Alessandro Padovani reporter

    update. possible fix.

    If there's no better way, then a possible fix is to use the workaround then delete the tongue category. This leaves us with all the FACS working including the tongue. This is a fix that can be done manually or also automatically by the addon when we load FACS for G9.

    steps:

    1. load FACS
    2. if FACS include tongue then load tongue FACS as custom morphs for the mouth
    3. delete the custom morph tongue category (advanced setup > morphs > remove category)

  26. Thomas Larsson repo owner

    I think that I found a solution. The plugin now loads morphs to submeshes again, but only those morphs that are trivial for the main mesh. If the main morph is non-trivial, i.e. if it defines a shapekey or a driver, then we skip that morph for submeshes, but if it only defines a slider and nothing more, the corresponding submesh morph is loaded.

  27. Alessandro Padovani reporter

    Commit dc4ae34 seems to work great here, thank you for the fix.

    This is hard to test extensively, eventually we can open another issue if we find bugs. I see G9 is extremely slow to load compared to other figures, but this is the same in daz studio so I guess it's expected.

  28. Log in to comment