見出し画像

[Blender][スクリプト]複数オブジェクトのトランスフォームに一括で演算子を適用するツール

選択中のオブジェクトのプロパティを一括で入力するにはAltを押しながらやりますが、あれ「+」とか「*」とか「/」とかの演算子には対応してないんですね。標準だと出来ませんよね?出来ます?
分からないですがまたAIに作ってもらいました。
演算子を一括で適用するツールです。

複数オブジェクトを選択した状態でサムネールにあるボタンを押すと、別窓で設定された処理がされます。
例えば画像の様に位置Y、Multiply(*)、値2.07だと選択中のオブジェクトの位置Yそれぞれに2.07が乗算されます。

今の所トランスフォームの値だけ選べるようになっています。

import bpy
import math

# オペレータークラス
class OBJECT_OT_custom_transform(bpy.types.Operator):
    bl_idname = "object.custom_transform"
    bl_label = "Apply Custom Transform"
    bl_description = "Apply a custom transform to selected objects with different operators"
    bl_options = {'REGISTER', 'UNDO'}

    # プロパティの選択肢
    properties: bpy.props.EnumProperty(
        name="Property",
        description="Choose which property to modify",
        items=[
            ('LOCATION_X', "Location X", ""),
            ('LOCATION_Y', "Location Y", ""),
            ('LOCATION_Z', "Location Z", ""),
            ('ROTATION_X', "Rotation X", ""),
            ('ROTATION_Y', "Rotation Y", ""),
            ('ROTATION_Z', "Rotation Z", ""),
            ('SCALE_X', "Scale X", ""),
            ('SCALE_Y', "Scale Y", ""),
            ('SCALE_Z', "Scale Z", ""),
        ]
    )

    # 操作する演算子の選択肢
    operation: bpy.props.EnumProperty(
        name="Operation",
        description="Choose the operation to apply",
        items=[
            ('ADD', "Add (+)", ""),
            ('MULTIPLY', "Multiply (*)", ""),
            ('DIVIDE', "Divide (/)", "")
        ]
    )

    # 変更する値
    value: bpy.props.FloatProperty(
        name="Value",
        description="Value to modify",
        default=0.0
    )

    def execute(self, context):
        for obj in context.selected_objects:
            if self.properties == 'LOCATION_X':
                if self.operation == 'ADD':
                    obj.location.x += self.value
                elif self.operation == 'MULTIPLY':
                    obj.location.x *= self.value
                elif self.operation == 'DIVIDE':
                    obj.location.x /= self.value
            elif self.properties == 'LOCATION_Y':
                if self.operation == 'ADD':
                    obj.location.y += self.value
                elif self.operation == 'MULTIPLY':
                    obj.location.y *= self.value
                elif self.operation == 'DIVIDE':
                    obj.location.y /= self.value
            elif self.properties == 'LOCATION_Z':
                if self.operation == 'ADD':
                    obj.location.z += self.value
                elif self.operation == 'MULTIPLY':
                    obj.location.z *= self.value
                elif self.operation == 'DIVIDE':
                    obj.location.z /= self.value
            elif self.properties == 'ROTATION_X':
                if self.operation == 'ADD':
                    obj.rotation_euler.x += math.radians(self.value)
                elif self.operation == 'MULTIPLY':
                    obj.rotation_euler.x *= self.value
                elif self.operation == 'DIVIDE':
                    obj.rotation_euler.x /= self.value
            elif self.properties == 'ROTATION_Y':
                if self.operation == 'ADD':
                    obj.rotation_euler.y += math.radians(self.value)
                elif self.operation == 'MULTIPLY':
                    obj.rotation_euler.y *= self.value
                elif self.operation == 'DIVIDE':
                    obj.rotation_euler.y /= self.value
            elif self.properties == 'ROTATION_Z':
                if self.operation == 'ADD':
                    obj.rotation_euler.z += math.radians(self.value)
                elif self.operation == 'MULTIPLY':
                    obj.rotation_euler.z *= self.value
                elif self.operation == 'DIVIDE':
                    obj.rotation_euler.z /= self.value
            elif self.properties == 'SCALE_X':
                if self.operation == 'ADD':
                    obj.scale.x += self.value
                elif self.operation == 'MULTIPLY':
                    obj.scale.x *= self.value
                elif self.operation == 'DIVIDE':
                    obj.scale.x /= self.value
            elif self.properties == 'SCALE_Y':
                if self.operation == 'ADD':
                    obj.scale.y += self.value
                elif self.operation == 'MULTIPLY':
                    obj.scale.y *= self.value
                elif self.operation == 'DIVIDE':
                    obj.scale.y /= self.value
            elif self.properties == 'SCALE_Z':
                if self.operation == 'ADD':
                    obj.scale.z += self.value
                elif self.operation == 'MULTIPLY':
                    obj.scale.z *= self.value
                elif self.operation == 'DIVIDE':
                    obj.scale.z /= self.value
        return {'FINISHED'}

# パネルクラス
class OBJECT_PT_custom_transform_panel(bpy.types.Panel):
    bl_label = "Custom Transform Tool"
    bl_idname = "OBJECT_PT_custom_transform_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Tool'
    
    def draw(self, context):
        layout = self.layout
        # オペレーターのUIを表示
        layout.operator("object.custom_transform")

# アドオンの登録/解除
def register():
    bpy.utils.register_class(OBJECT_OT_custom_transform)
    bpy.utils.register_class(OBJECT_PT_custom_transform_panel)

def unregister():
    bpy.utils.unregister_class(OBJECT_OT_custom_transform)
    bpy.utils.unregister_class(OBJECT_PT_custom_transform_panel)

if __name__ == "__main__":
    register()


これもそもそも、+Alt入力に演算子が対応してれば不要なんですけどね。

この記事が気に入ったらサポートをしてみませんか?