Bagaimana cara menambahkan pengubah cermin ke semua objek dari koleksi tertentu?

Nov 29 2020

Saya ingin menambahkan pengubah cermin ke setiap objek dari koleksi tertentu.

Masalahnya adalah pengubah hanya akan ditambahkan ke objek terakhir yang bahkan mendapatkan pengubah yang sama beberapa kali dan saya tidak tahu mengapa:

 def add_empty_collection(self):
    for obj in bpy.data.collections['my_collection'].all_objects:
        print("obj_: ", obj)
        bpy.ops.object.select_all(action='DESELECT') # Deselecting all
        obj.select_set(True)
        bpy.ops.object.modifier_add(type='MIRROR')
        bpy.context.object.modifiers["Mirror"].use_axis[0] = False
        bpy.context.object.modifiers["Mirror"].use_axis[1] = True
        bpy.context.object.modifiers["Mirror"].use_axis[2] = False
        bpy.context.object.modifiers["Mirror"].mirror_object = bpy.data.objects["target"]

T: Bagaimana cara menambahkan pengubah cermin ke semua objek koleksi tertentu?

Jawaban

3 Psyonic Nov 29 2020 at 10:25

Anda lebih baik menggunakan bpy.data.objectsuntuk memanipulasinya. Dengan cara ini Anda tidak perlu bergantung pada apa yang dipilih, yang Anda butuhkan hanyalah nama objek.

import bpy

mod_name = 'My-Mirror-Modifier'

for obj in bpy.data.collections["My-Collection"].all_objects:
    if obj.type == 'MESH':
        mod = obj.modifiers.new(mod_name, 'MIRROR')
        mod.use_axis[0] = False
        mod.use_axis[1] = True
        mod.use_axis[2] = False
        mod.mirror_object = bpy.data.objects["Light"]
2 batFINGER Nov 30 2020 at 12:47

Untuk operator gunakan konteks.

Diberikan selfdalam kode pertanyaan, membuat asumsi Anda menulis operator

Selanjutnya jawaban @RoufirHassan dengan cara penjelasan, perulangan objek koleksi de-memilih dan memilih tunggal, tidak mengubah objek aktif. Menambahkan context.objectke pernyataan cetak akan mengkonfirmasi ini.

Apakah objek aktif dan objek yang dipilih ke nol selalu sama?

untuk memperbaiki mengatur objek aktif ke objek loop sebelum memanggil operator.

context.view_layer.objects.active = obj

Blender 2.8 API, python, atur objek aktif

Namun masalah di sini adalah skrip memiliki kecenderungan untuk melambat jika mengulang banyak operator. Hitungan operasi operator menggunakan kode pertanyaan yang diubah akan menjadi 2 x jumlah objek dalam koleksi.

Pengubah menambahkan operator menambah akhir tumpukan pengubah

jika menggunakan pengubah tambah operator pengubah yang baru ditambahkan akan

context.object.modifiers[-1]

yaitu yang terakhir. Sekali lagi dalam blender menggunakan nama bisa jadi cerdik, seperti halnya menambahkan benda lain dengan nama yang sama tidak akan memiliki nama yang sama.

Kandidat utama untuk KeyError

Jangan pernah gunakan bpy.data.whatevers["Foo"]kecuali Anda yakin "Foo" ada. Di mana itu dapat memiliki nilai NoneJuga merekomendasikan menggunakan objek adegan, seolah-olah objek di bpy.data.objectstidak terkait dengan adegan itu kemungkinan besar tidak akan bekerja seperti yang diharapkan.

target = context.scene.objects.get("Foo")

atau gunakan konteksnya. Dalam kasus ini misalnya, kumpulan dapat berupa kumpulan konteks (terakhir dipilih di garis luar) dan dapat menjadi target pengubahcontext.object

Konteks utama

Dapat meneruskan kamus konteks ke operator. Di bawah ini adalah metode yang dijelaskan oleh @RoufirHassan menggunakan override. Catatan: ini akan menambahkan semua pengubah objek mesh pertama dalam koleksi (termasuk mirror yang baru ditambahkan) ke semua objek mesh lainnya dalam koleksi, kecuali target mirror jika itu adalah objek mesh dalam koleksi yang sama

Ini hanya akan menjalankan 2 operator tidak peduli berapa banyak objek yang ada di dalam koleksi.

import bpy

context = bpy.context

coll = context.collection
ob = context.object

mesh_obs = [o for o in coll.all_objects 
        if o.type == 'MESH'
        and o is not ob]


if mesh_obs:
    ao = mesh_obs.pop(0)
    bpy.ops.object.modifier_add(
            {"object" : ao},
            type='MIRROR'
            )
    mod = ao.modifiers[-1]
    mod.use_axis = (True, False, True)
    mod.mirror_object = ob
    bpy.ops.object.make_links_data(
            {"object" : ao,
             "selected_editable_objects": mesh_obs
             },
             type='MODIFIERS',
             )

Metode API.

Terakhir, saya akan merekomendasikan penggunaan metode API seperti yang disarankan dalam jawaban @Pysonic , kecuali menggunakan konteks untuk menyetel target koleksi dan pengubah.

1 RoufirHasan Nov 29 2020 at 09:50

Pilih semua jerat dalam koleksi Anda dan tambahkan pengubah cermin.

Tapi seperti yang Anda katakan, itu hanya akan mencerminkan objek aktif (objek aktif = objek terakhir yang dipilih dengan garis luar berwarna berbeda). Jadi untuk mencerminkan setiap objek cukup ketik ( Ctrl+ L) > pengubah . Ini akan menghubungkan semua objek dengan pengubah yang sama.

Anda dapat menggunakannya untuk pengubah lain.