Attribution d'un objet parent vide

Nov 19 2020

J'ai écrit un opérateur pour créer un objet vide, puis en faire un parent de l'objet actuellement sélectionné. Cependant, lorsque j'attribue l'objet parent, l'objet enfant se déplace à moins qu'il ne soit à l'origine. Comment puis-je empêcher cela? Voici un code qui illustre le problème:


class ObjectTest(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "myops.object_test"
    bl_label = "Array of current object"
    
    def execute(self,context):

        origobj = bpy.context.active_object
        bpy.context.scene.cursor.location = origobj.location

        bpy.ops.object.empty_add()
        objparent=bpy.context.active_object
        objparent.name=origobj.name+"Array"
        origobj.parent=objparent
        return {'FINISHED'}
    
def register():
    bpy.utils.register_class(ObjectTest)


def unregister():
    bpy.utils.unregister_class(ObjectTest)


if __name__ == "__main__":
    register()

Je voudrais que l'objet parent vide et l'objet enfant sélectionné soient au même emplacement, pas nécessairement à l'origine. J'essaie de créer un groupe d'objets qui peuvent être déplacés ensemble, et un parent semble être le meilleur moyen. J'utilisais Blender 2.83, mais j'ai récemment mis à jour la version 2.9. Merci de votre aide.

Réponses

2 batFINGER Nov 20 2020 at 09:03

Ensemble matrix_parent_inverse

Voir Un objet enfant hérite-t-il de la matrice du parent?

La clé ici est que l'origine de l'espace local est calculée à partir de la matrice de base (ce que vous voyez dans l'interface utilisateur de la transformation) et de sa matrice inverse parente.

Il existe plusieurs façons d'obtenir le résultat souhaité:

  • définir le monde de la matrice des vides sur celui de l'original
  • et mettre à la fois le matrix_basiset matrix_parent_inversede l'original à l'identité. Équivaut au cas où «n'a pas bougé»

Par défaut, Blender définit l'inverse du parent de la matrice, de sorte que lorsque le parentage est supprimé, l'objet conserve sa transformation précédente. L'utilisation de la première méthode les ramènera à l'origine.

  • Définissez le monde de la matrice parent sur childs.
  • Conservez l'emplacement actuel en définissant childs matrix_parent_inversesur sa matrice de base inversée.

Script de test, méthode 2.

import bpy

class ObjectTest(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.test"
    bl_label = "Array of current object"
    
    def execute(self, context):

        ob = context.active_object

        bpy.ops.object.empty_add()
        mt = context.active_object
        mt.name = f"{ob.name}Array"
        mt.matrix_world = ob.matrix_world
        ob.parent = mt
        ob.matrix_parent_inverse = ob.matrix_basis.inverted()
        return {'FINISHED'}
    
def register():
    bpy.utils.register_class(ObjectTest)


def unregister():
    bpy.utils.unregister_class(ObjectTest)


if __name__ == "__main__":
    register()

Envisagez d'étendre cela aux objets sélectionnés de manière à pouvoir ajouter un parent vide à chacun, ou un parent à l'objet actif et tous les autres sélectionnés deviennent également des enfants.

MohammadHosseinJamshidi Nov 20 2020 at 13:54

vous avez besoin d'une matrice de transformation relative que j'ai expliquée ici: Comment puis-je calculer manuellement bpy.types.PoseBone.matrix en utilisant l'API Python de Blender?