특정 컬렉션의 모든 오브젝트에 미러 수정자를 추가하는 방법은 무엇입니까?

Nov 29 2020

특정 컬렉션의 각 오브젝트에 미러 수정자를 추가하고 싶습니다.

문제는 수정자가 동일한 수정자를 여러 번 가져 오는 마지막 오브젝트에만 추가되며 그 이유를 모르겠다는 것입니다.

 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"]

Q : 특정 컬렉션의 모든 오브젝트에 미러 수정자를 추가하는 방법은 무엇입니까?

답변

3 Psyonic Nov 29 2020 at 10:25

bpy.data.objects그들을 조작하는 데 사용 하는 것이 좋습니다 . 이렇게하면 선택한 항목에 의존 할 필요가 없으며 개체 이름 만 있으면됩니다.

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

연산자의 경우 컨텍스트를 사용하십시오.

주어진 self가정하면 운영자를 작성하고, 질문 코드

설명을 통해 @RoufirHassan 의 대답에 더하여 컬렉션 개체를 반복 선택하고 단일 선택을 선택하면 활성 개체가 변경되지 않았습니다. context.object인쇄 문에 추가하면 이를 확인할 수 있습니다.

활성 개체와 0 번째 선택된 개체가 항상 동일합니까?

연산자를 호출하기 전에 활성 객체를 루프 객체로 고정하려면.

context.view_layer.objects.active = obj

Blender 2.8 API, Python, 활성 개체 설정

그러나 여기서 문제는 많은 연산자를 반복하면 스크립트가 끔찍하게 느려지는 경향이 있다는 것입니다. 수정 된 질문 코드를 사용하는 운영자 실행 횟수 는 컬렉션에있는 개체 수의 2 배가됩니다.

수정 자 추가 연산자가 수정 자 스택 끝에 추가됩니다.

수정 자 추가 연산자를 사용하는 경우 새로 추가 된 수정자는

context.object.modifiers[-1]

, 마지막 것. 이름을 사용하는 블렌더에서 다시 한 번 같은 이름을 가진 다른 개체를 추가하면 같은 이름을 갖지 않는 것과 마찬가지로 이름을 사용할 수 없습니다.

KeyError의 주요 후보

bpy.data.whatevers["Foo"]"Foo"가 존재하지 않는 한 절대 사용 하지 마십시오 . 가치를 가질 수있는 곳 None또한 씬 개체를 사용하는 것이 좋습니다. 마치의 개체 bpy.data.objects가 씬에 연결되어 있지 않으면 예상대로 작동하지 않을 수 있습니다.

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

또는 컨텍스트를 사용하십시오. 예를 들어이 경우 컬렉션은 컨텍스트 컬렉션 (아웃 라이너에서 마지막으로 선택됨)이 될 수 있으며 수정 자 대상은context.object

컨텍스트 재정의

연산자에게 컨텍스트 사전을 전달할 수 있습니다. 아래는 재정의를 사용하여 @RoufirHassan이 설명하는 방법 입니다. 참고 : 이렇게하면 컬렉션의 첫 번째 메시 오브젝트 (새로 추가 된 미러 포함)의 모든 수정자가 컬렉션의 다른 모든 메시 오브젝트에 추가됩니다. 단, 동일한 컬렉션의 메시 오브젝트 인 경우 미러 대상은 제외됩니다.

컬렉션에있는 개체 수에 관계없이 연산자 2 개만 실행됩니다.

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',
             )

API 메서드.

마지막으로 컨텍스트를 사용하여 컬렉션 및 수정 자 대상을 설정하는 것을 제외하고 @Pysonic의 답변에서 제안 된 API 메서드를 사용하는 것이 좋습니다 .

1 RoufirHasan Nov 29 2020 at 09:50

컬렉션의 모든 메시를 선택하고 미러 수정자를 추가합니다.

그러나 말했듯이 활성 개체 만 미러링합니다 (활성 개체 = 다른 색상의 윤곽선으로 선택한 마지막 개체). 따라서 모든 단일 오브젝트를 미러링하려면 ( Ctrl+ L) > modifiers를 입력하십시오 . 동일한 수정자를 가진 모든 오브젝트를 연결합니다.

다른 수정 자에도 사용할 수 있습니다.