Retarget driver duplicate custom morph props as Shape category

Issue #315 resolved
engetudouiti created an issue

I could not catch or notice when it happen, but I found MHX boe props shown in my custom morph section. they seems offered by MHX, but it actually no usage. I do not know when it happen, I just append some mhx clothing to converted body rig, then use retarget-driver. I do not check about that time, basically it retarget driver from library rig to current rig,

So do not know clear which function may auto generate custom morphs (Shape) I usually not use shape category, Though I may test with new scene, (do same-thing and if it cause issue or not), but can you quick find , what may cause this issue?

I found it, when I import some new shape key for MHX rig items (for skirt). without driver. but even though I re-open old scene, (untill import shape key morphs for dress), those props already be shown as shape morph category. and at same time it seems duplicate another custom morphs, I do not touch morph group etc, so do not know why and when it happend.

(I only use “retarget driver” when I append mhx items in library. )

The MHX controller problem seems solved, but still see duplicate custom morph props when retarget rig as “shape” group.

then it can not clean up by remove category.

Comments (23)

  1. engetudouiti reporter

    OK I seems find one reason.

    1. import custom shape morph for body with PBM category name, with driver for rig then save scene A
    2. transfer custom morphs to clothing (as same as jcm) with driver, for rig then save in sceneB so sceneB and sceneA rig have same morph category. and morphs.
    3. in Scene A, append items(clothings) of scene B (come with rig), then I change armature modifier rig as SceneA rig. and change parent to sceneA rig. I select append objects, then select sceneA rig, then retarget driver.
    4. now it make new “shape” category which I have not used, , then duplicate same morphs and drivers in PBM and shape.
    5. I tried to remove category (shape) without shape key.. (so hope it remain drv) but it remove shape category, then remove dirver in category PBM = remove prop controller in the section…(those use same driver id, so it will be removed I think)

    Maybe I can clean up it,, but I keep my default rig as clean, then hope to attach items which use same rig and custom prop groups, (so rig A in scene A and rig B in scene B always keep same prop and custom groups which I named)

    Maybe same thing happened, when I try to append other scene MHX rig attached item to current scene MHX rig, then retarget driver.. about custom morphs (shape key) and rig driver (then maybe about that time, it auto generate those mhx props in “shapes” with clothing morphs.

    The main problem is , when I remove duplicate category, (if retarget driver must generate new shape category, for shape key dirvers) , it not only remove duplicate category, but try to remove drivers ,my hand made custom group too (which I made). it seems change how work,, sometimes it remove both , sometimes it work as I need.

    Though retarget-driver, and remove category is advanced option, so I do not push request hard, but hope if you can improve them,,… (it need to use another scene clothing etc for current rig often ^^;)

  2. engetudouiti reporter

    I think, it can be solved with change way.

    when retarget driver, add on try to generate new controller in UI for custom shape key morphs as shape group. (of couse without it, we have no meaning to generate driver) but about this case,, (the current rig already have controller which can change the labelled shape key values,) do not generate new controller but only change driver target prop.

    If auto-detect is difficult, I can manually set the option active. if you can offer it. (auto generate shape category and new controller for shape key driver or only change driver target prop as same as JCMs. about my case I need later one. (not try to generate new controller and new shape group)

  3. engetudouiti reporter

    So at current I make this disable (comment out) in driver.py I suppose it work for my purpose

    def retargetRna(self, rna, rig):
        from .morphing import addToCategories
        if rna and rna.animation_data:
            props = []
            for fcu in rna.animation_data.drivers:
                for var in fcu.driver.variables:
                    if var.type == 'SINGLE_PROP':
                        trg = var.targets[0]
                        words = trg.data_path.split('"')
                        if len(words) == 3:
                            prop = words[1]
                            setFloatProp(rig, prop, 0.0, GS.propMin, GS.propMax)
                            props.append(prop)
                    for trg in var.targets:
                        if trg.id_type == 'OBJECT':
                            trg.id = rig
            updateDrivers(rna)
            #if props:
                #addToCategories(rig, props, "Shapes")
                #rig.DazCustomMorphs = True
    

    (retarget driver, target rig already have same prop and already have custom group to controll shape keys, so only need to change driver target rig to current rig. without generate new shape category)

    Only thing I hope to confirm, the rig.DazCustomMorphs = True still need or not. (do not know clear what will change with True of False and, may effect current target rig and atached items ?)

    So I may only request toggle option, (understand there should be case, target rig have no custom gorup and controller for source mesh shape keys (though source rig already have the custom prop and custom morph group, about these case,, it need to add new Category and props) about “Retarget driver” (generate new category and controller for rig or not)

    Then may request “remove category” will be enhanced to consider case when there is same shape key controller duplicated in 2 groups. (actually it often happen ,when user import custom morphs, which already imported before ,) . it should not remove another controller.

  4. Thomas Larsson repo owner

    It happens because Retarget Driver also retargets it own drivers. I don’t think that is right. But am not sure.

  5. engetudouiti reporter

    mmm,,,,I can not understand, what Thomas means “it own driver”…

    but I feel if my current fix only hide controller but still generate new custom props which may need not for current rig..

    I understand, there is 2 case.

    1. target rig do not have controller to drive shape keys (soruce mesh shape keys have been driven by souce rig custom prop and controller)

    about this case, current way is reasonable.

    1. target rig already have controller which can drive same name shape keys for appended meshes. it may often happen, when we transfer cutom shape morph from body to clothings. then append those clothing to different scene. (which remove the clothing but rig still have controller which drive same name shape key of body mesh

    about this case,, only need to change driver target prop.. no need to generate new UI rpop, or new rig custom prop etc..

  6. engetudouiti reporter

    About MHX props added, I did not know how I can manage them,, my way anyway remove to generate new UI props, but I do not know if it still generate un-necesarry props, ^^; so hope you test or check, if you can.

    (it should happen, when I append another MHX scene B mesh, to current scene A MHX rig, then retarget driver for JCM and shape keys for current MHX rig(and body). those MHX prop generate as custom morphs ^^;

  7. engetudouiti reporter

    0d5ea3e still duplicate shape key controller as new “shape” category morph for target rig. So I suppose to avoid it, I still need to comment out “if porps” section in driver.py

    (and I could understand, what you means , so target rig need to include in selection, then target rig MHX props had been generated as new props with shape key category, but it seems not related with duplicate issue. Though duplicated problem is not this topic, (I happend to find it at same time,,)

    What I think is, when make prop list (shape keys), script need to check target rig already have it as custom morphs.

    Because if target rig attached with body mesh, usually target rig have all custom morph (for body) dirver and prop (and category). like FBM category, fat morph.

    Then when append clothing (come with rig) of other scene, they have shape keys which transfered from same body.

    so when retarget driver for clothing and current target rig, target rig already have category and controller for those shape keys (include PBM/ fat custom morph controller), . then it will be duplicated and grouped in “Shape” category of current rig props.

    So as default it is OK, (script work, if current target rig have no custom morph props. but hope toggle option, when user know, target rig already have those shape key custom morph prop with user defined category , I can avoid to generate new props and “shape category” but only change driver target. as same as before.

  8. engetudouiti reporter
    def retargetRna(self, rna, rig):
        from .morphing import getMorphs
        from .morphing import addToCategories
        if rna and rna.animation_data:
            props = []
            cmorph = list(getMorphs(rig,"Custom").keys())
            for fcu in rna.animation_data.drivers:
                for var in fcu.driver.variables:
                    if var.type == 'SINGLE_PROP':
                        trg = var.targets[0]
                        words = trg.data_path.split('"')
                        if len(words) == 3:
                            prop = words[1]
                            if prop not in cmorph:
                                setFloatProp(rig, prop, 0.0, GS.propMin, GS.propMax)
                                props.append(prop)
                    for trg in var.targets:
                        if trg.id_type == 'OBJECT':
                            trg.id = rig
            updateDrivers(rna)
            if props:
                addToCategories(rig, props, "Shapes")
                rig.DazCustomMorphs = True
    

    I think it work ,, (though it is dirty edit,,), but I think it is what I need. use your offered getMorphs function to check if there is already same custom morph props. so it can exclude those to generate new props with setting.

    but I still not test when it need to add new props. I may test later…

  9. engetudouiti reporter

    And I understand, there remain case, it not work.

    clothing A have morph to move side, then import morph for clothing A shape keys “move-right”

    clothing B have same name morph (it may happen), then import morph as shape keys, for clothing B, “move-right”

    about those type morph, we need to use different category morph, I understand Thomas not hope to hard edit untill release new version, so I do not request it, but I think it will need to consider,

    how generate driver for rig about clothing morphs (it need to work individuallly), and auto transfer mimic morph (not jcm but body morphs transfered for each clothing, which need to work at same time with one controller)

    I remember other user request, who may hope to add driver not rig but individual mesh. (though it not so flexible to pose, because we need to select each mesh to use the driver, but it is more daz like way. (about daz we select each mesh top nodes, to controll those clothing morphs) ,

    But if individual clothing shape key driver target = each mesh object, this problem may not happen.

  10. engetudouiti reporter

    There may be 2 way to manage all.

    1 keep all shape key driver attached to rig. (it is useful for pose),

    about this case, I may request 2 things. (after release new version, as future beta request)

    a. when import shape morph for clothing, auto option which set category for clothing name as default. at current all import morph will be categorized as “shape” (default), then it often cause user make many category, or duplicate category with spell miss. if default try to generate clothing morphs , with clothing name (labell or ID), and if there is always same name, it not duplicate category , at least user just obey the way.

    b. retarget driver need to check, shape keys controller category too. at current I only use getDazmorph, custom but you already offer way, only get props with custom group name, but it need to check soruce rig category, from driver (f-curve) , then if source rig have same category and same props, it need to be excluded.

    2. sesparate “auto transfer” mimic custom morphs, and “individual clothing morph” by change driver target for rig or mesh. or offer option (only user may use it, they clear understand difference when import custom morphs)

    basically, if user use transfer morphs from body to another object, it try to mimic “Daz auto transfer” or if vendor offer same name morph for clothing as body morph (include jcm), it controlled by body morph, (so when select the character top node, those controller change at same time, in daz studio). Then controller need to generate as rig prop (character rig)

    but if user simply import clothing shape morph, or clothing custom bone controller, (like hair), those controller can be generate as each object (clothing, hair) props. if user clear understand difference, they may hope to generate controller with object.

    the idea is to clear divide shape keys target ,, as character rig and attached mesh. (but about grafted item,, may be they need to include in body, even though they have custom bone)

    typeA: Auto transfer represent morphs = “character body morph shape keys + auto transfered or overwrite morphs shape keys of clothing hairs, (include all bone related pose controller)

    typeB: individual morphs (never auto transfer) shape keys target (include custom bone controller which relate with each object (hair bone, or skirt bones etc)

  11. engetudouiti reporter

    As for me, (so retarget morph may not work for some cases), so I keep not import morph for each clothing, for library scenes. (so only transfer JCM and body morph for each assets, then append them from library with rig for current scene), then basically it is not problem though…

  12. engetudouiti reporter

    Btw I think if you already offer clever function, which can find custom morph category from shape key driver F curves ? I understand, I can get source rig id from f-curve,, and can get morph list with your getMorph function, but can not find good way to find category, where the shape key driver target belong to,,, if I can find source rig category , I can check same category and same name morph is in target rig daz props. then can exclude those from prop list, witch need to generate new morph as “Shape”

    ==
    then I hope to know how you manage (script may work), if user import same name morph for different object (clothing A and clothing B etc), with driver option? I suspect it may happen.. then I think at current add on can not manage it as user clear find. without you auto-set category when import those morphs. 🤔

    so that means, when you select one shape key, can you find category from driver , even though there are same name morphs in morph list?

  13. engetudouiti reporter

    btw the above edit, seems work correctly, (source skirt mesh have new shape keys with driver, then retarget driver, it generate new morph in shape section as it need. but not duplicate same name morph as Shape.

    And I think it not caused by my edit, but I suppose when generate new morph with retarget, script need to “Update dependency”. (new prop correctly generated, as driver target, but without up-date dependency, it still not work, then I manually click it, I suppose you alreaqdy offer function, up-date driver correctly, but I did not remember,, so I can not edit to correct it.

    And as already said, it may not work correctly if there are same name morphs (but link with other clothing shape key) which need to re-target, in target rig.. I do not know if it simply show error, or the shape key may driven by first one. as if they are auto transfered morphs. without body morph.

  14. engetudouiti reporter

    Yes I test like this

    1_ make new shape key for skirt name as “fit well” then use “add shape key driver” then set category as “skirt” . when I move skirt > fit well, it move skirt shape key

    2_ make new shape key for blazer name as “fit well” , then do same thing but set category as “Blazer”

    I may expect, it can change shape key value individually. but atcually no.. both category morph already keep same value. (I can not set different morph value for skirt and blazer, when 2 shape key have same name.

    Then I can summarize, what is problem. when set driver for shape keys of attached item (not include body), script need to consider 2 case.

    A if it is expected to work with body morph, ( script check if body mesh have same name shape key and it already have driver link with rig property), they should not generate new controller or new category,, but only set driver for the body morph controller . because it work as same as daz body morph and same name morph. it is not matter, those morph are auto transfered, (in daz), or vendor offer clothing morph with set file name as body morph files. even though vendor not intend it, DS auto move all same name properties, when we move character parameter. (I sometimes reported those issue, usually vendor did not how how other vendor set morph file name or ID etc,, so sometimes it happend to get same id)

    B if clothing morphs are expected to work individually there should not be same name shape key as body mesh. (it is rule for daz, so we follow it) script may need to check it first.

    then if there is no same name shape key, each shape key driver need to work separately ,even though there are same name shape keys in clothing A and B. At current both target prop is same.

    so add on may need to offer way, how manage same name shape keys (but not included in body shape keys) as diffeent controller.

    at current there is no group for the case. custom morph group include both. so you may need to make one more group which can drive each clothing shape key ,even though shape key name are same.

    At current add on can not manage B type shape key (morphs and drivers) well. (neather import morphfile, or add driver) because 2 category can include same prop of rig. (so it may cause problem, when remove category, or change category etc)

  15. engetudouiti reporter

    I suppose new commit solve this issue, but I still do not know so we can not make driver for same name shape key about clothing A and clothing B or hair A and hair B ?

    (I can manage it , if at current it is limit of this add on, I may not make driver for those shape keys, then I may request to offer controler, attach driver target prop for each mesh as option. it may be used when user add driver for clothing shape key (which not change with body morph prop values, (or rig props), so it never be duplicated, and I do not need retarget driver. for those shape keys, (though script need to know, when retarget driver… the target is rig or mesh type object,,then exclude them from new shape props)

  16. engetudouiti reporter

    About up-date problem I do not rememer, clearly,, but after I use my custom one, then try to retarget driver, (with new shape key and driver which not in current scene rig), it could generate new morph as shape. then it need to manually up-date dependency .

    I could not see this issue before, but may be when retarget driver, it duplicate , so this not be shown as problem. (only duplicate ui prop, but old prop still remain) maybe up-date problem only happen when we generate new props (it not in target rig)

  17. engetudouiti reporter

    And I said, old rig category may need to check, but after test with other case, after all current add on can not manage, about same name shape keys in different obj. so it seems not matter. when add on not generate new morph, = there already category and morph. then if add on need to generate new morph as shape category,, it may work for all same name shape keys. (can not change morph value separately)

    I now understand it is useful. if add on can make old rig category when make new props, (before add on auto set category. ) I said only about exceptional case problem (same name shape keys in different items, need to set driver for same rig.,,but it was not retarget problem, actually it is “ set driver problem” until user will use retarget function ^^;)

  18. engetudouiti reporter

    I test with e2ed238 then I could confrim new props generated as same category as old rig props. and not duplicate same props 😀 . but only about new generate prop, still not up-date, (need manually update dependency)

    Though It seems only need to up-date depthgraph for one shape key driver, (I test with 2 driver shape keys.. maybe old technic (change expression with empty etc) may work I suppose. (I do not know what way you use for recent verson to up-date dependency though)

    Unfortunately, actually I needed to up-date both (so if I have 5 new shape key, which need to retarget, maybe it becom trouble,, about already generated prop , they keep link as same as before, and change target to current rig prop correctly.

    I found old thechnic again, I think we used it before for other purpose,, but do not know recent code.

    driver.expression += " " driver.expression = driver.expression[:-1]

  19. engetudouiti reporter
    def retargetRna(self, rna, rig):
        from .morphing import addToCategories
        if rna and rna.animation_data:
            props = {}
            for fcu in rna.animation_data.drivers:
                for var in fcu.driver.variables:
                    if var.type == 'SINGLE_PROP':
                        trg = var.targets[0]
                        words = trg.data_path.split('"')
                        if len(words) == 3:
                            prop = words[1]
                            if prop not in rig.keys():
                                min,max,cat = self.getOldData(trg, prop)
                                if cat not in props.keys():
                                    props[cat] = []
                                props[cat].append(prop)
                                setFloatProp(rig, prop, 0.0, min, max)
                    for trg in var.targets:
                        if trg.id_type == 'OBJECT':
                            trg.id = rig
            if props:
                for cat,cprops in props.items():
                    addToCategories(rig, cprops, cat)
                rig.DazCustomMorphs = True
            updateDrivers(rig)//<<<<<< change here
    

    found criminal.. updateDriver(rna) >> updateDriver(rig) , then it worked for me

  20. Log in to comment