Open8

Blender スクリプト メモ

ウサギウサギ

アクティブなメッシュオブジェクトの頂点のうち、
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()