Attribution d'un objet parent vide
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
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_basis
etmatrix_parent_inverse
de 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_inverse
sur 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.
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?