Przypisywanie pustego obiektu nadrzędnego

Nov 19 2020

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

2 batFINGER Nov 20 2020 at 09:03

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_basisi matrix_parent_inverseoryginał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_inversena 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.

MohammadHosseinJamshidi Nov 20 2020 at 13:54

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?