Takunojiの日記

自分が勉強したプログラム技術メモ

Blender Python 開発メモ 〜UV座標の取得〜

まとめ→オペレーターで作成したプロパティ(データ型でボタン、チェックボックスが決まる)をパネルのdraw()で登録する

 

アドオンのパネルに複数のコンポーネントを使用したい時はPropertyGroupを使う

https://docs.blender.org/api/blender_python_api_current/bpy.types.PropertyGroup.html

import bpy


class MyPropertyGroup(bpy.types.PropertyGroup):
custom_1 = bpy.props.FloatProperty(name="My Float")
custom_2 = bpy.props.IntProperty(name="My Int")

bpy.utils.register_class(MyPropertyGroup)

bpy.types.Object.my_prop_grp = bpy.props.PointerProperty(type=MyPropertyGroup)


# test this worked
bpy.data.objects[0].my_prop_grp.custom_1 = 22.0

 

アドオンの実装注意

panel.drawでの描画は無限ループ内での処理になるので、イベント等は別メソッドに実装する

ドキュメントには再描画時に走ると書いてあるのでもしかしたら、何も描画してないので無限ループしていたのかもしれない → その通りだった。以下のように実装すると
問題なく(無限ループ)しなくなった、が問題のチェックボックスが表示されない。。。
print("Drawing")
layout = self.layout
col = layout.column(align=True)
row = col.row(align = True)
row.operator('object.root_operator', text = "Update")
こんなボタンができて、オペレータクラスのbl_idnameに指定したIDを設定すると
そのクラスの「execute()」が起動する

f:id:Takunoji:20180403204653p:plain

 

 参照:
https://wiki.blender.org/index.php/Dev:Py/Scripts/Cookbook/Code_snippets/Interface

点の追加方法
First of all you have to create a object and a mesh, after that you can add the vertex to it:

# name: string for new object name
# verts: array of position coords - [(-1.0, 1.0, 0.0), (-1.0, -1.0, 0.0)]

def create_Vertices (name, verts):
# Create mesh and object
me = bpy.data.meshes.new(name+'Mesh')
ob = bpy.data.objects.new(name, me)
ob.show_name = True
# Link object to scene
bpy.context.scene.objects.link(ob)
me.from_pydata(verts, , )
# Update mesh with new data
me.update()
return ob

 

UV座標の取得スクリプトを発見したのでメモしておく

エディットモード時でないとエラーになるので注意
オブジェクトにテクスチャを貼り付けた状態で以下のスクリプトを起動します。
毛利家の家紋を貼り付けてみました。

f:id:Takunoji:20180320220347p:plain

そして、テキストエディタより以下のスクリプトを起動します。

import bpy
import bmesh
from mathutils import Vector

obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)


def uv_from_vert_first(uv_layer, v):
for l in v.link_loops:
uv_data = l[uv_layer]
return uv_data.uv
return None


def uv_from_vert_average(uv_layer, v):
uv_average = Vector*1
total = 0.0
for loop in v.link_loops:
uv_average += loop[uv_layer].uv
total += 1.0

if total != 0.0:
return uv_average * (1.0 / total)
else:
return None

# Example using the functions above
uv_layer = bm.loops.layers.uv.active

for v in bm.verts:
uv_first = uv_from_vert_first(uv_layer, v)
uv_average = uv_from_vert_average(uv_layer, v)
print("Vertex: %r, uv_first=%r, uv_average=%r" % (v, uv_first, uv_average))
参考にしたサイトは、以下です。

How to get the UV corresponding to a vertex via the Python API? - Blender Stack Exchange

出力結果

f:id:Takunoji:20180320220946p:plain

Vertex: <BMVert(0x109e26810), index=0>, uv_first=Vector*2, uv_average=Vector*3

Vertex: <BMVert(0x109e26848), index=1>, uv_first=Vector*4, uv_average=Vector*5

Vertex: <BMVert(0x109e26880), index=2>, uv_first=Vector*6, uv_average=Vector*7

Vertex: <BMVert(0x109e268b8), index=3>, uv_first=Vector*8, uv_average=Vector*9

Vertex: <BMVert(0x109e268f0), index=4>, uv_first=Vector*10, uv_average=Vector*11

Vertex: <BMVert(0x109e26928), index=5>, uv_first=Vector*12, uv_average=Vector*13

Vertex: <BMVert(0x109e26960), index=6>, uv_first=Vector*14, uv_average=Vector*15

Vertex: <BMVert(0x109e26998), index=7>, uv_first=Vector*16, uv_average=Vector*17

 

*1:0.0, 0.0

*2:0.9999000430107117, 9.997999586630613e-05

*3:0.33330002427101135, 3.332666528876871e-05

*4:0.0, 0.0

*5:0.0, 0.0

*6:0.0, 0.0

*7:0.0, 0.0

*8:0.0, 0.0

*9:0.0, 0.0

*10:0.0, 0.0

*11:0.3332999050617218, 0.3332999050617218

*12:0.0, 0.0

*13:3.332666528876871e-05, 0.3332999348640442

*14:0.0, 0.0

*15:0.0, 0.0

*16:0.0, 0.0

*17:0.0, 0.0