tobi-be / BlenderEdmExporter

Blender EDM Exporter please read the readme
MIT License
32 stars 1 forks source link

"Use only one armature" error with one armature on scene. #1

Closed aunoor closed 4 years ago

aunoor commented 4 years ago

Hi. In Blender, at least 2.82a, if you add two armatures to scene and then delete one, you still get "Use one armature" message, because bpy.data.armatures list still contain record for deleted armature.

May be allow to have many armatures on scene, but on model export take one with fixed name, "Root" for example?

tobi-be commented 4 years ago

Hi, Thank you for explaining this problem! I would like to avoid further rules regarding the armature to avoid making it more complicated. I just saw that bpy.data.armatures[1].users is 0 when armature[1] is deleted by the user. Would it be better and sufficient to count the number of armatures correctly with this information?

aunoor commented 4 years ago

I agree, checking armature.users can help in general case. But in next scenario it's not working: 1) Create second armature. 2) Add fake user to it. 3) Delete armature. 4) Get error message, because deleted armature present in scene as orphan.

The most simplest way is next: if you got error message please save and reload file. If it not help please check if armature is orphaned. :)

I think, there must be another method, more reliable, but I can't find it now..

aunoor commented 4 years ago

Hm... I think i found solution. But please make allowances for the fact that this is my first deep dive into a Blender, so I may be fatally mistaken. :)

How I understand, when object deleted then happend next things 1) object's users count set to zero if object don't have fake user; 2) object removed from scene and moved to list of orpans.

And if we check that 'bpy.context.scene.objects ' contain more than one armature, then need to raise the error. Like this:

    if len(bpy.data.armatures) !=1:
        scene_have_arm=False
        for armature in bpy.data.armatures:
            if armature.name in bpy.context.scene.objects:
                if scene_have_arm:
                    print("Use one and only one armature! Not writing")
                    return None
                scene_have_arm=True
tobi-be commented 4 years ago

thanks for your contribution this actually looks good but i think i found an easier way:

    for i in bpy.data.objects:
        if i.type=='ARMATURE':
            armatures.append(i)     
    if len(armatures) !=1:
        print("Use one and only one armature! Not writing")
        return None
    armature=armatures[0]

I noticed that armature.name must not be the name of the object. It would be a problem if a user renames the armature object.

aunoor commented 4 years ago

Ok. If it work, why not? :)

aunoor commented 4 years ago

I checked it in 1.0.2. Problem with deleted armatures is gone, but still present for orphaned with fake user.

tobi-be commented 4 years ago

ok can you describe me how create orphaned with fake user?

aunoor commented 4 years ago

Oh, it's simple: 1) Create armature as usual. 2) Click right button on it in "Outliner" panel, then "ID Data"->"Add Fake User". 3) Delete it from scene. 4) Now you have ghosted armature. :)

To delete it permanently switch "Display mode" in "Outliner" to "Orphan Data" and you can find it under "Objects" list.

Yes, I understand that it not usual use case, but if it can happend then it happend. And if it not covered by code, then it must be covered by docs. :)

tobi-be commented 4 years ago

Ok the documentation says now not to use fake user armatures. Should be fine