前回記述した方法以外にも、bmeshモジュールを使用したUV情報の取得方法があります。

ドキュメントによると、bmeshモジュールはC APIに密接とのことで、こちらのほうが早いのかもしれません。
あと、こちらの手法では実行中にオブジェクトモードへ移行することがありません。

今回は
https://katsumi3.hatenablog.com/entry/2020/02/29/034510
を参考にさせていただきました。

下記コード内で”UVインデックス”のような言い回しをしていますが、Blenderには厳密にはそういった概念はないようです。
単に面を構成する要素を便宜上そう呼んでみました。

テストケース

今回もマテリアルを割り当てて、UVを動かしただけです

コード

import bpy
import bmesh

'''UV情報取得 BMesh版'''
mesh = bpy.data.objects['Cube'].data
bm = bmesh.from_edit_mesh(mesh)
# UV座標を一括で取得
print('----- UV coordinates -----')
uv_layer = bm.loops.layers.uv.active
for face in bm.faces:
    for face_corner in face.loops:
        uv = face_corner[uv_layer]
        print(uv.uv, uv.select)
# 各ポリゴンに属する頂点のグローバルID
print('----- Vertex index belonging to each polygons -----')
for face_id, face in enumerate(bm.faces):
    vtx_ids = [x.index for x in face.verts]
    print('face_id: {}, vtx_ids: {}'.format(face_id, vtx_ids))
# 各ポリゴンに属するUVの通し番号
print('----- UV indices belonging to each polygon -----')
start_uv_id = 0
for face in bm.faces:
    face_corner_count = len(face.loops)
    end_uv_id = start_uv_id + face_corner_count
    indices = [x for x in range(start_uv_id, end_uv_id)]
    print(indices)
    start_uv_id = end_uv_id
# UVの通し番号順に様々な情報を取得
print('----- UV information -----')
uv_layer = bm.loops.layers.uv.active
for face_id, face in enumerate(bm.faces):
    face_corners = face.loops
    vertices = face.verts
    for face_corner, vtx in zip(face_corners, vertices):
        uv = face_corner[uv_layer]
        print('face_id: {}, vtx_id: {}, uv: {}, uv_select: {}'.format(face_id, vtx.index, uv.uv, uv.select))

出力は以下の通りです。

----- UV coordinates -----
<Vector (0.3750, 0.0000)> False
<Vector (0.9369, 0.0000)> True
<Vector (0.6250, 0.2500)> False
<Vector (0.3750, 0.2500)> False
<Vector (0.3750, 0.2500)> False
<Vector (0.6250, 0.2500)> False
<Vector (0.6250, 0.5000)> False
<Vector (0.3750, 0.5000)> False
<Vector (0.3750, 0.5000)> False
<Vector (0.6250, 0.5000)> False
<Vector (0.6250, 0.7500)> False
<Vector (0.3750, 0.7500)> True
<Vector (0.3750, 0.7500)> True
<Vector (0.6250, 0.7500)> False
<Vector (0.6250, 1.0000)> False
<Vector (0.3750, 1.0000)> False
<Vector (0.1250, 0.5000)> False
<Vector (0.3750, 0.5000)> False
<Vector (0.3348, 0.7006)> False
<Vector (0.1250, 0.7500)> False
<Vector (0.6250, 0.5000)> False
<Vector (0.8750, 0.5000)> False
<Vector (0.8750, 0.7500)> False
<Vector (0.6250, 0.7500)> False
----- Vertex index belonging to each polygons -----
face_id: 0, vtx_ids: [0, 1, 3, 2]
face_id: 1, vtx_ids: [2, 3, 7, 6]
face_id: 2, vtx_ids: [6, 7, 5, 4]
face_id: 3, vtx_ids: [4, 5, 1, 0]
face_id: 4, vtx_ids: [2, 6, 4, 0]
face_id: 5, vtx_ids: [7, 3, 1, 5]
----- UV indices belonging to each polygon -----
[0, 1, 2, 3]
[4, 5, 6, 7]
[8, 9, 10, 11]
[12, 13, 14, 15]
[16, 17, 18, 19]
[20, 21, 22, 23]
----- UV information -----
face_id: 0, vtx_id: 0, uv: <Vector (0.3750, 0.0000)>, uv_select: False
face_id: 0, vtx_id: 1, uv: <Vector (0.9369, 0.0000)>, uv_select: True
face_id: 0, vtx_id: 3, uv: <Vector (0.6250, 0.2500)>, uv_select: False
face_id: 0, vtx_id: 2, uv: <Vector (0.3750, 0.2500)>, uv_select: False
face_id: 1, vtx_id: 2, uv: <Vector (0.3750, 0.2500)>, uv_select: False
face_id: 1, vtx_id: 3, uv: <Vector (0.6250, 0.2500)>, uv_select: False
face_id: 1, vtx_id: 7, uv: <Vector (0.6250, 0.5000)>, uv_select: False
face_id: 1, vtx_id: 6, uv: <Vector (0.3750, 0.5000)>, uv_select: False
face_id: 2, vtx_id: 6, uv: <Vector (0.3750, 0.5000)>, uv_select: False
face_id: 2, vtx_id: 7, uv: <Vector (0.6250, 0.5000)>, uv_select: False
face_id: 2, vtx_id: 5, uv: <Vector (0.6250, 0.7500)>, uv_select: False
face_id: 2, vtx_id: 4, uv: <Vector (0.3750, 0.7500)>, uv_select: True
face_id: 3, vtx_id: 4, uv: <Vector (0.3750, 0.7500)>, uv_select: True
face_id: 3, vtx_id: 5, uv: <Vector (0.6250, 0.7500)>, uv_select: False
face_id: 3, vtx_id: 1, uv: <Vector (0.6250, 1.0000)>, uv_select: False
face_id: 3, vtx_id: 0, uv: <Vector (0.3750, 1.0000)>, uv_select: False
face_id: 4, vtx_id: 2, uv: <Vector (0.1250, 0.5000)>, uv_select: False
face_id: 4, vtx_id: 6, uv: <Vector (0.3750, 0.5000)>, uv_select: False
face_id: 4, vtx_id: 4, uv: <Vector (0.3348, 0.7006)>, uv_select: False
face_id: 4, vtx_id: 0, uv: <Vector (0.1250, 0.7500)>, uv_select: False
face_id: 5, vtx_id: 7, uv: <Vector (0.6250, 0.5000)>, uv_select: False
face_id: 5, vtx_id: 3, uv: <Vector (0.8750, 0.5000)>, uv_select: False
face_id: 5, vtx_id: 1, uv: <Vector (0.8750, 0.7500)>, uv_select: False
face_id: 5, vtx_id: 5, uv: <Vector (0.6250, 0.7500)>, uv_select: False

face_cornerについて

コード中にface_cornerと書いていますが、これはジオメトリの面を順に構成する点です。正しくはBMLoopと呼ばれます。
MayaでのFaceVertexのようなものです。

UVと対になるジオメトリ情報をface_cornerとして取得しただけでは、特定のUV情報を得られません。なぜならUVマップは一つのジオメトリに一つとは限らないからです。特定のUV情報を取得するには、どのUVマップかを指定する必要があります。

uv_for_specific_uvmap = face_corner[uv_layer]

このようにどのUVレイヤー(UV Map)かを指定することで、特定のUVマップでのUV情報が取得可能になります。こうしてユニークな(唯一の)UV情報を得られます。(BMLoopUVと呼ばれます。)

辞書形式で値を取得するという方法について、ドキュメントを軽く読んだ限りでは見つけられませんでした…