Przypisywanie pustego obiektu nadrzędnego
Napisałem operatora, aby utworzyć pusty obiekt, a następnie uczynić go rodzicem dla aktualnie wybranego obiektu. Jednak kiedy przypisuję obiekt nadrzędny, obiekt podrzędny porusza się, chyba że znajduje się w miejscu pochodzenia. Jak mogę temu zapobiec? Oto kod, który demonstruje problem:
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()
Chciałbym, aby pusty obiekt nadrzędny i wybrany obiekt podrzędny znajdowały się w tej samej lokalizacji, niekoniecznie w miejscu pochodzenia. Staram się stworzyć grupę obiektów, które można przesuwać razem, a rodzic wydaje się najlepszym sposobem. Używałem Blendera w wersji 2.83, ale niedawno zaktualizowałem go do wersji 2.9. Dzięki za pomoc.
Odpowiedzi
Zestaw matrix_parent_inverse
Zobacz Czy obiekt podrzędny dziedziczy macierz po rodzicu?
Kluczowe jest tutaj to, że początek przestrzeni lokalnej jest obliczany z macierzy bazowej (co widać w interfejsie transformacji) i jej macierzy odwrotnej nadrzędnej.
Istnieje kilka sposobów na osiągnięcie pożądanego rezultatu:
- ustaw świat pustej matrycy na ten z oryginału
- i nadać tożsamości zarówno oryginałowi, jak
matrix_basis
imatrix_parent_inverse
oryginałowi. Odpowiednik przypadku, który „się nie poruszył”
Domyślnie blender ustawia macierz macierzystą na odwrót, więc po usunięciu rodzicielstwa obiekt zachowuje swoją poprzednią transformację. Użycie pierwszej metody przywróci je do początku.
- Ustaw świat macierzy rodzica na childs.
- Utrzymaj bieżącą lokalizację, ustawiając elementy potomne
matrix_parent_inverse
na odwróconą macierz podstawową.
Skrypt testowy, metoda 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()
Rozważ rozszerzenie tego na wybrane obiekty, tak aby można było dodać pustego rodzica do każdego z nich lub jednego rodzica przy aktywnym obiekcie, a wszystkie inne wybrane również staną się dziećmi.
potrzebujesz względnej macierzy transformacji, którą wyjaśniłem tutaj: Jak mogę ręcznie obliczyć bpy.types.PoseBone.matrix za pomocą interfejsu API Pythona Blendera?