本日は Blender の技術調査枠です。
Blender2.8で利用可能なpythonスクリプトを作ります。
UVマップの全頂点をピン止めする
UVマップの全頂点をピン止めします。
指定のUVマップが存在しない場合は処理ません。
ビューを通さず、直接UVのピン止め情報にアクセスします。
・pin_UVmap_all.py
# bpyインポート import bpy # メッシュ操作のため import bmesh # UVマップの全頂点をピン止めする def pin_UVmap_all(arg_objectname="Default", arg_uvname="UVMap") -> bool: """UVマップの全頂点をピン止めする Keyword Arguments: arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"}) arg_uvname {str} -- 指定UVマップ名 (default: {"UVMap"}) 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.pin_uv = True # メッシュ情報を更新する bmesh.update_edit_mesh(selectob.data) # 変更前のモードに移行する bpy.ops.object.mode_set(mode=befmode) return True # 関数の実行例 pin_UVmap_all(arg_objectname="Sphere", arg_uvname="UVMap")
選択中の頂点のUVマップの頂点をピン止めする
選択中の頂点のUVマップの頂点をピン止めします。
指定のUVマップが存在しない場合は処理ません。
サンプルはメッシュにおけるY軸の端の頂点を選択してピン留めします。
・pin_UVmap_selected.py
# bpyインポート import bpy # メッシュ操作のため import bmesh # 選択中の頂点のUVマップの頂点をピン止めする def pin_UVmap_selected(arg_objectname="Default", arg_uvname="UVMap") -> bool: """選択中の頂点のUVマップの頂点をピン止めする Keyword Arguments: arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"}) arg_uvname {str} -- 指定UVマップ名 (default: {"UVMap"}) 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: # 頂点が選択中か否か判定する if loop.vert.select == True: # UVレイヤーの参照を取得する loop_uv = loop[targetuvlayer] # 頂点のUV情報を取得してピンを設定する # UV情報アクセスのマニュアル # (https://docs.blender.org/api/current/bmesh.types.html#bmesh.types.BMLoopUV) loop_uv.pin_uv = True # メッシュ情報を更新する bmesh.update_edit_mesh(selectob.data) # 変更前のモードに移行する bpy.ops.object.mode_set(mode=befmode) return True # Y軸座標が最大または最小の座標の頂点を選択する def select_vert_Ytip(arg_objectname="Default", arg_uvname="UVMap", arg_max=False) -> bool: """Y軸座標が最大または最小の座標の頂点を選択する Keyword Arguments: arg_objectname {str} -- 指定オブジェクト名 (default: {"Default"}) arg_uvname {str} -- 指定UVマップ名 (default: {"UVMap"}) arg_max {bool} -- 最大値の端か否か (default: {True}) 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) # 選択モードを頂点選択モードにする bmeshdata.select_mode = {'VERT'} # 頂点を走査する # 頂点アクセスのマニュアル # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMVert) for vert in bmeshdata.verts: # 全ての頂点は一旦選択状態を解除する vert.select = False # Y座標の比較用変数を初期化 Ytip_pos = 0.0 Ytip_index = -1 # 頂点を走査する # 頂点アクセスのマニュアル # (https://docs.blender.org/api/current/bmesh.types.html?highlight=bmedge#bmesh.types.BMVert) for vert in bmeshdata.verts: # 1つ目の座標は基準として取得する if Ytip_index == -1: # 座標の値とインデックスを取得する Ytip_pos = vert.co[1] Ytip_index = vert.index else: # Y軸座標が最大または最小の座標かチェックする if (vert.co[1] > Ytip_pos) == arg_max: # 座標の値とインデックスを取得する Ytip_pos = vert.co[1] Ytip_index = vert.index # インデックス参照のため、テーブルを初期化する bmeshdata.verts.ensure_lookup_table() # Y軸座標が最大または最小の座標を選択する if Ytip_index > -1: bmeshdata.verts[Ytip_index].select = True # 辺または面の選択状態を更新する bmeshdata.select_flush_mode() # 変更前のモードに移行する bpy.ops.object.mode_set(mode=befmode) return True # 関数の実行例 select_vert_Ytip(arg_objectname="Sphere", arg_uvname="UVMap", arg_max=False) pin_UVmap_selected(arg_objectname="Sphere", arg_uvname="UVMap")