MRが楽しい

MRやVRについて学習したことを書き残す

Blender2.8で利用可能なpythonスクリプトを作る その39(UVマップの拡大縮小)

本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。

UVマップを指定値で拡大縮小する

UVマップを指定値で拡大縮小します。
指定のUVマップが存在しない場合は処理しません。
拡大縮小の中心点がUVマップの中央となるよう調整します。
・move_UVmap_selected.py

# bpyインポート
import bpy
# メッシュ操作のため
import bmesh

# UVマップを指定値で拡大縮小する
def change_UVmap_scale(arg_objectname="Default", arg_uvname="UVMap", arg_scale=1.0) -> bool:
    """UVマップを指定値で拡大縮小する

    Keyword Arguments:
        arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"})
        arg_uvname {str} -- 指定UVマップ名 (default: {"UVMap"})
        arg_scale {float} -- 拡大縮小倍率 (default: {1.0})

    Returns:
        bool -- 実行正否
    """

    # 指定オブジェクトを取得する
    # (get関数は対象が存在しない場合 None が返る)
    selectob = bpy.data.objects.get(arg_objectname)

    # 指定オブジェクトが存在するか確認する
    if selectob == None:
        # 指定オブジェクトが存在しない場合は処理しない
        return False
    
    # オブジェクトがメッシュであるか確認する
    if selectob.type != 'MESH':
        # 指定オブジェクトがメッシュでない場合は処理しない
        return False

    # 指定オブジェクトをアクティブに変更する
    bpy.context.view_layer.objects.active = selectob

    # 元々の操作モードを記録する
    befmode = bpy.context.active_object.mode

    # 編集モードに移行する
    bpy.ops.object.mode_set(mode='EDIT', toggle=False)

    # Bメッシュデータを取得する
    # Bメッシュアクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMesh)
    bmeshdata = bmesh.from_edit_mesh(selectob.data)

    # UVレイヤーの参照を取得する
    # レイヤーアクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html#bmesh.types.BMLayerAccessLoop)
    targetuvlayer = bmeshdata.loops.layers.uv.get(arg_uvname)

    # 指定UVマップが存在するか確認する
    if targetuvlayer == None:
        # 指定UVマップが存在しない場合は処理しない
        return False

    # メッシュの面の参照からUVマップの頂点を編集する
    # 面の参照を取得する
    # 面アクセスのマニュアル
    # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMFace)
    for face in bmeshdata.faces:
        # 要素の参照を取得する
        # 要素アクセスのマニュアル
        # (https://docs.blender.org/api/current/bmesh.types.html#bmesh.types.BMElemSeq)
        for loop in face.loops:
            # UVレイヤーの参照を取得する
            loop_uv = loop[targetuvlayer]

            # 頂点のUV情報を取得して座標を拡大縮小する
            # UV情報アクセスのマニュアル
            # (https://docs.blender.org/api/current/bmesh.types.html#bmesh.types.BMLoopUV)
            loop_uv.uv[0] *= arg_scale
            loop_uv.uv[1] *= arg_scale

            # 中心位置を調整する
            if arg_scale > 1.0:
                loop_uv.uv[0] -= ((arg_scale - 1.0) / 2.0)
                loop_uv.uv[1] -= ((arg_scale - 1.0) / 2.0)
            else:
                loop_uv.uv[0] += ((1.0 - arg_scale) / 2.0)
                loop_uv.uv[1] += ((1.0 - arg_scale) / 2.0)

    # メッシュ情報を更新する
    bmesh.update_edit_mesh(selectob.data)

    # 変更前のモードに移行する
    bpy.ops.object.mode_set(mode=befmode)

    return True

# 関数の実行例
change_UVmap_scale(arg_objectname="Sphere", arg_uvname="UVMap", arg_scale=0.5)

f:id:bluebirdofoz:20200602230348j:plain