이것 저것 개발하고 만들어보기
article thumbnail

 

 

 

 

 

 

이번에는 오브젝트에 세팅된 모디파이 메뉴들을 일괄 삭제/적용하는 기능을 만들고, 이전에 만들었던 패널 탭을 Add-ons를 통해 제어할 수 있도록 만들어 보겠습니다.

 

 

그리고 블렌더의 파이썬 파일들을 역할별로 나눠 작성하고, 필요할 때 꺼내 쓰는 방법을 알아보자 합니다.

 

 

블렌더 내 텍스트 에디터가 아닌 지난 게시글에 VSCode 로 설치한 모듈과 함께 해당 코드를 작성합니다.

 

 

 

 

[Blender BPY] 블렌더 Add-ons 만들기.01 코딩 환경설정

우리가 UI를 직접 작성해 정리하는것도 중요하지만, 내가 만든 기능들을 한데 모아 묶어 분류하는것도 중요합니다. 무엇보다 다른 컴퓨터, 혹은 일하는 동료에게 BPY를 넘겨주어야 할 때 코드 전

tintana4168.tistory.com

 

 

 

 

 

import

 

 

 

 

 

 

지난 게시물에서 Add-ons를 작성하면서 여러 기능을 효율적으로 관리하기 위하여 VSCode를 사용했었습니다.

 

 

블렌더 BPY를 사용하기 위해서 " import bpy " 를 제일 첫줄에 삽입하는 것 처럼, 다른 모듈이나 패키지 파일을 불러와 현재 작성중인 스크립트에서도 동작할 수 있도록 하기 위해 삽입하는 구문입니다.

 

 

눈치 채신 분도 있겠지만,설치한 외부 패키지나 모듈을 스크립트뿐만 아니라 내가 작성한 스크립트도 똑같이 import 해줄 수 있습니다.

 

 

 

 

 

 

 

 

 

밑줄 친 "새 파일" 아이콘을 통해 파일을 파이썬 파일을 여러개 만들어줍니다.

 

 

각 기능에 따라서 파이썬 파일의 이름을 정해주고, 우선은 하위 폴더 없이 __init__ 파일과 같은 경로에 파일을 생성합니다.

 

 

이렇게 하면 에드온이 작동하기 위해 작업자가 파일을 깔끔하게 정리해 줄 수 있습니다.

 

 

 

 

 

모디파이어를 적용하는 기능구현

 

 

 

우선 실제로 UI에 들어가야 하는 기능을 먼저 구현하기 위해 OP_SetModifier 파일로 이동합니다. 

 

 

우선 모디파이어를 일괄 삭제/적용 하는 코드는 다음과 같습니다.

 

 

 

import bpy
from bpy_types import Operator

class TEST_OT_Delete_ALL(Operator):
    bl_idname = "test.delete_modifier"
    bl_label ="Delet Modifier"
    bl_description ="Remove modifiers."
    
    @classmethod
    def poll(cls,context):
        obj = context.object
        
        if obj is not None :
            if obj.mode == "OBJECT" :
                return True
            
            return False        
        
    def execute(self, Context):
        active_obj = bpy.context.active_object
        for mod in active_obj.modifiers:
            bpy.ops.object.modifier_remove(modifier=mod.name)

        return{'FINISHED'}



class TEST_OT_Apply_ALL(Operator):
    bl_idname = "test.apply_modifier"
    bl_label ="Apply Modifier"
    bl_description ="Applies registered modifiers."
    
    @classmethod
    def poll(cls,context):
        obj = context.object
        
        if obj is not None :
            if obj.mode == "OBJECT" :
                return True
            
            return False        
        
    def execute(self, context):
        active_obj = bpy.context.active_object
        for mod in active_obj.modifiers:
            bpy.ops.object.modifier_apply(modifier=mod.name)

        return{'FINISHED'}

 

 

 

여기서 두번째 줄 부터 확인해 보겠습니다.

from bpy_types import Operator

from 과 import 는 우리가 bpy 패키지나 모듈, 혹은 메소드를 쓰기 위해서 접근하기 위해 사용합니다.

 

 

from 을 통해서 어떤 모듈(파이썬 파일 등)을 가져와 import를 통해 필요한 클래스만 불러올 수도 있습니다.

 

 

모든 기능을 다 불러오게 되면, 동적 언어 특성상 느려질 수도 있으니 필요한 기능만 불러와 최적화 할 필요가 있습니다.

 

 

이렇게 하면 클래스에 스트럭쳐를 전부 기입해 상속받을 필요가 없습니다.

 

 

에드온에 구현해야할 기능이 많아지면 많아질수록, 여러 타입을 동시에 임포트 해야 할 때 사용할 수 있습니다.

 

 

 

 

 

    @classmethod
    def poll(cls,context):
        obj = context.object
        
        if obj is not None :
            if obj.mode == "OBJECT" :
                return True
            
            return False

 

 

 

@classmethod 는 정적메소드 라고 하며 클래스에서 직접 접근이 가능한 메소드입니다.

 

 

클래스 메소드 라고도 하는데, 다른 메소드와 달리 self 대신 cls를 인자로 받습니다.

 

 

이렇게 전달받은 cls 파마리터를 다른 곳에서도 호출할 수 있게 합니다. 이를 인스턴싱이라고 합니다.

 

 

 

 

 

poll 이라는 BPY메소드는 현재 상태에서 실행 가능한 context인지 확인이 가능합니다.

 

 

context는 현재 사용자가 조작하고 있는 상태를 뜻합니다.

 

 

블렌더에서 직접 Modifier를 적용하고자 할 땐 Edit Mode에서는 적용이 안되는데, 이때 poll 메소드를 통해서 context가 거짓을 반환해 실행이 되질 않습니다.

 

 

이를 검출한 데이터를 오브젝트 모드가 if문을 통해 "OBJECT" 모드 일 때만 기능을 활성화 시키게 합니다.

 

 

그 외는 비활성화 합니다.

 

 

 

    def execute(self, Context):
        active_obj = bpy.context.active_object
        for mod in active_obj.modifiers:
            bpy.ops.object.modifier_remove(modifier=mod.name)

        return{'FINISHED'}

 

 

이후 execute 메소드에서 선택된 오브젝트(.active_object)가 for문을 통해 현재 적용된 모디파이 정보(.modifier)를 취득해 mod 라는 임시 변수 안에 넣습니다.

 

 

for이 계속 돌면서 모디파이를 제거하는 메소드 (.modifier_remove) 를 통해 취득한 모든 모디파이 정보를 삭제합니다.

 

 

modifier_remove 메소드의 인자는 취득한 모디파이어들의 이름을 통해서 삭제할 수 있는데, 이는 모디파이어가 가진 이름과 일치합니다.

 

 

하지만 우리는 모든 모디파이어를 일괄 삭제해 주기 위해서 mod 라는 임시 변수를 name을 호출해 모든 모디파이어의 이름을 뜻하는 의미로 바꿔줍니다.

 

 

이러면 취득한 모든 모디파이어 정보가 일괄삭제할 수 있게 됩니다.

 

 

 

 

class TEST_OT_Apply_ALL(Operator):
    bl_idname = "test.apply_modifier"
    bl_label ="Apply Modifier"
    bl_description ="Applies registered modifiers."
    
    @classmethod
    def poll(cls,context):
        obj = context.object
        
        if obj is not None :
            if obj.mode == "OBJECT" :
                return True
            
            return False        
        
    def execute(self, context):
        active_obj = bpy.context.active_object
        for mod in active_obj.modifiers:
            bpy.ops.object.modifier_apply(modifier=mod.name)

        return{'FINISHED'}

 

 

 

모디파이어를 적용하는 클래스는 execute 함수의 for문 내부에서 오퍼레이터가 modifier_apply로 바뀐것과, 해당 기능을 위해 클래스명, bl_idname, bl_label을 바꿔주고 나머지는 같게 작성합니다.

 

 

이렇게 하면 모디파이어를 일괄 삭제/적용 하는 기능은 만들게 되었습니다.

 

 

 

 

 

기능을 버튼으로 UI에 등록하기

 

 

 

 

import bpy
from bpy_types import Panel



class TT_Penal_TEST(Panel):
    bl_space_type ="VIEW_3D"
    bl_region_type = "UI"
    bl_label = "ModifierOperations"
    bl_idname = "modifieradd"
    bl_category = "TT_Addons"

    def draw(self, context):
        layout = self.layout
        
        row = layout.row(align=True)
        col = row.column()
        col.operator("test.apply_modifier",text = "Apply All")
        
        row = layout.row(align=True)
        col = row.column()
        col.operator("test.delete_modifier",text = "Delete All")

 

 

 

from bpy_types import Panel

 

 

 

이번엔 우리는 bpy_types 중에서 panel 이라는 기능을 불러왔습니다.

 

 

클래스에서 이전 게시글에서 만들었던 panel을 이용해 보려고 합니다만, 이번엔 조금 다릅니다.

 

 

 

    def draw(self, context):
        layout = self.layout
        
        row = layout.row(align=True)
        col = row.column()
        col.operator("test.apply_modifier",text = "Apply All")
        
        row = layout.row(align=True)
        col = row.column()
        col.operator("test.delete_modifier",text = "Delete All")

 

 

 

draw 메소드를 들여다 보면, row 에 layout을 지정하는데, col 변수가 row.colum() 으로 '칼럼'이라는 함수를 호출하는것을 볼 수 있습니다.

 

 

가로(행, row)에서 호출한 Layout은 세로(열,col ) 에도 저장합니다. 그리고 블렌더의 operator 기능으로 이전에 지정한 모디파이어 적용 기능의 bl_idname 을 인자로 넣고, 선택사항으로 text를 지정해줍니다.

 

 

 

 

 

 

이어지는 다음 게시물에서, 실제로 에드온을 통해 출력할 수 있도록 레지스트리에 등록하고 해제하는 기능을 넣어보겠습니다.

profile

이것 저것 개발하고 만들어보기

@Tintana'k