Open8
Blender スクリプト メモ
以下、だいたい Blender 3.2 alpha 2865 (2022/2/5時点) あたりで動くコード。
アクティブなメッシュオブジェクトの頂点のうち、
X成分が0未満のものを選択する。
import bpy
import bmesh
def sel_b():
curobj = bpy.ops.active_object
bpy.ops.object.mode_set(mode='EDIT')
meshdata = bmesh.from_mesh(curobj.data)
for v in meshdata.verts:
if v.co.x < 0:
v.select = True
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set_with_submode(mode='EDIT', mesh_select_mode={'VERT'})
print(f'done')
sel_b()
Blender 3.0.0 2022/3/2
なんかこっちの方がエラーでにくい??
import bpy
import bmesh
def sel_c():
curobj = bpy.context.object
bpy.ops.object.mode_set(mode='EDIT')
meshdata = bmesh.from_edit_mesh(curobj.data)
for v in meshdata.verts:
if v.co.x > 0:
v.select = True
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set_with_submode(mode='EDIT', mesh_select_mode={'VERT'})
print(f'done')
sel_c()
Blender 3.0.0 2022/3/5
ボーン名で指定して頂点ウエイトが 0.0 より大きい頂点を選択する。
全頂点をなめていてかっこ悪い。
VertexGroup に含まれる頂点を取得する方法ありそう。
import bpy
import bmesh
def sel_f(sub):
curobj = bpy.context.object
vgs = curobj.vertex_groups
target = None
for vg in vgs:
if sub in vg.name:
target = vg
break
if target == None:
print(f'Not Found, {sub}')
return
print(f'Target, {target.name}')
bpy.ops.object.mode_set(mode='EDIT')
meshdata = bmesh.from_edit_mesh(curobj.data)
for v in meshdata.verts:
try:
wt = target.weight(v.index)
if wt > 0:
v.select = True
except:
pass
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set_with_submode(mode='EDIT', mesh_select_mode={'VERT'})
print(f'done')
sel_f('head')
Blender 3.0.0 2022/3/5
材質名を指定して、面のうち材質が合致する面の頂点を選択する。
import bpy
import bmesh
def sel_g(mtl_name):
curobj = bpy.context.object
mtls = curobj.data.materials
print(f'{mtls}')
mtl_index = -999
for index, mtl in enumerate(mtls):
print(mtl.name)
if mtl_name == mtl.name:
mtl_index = index
if mtl_index < 0:
print(f'Not found, {mtl_name}')
return
print(f'Found, {mtl_index}, {mtl_name}')
bpy.ops.object.mode_set(mode='EDIT')
# BMesh
meshdata = bmesh.from_edit_mesh(curobj.data)
for face in meshdata.faces:
if True:
if mtl_index == face.material_index:
for v in face.verts:
meshdata.verts[v.index].select = True
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set_with_submode(mode='EDIT', mesh_select_mode={'VERT'})
print(f'done')
sel_g('bodymaterial')
Blender 3.1 2022/3/27
# 選択頂点の平均(変更あり)
import bpy
import math
import bmesh
def act_b():
bpy.ops.object.mode_set(mode='EDIT')
bm = bmesh.from_edit_mesh(bpy.context.object.data)
possum = {'x': 0, 'y': 0, 'z': 0}
count = 0
sels = [v for v in bm.verts if v.select]
for v in sels:
possum['x'] += v.co.x
possum['y'] += v.co.y
possum['z'] += v.co.z
count += 1
s = f'{v.index} {v.co.x:.6f} {v.co.y:.6f} {v.co.z:.6f}'
print(s)
if count == 0:
return
possum['x'] /= count
possum['y'] /= count
possum['z'] /= count
print(f'avg {possum["x"]:.6f}')
min = 99999
best = None
for v in sels:
dist = 0
dist += pow(v.co.x - possum['x'], 2)
dist += pow(v.co.y - possum['y'], 2)
dist += pow(v.co.z - possum['z'], 2)
dist = math.sqrt(dist)
if dist < min:
best = v
min = dist
v.co.y += 0.020
print(f'minimum {min} {best.index}')
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
return
act_b()
実行する度にリロードするには importlib.reload() を使うらしい.
import foo
import importlib
importlib.reload(foo)
面を持たない材質をスロットから削除する.2022/5/30 3.3 alpha
# 使っている材質列挙したい
import bpy
import bmesh
def act():
curobj = bpy.context.object
mtls = curobj.data.materials
print(f'総数, {len(mtls)}')
bpy.ops.object.mode_set(mode='EDIT')
# BMesh
meshdata = bmesh.from_edit_mesh(curobj.data)
indexcount = {}
have_faces = set([])
for face in meshdata.faces:
index = face.material_index
if not index in indexcount:
indexcount[index] = { "count": 0 }
indexcount[index]["count"] += 1
if False:
if mtl_index == face.material_index:
for v in face.verts:
meshdata.verts[v.index].select = True
existcount = 0
for key in indexcount:
if key < len(mtls):
existcount += 1
mtl = mtls[key]
have_faces.add(mtl.name)
indexcount[key]["name"] = mtl.name
print(f'{key} {indexcount[key]["count"]} {mtl.name}')
bpy.ops.object.mode_set(mode='OBJECT')
bpy.context.view_layer.objects.active = curobj
num = len(curobj.material_slots)
for i in reversed(range(num)):
mtl = curobj.material_slots[i]
name = mtl.name
if name in have_faces:
continue
curobj.active_material_index = i
bpy.ops.object.material_slot_remove()
#bpy.ops.object.mode_set_with_submode(mode='EDIT', mesh_select_mode={'VERT'})
print(f'done, {existcount}, {len(indexcount.keys())}')
act()