Asignar un objeto padre vacío
Escribí un operador para crear un objeto vacío y luego convertirlo en padre del objeto seleccionado actualmente. Sin embargo, cuando asigno el objeto principal, el objeto secundario se mueve a menos que esté en el origen. ¿Cómo puedo evitar que eso suceda? Aquí hay un código que demuestra el problema:
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()
Me gustaría que el objeto principal vacío y el objeto secundario seleccionado estuvieran en la misma ubicación, no necesariamente en el origen. Estoy tratando de hacer un grupo de objetos que se puedan mover juntos, y un padre parece ser la mejor manera. Estaba usando Blender 2.83, pero recientemente actualicé a 2.9. Gracias por tu ayuda.
Respuestas
Conjunto matrix_parent_inverse
Consulte ¿Un objeto hijo hereda la matriz del padre?
La clave aquí es que el origen del espacio local se calcula a partir de la matriz base (lo que ve en la interfaz de usuario de la transformación) y su matriz inversa principal.
Hay varias formas de lograr el resultado deseado:
- establecer el mundo de la matriz vacía al del original
- y establecer tanto el
matrix_basisymatrix_parent_inversedel original como identidad. Equivalente al único caso que "no se movió"
Por defecto, blender establece la matriz principal inversa, por lo que cuando se elimina la crianza, el objeto mantiene su transformación anterior. El primer método los devolverá al origen.
- Establezca el mundo de la matriz principal en niños.
- Mantenga la ubicación actual estableciendo childs
matrix_parent_inverseen su matriz de base invertida.
Guión de prueba, método 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()
Considere la posibilidad de extender esto a objetos seleccionados de modo que puedan agregar un padre vacío a cada uno, o un padre en el objeto activo y todos los demás seleccionados también se convertirán en hijos.
necesita una matriz de transformación relativa que he explicado aquí: ¿Cómo puedo calcular manualmente bpy.types.PoseBone.matrix usando la API de Python de Blender?