sysvbannerとBlenderドミノ(その2)


『掟上今日子の備忘録』

見たのはドラマの方なんですが、原作はライトノベルだったんですね。
ガッキーがおばあちゃんの役をやっているものとばかり思ってたんですが、若い女性でした。推理ものってわくわくします。
アニメ化もしてほしいです。

では、ドミノの続きです。
仕掛けドミノに導火線ドミノ追加していく前に、
「sysvbannerとBlenderドミノ(その1)」で作ったのが下のようなスクリプトになってしまい、ものすごく冗長です。
リファクタリングしたいと思います。

def addobj( x, y ):
    bpy.ops.mesh.primitive_cube_add()
    bpy.ops.transform.translate(value=(x,y,0))

filename = "c:/Users/takk/Desktop/banner.txt"
f=open(filename)
lines=f.readlines()

for y, line in enumerate(lines):
    for x, ch in enumerate(line):
        if ch == '#':
            addobj(y,x)

import math
camera=bpy.data.objects['Camera']
camera.location=(10,20,60)
camera.rotation_euler[0]=0
camera.rotation_euler[1]=0
camera.rotation_euler[2]=math.pi/2



for o in bpy.data.objects:
    if o.name.startswith('Cube'):
        bpy.ops.object.select_all(action='DESELECT')
        o.select = True
        bpy.ops.transform.resize(value=(0.5,0.2,1))

for o in bpy.data.objects:
    if o.name.startswith('Cube'):
        bpy.ops.object.select_all(action='DESELECT')
        o.select = True
        o.location.x = o.location.x * 1.5

m=bpy.data.materials.new('Material.001')
m.diffuse_color=(1,1,0)

for o in bpy.data.objects:
    if o.name.startswith('Cube'):
        o.active_material=m

import bmesh

bpy.ops.object.select_all(action='DESELECT')
cube=bpy.data.objects['Cube']
bpy.context.scene.objects.active=cube
cube.select=True
bpy.ops.object.mode_set(mode='EDIT')
m2=bpy.data.materials.new('Material.002')
m2.diffuse_color=(0,0,0)
bpy.context.object.data.materials.append(m2)
bm=bmesh.from_edit_mesh(bpy.context.object.data)
bm.faces.ensure_lookup_table()
bm.faces[3].material_index=1
bpy.ops.object.mode_set(mode='OBJECT')



for y, line in enumerate(lines):
    for x, ch in enumerate(line):
        if ch == ' ':
            bpy.ops.object.select_all(action='DESELECT')
            bpy.context.scene.objects.active=cube
            cube.select=True
            bpy.ops.object.duplicate()
            bpy.ops.transform.translate(value=(y*1.5,x,0))

まず、addobjでプリミティブを追加してますが、効率がよくないので、内容を牌のコピーに変更します。また、倒れたときに色が見えるかどうかを引数で指定できるようにします。chがsysvbannerの結果の#だった場合、牌の正面を黒く塗ります。

def addobj( x, y, ch ):
    bpy.ops.object.select_all(action='DESELECT')
    bpy.context.scene.objects.active=cube
    cube.select=True
    bpy.ops.object.duplicate()
    bpy.ops.transform.translate(value=(x*1.5,y,0))
    if ch=='#':
        bpy.ops.object.mode_set(mode='EDIT')
        bm=bmesh.from_edit_mesh(bpy.context.object.data)
        bm.faces.ensure_lookup_table()
        bm.faces[3].material_index=1
        bpy.ops.object.mode_set(mode='OBJECT')

牌全体のマテリアルはCubeに最初から設定されている’Material’を使います。
色を変えるだけです。

bpy.data.materials['Material'].diffuse_color=(1,1,0)

倒れた時に、色が変わる仕掛けは、追加のマテリアルで色を黒にしておきます。

m=bpy.data.materials.new('Material.Black')
m.diffuse_color=(0,0,0)

リファクタリング後のスクリプトです。

import bmesh,math

cube=bpy.data.objects['Cube']
bpy.ops.transform.resize(value=(0.5,0.2,1))

bpy.data.materials['Material'].diffuse_color=(1,1,0)

m=bpy.data.materials.new('Material.Black')
m.diffuse_color=(0,0,0)
bpy.context.object.data.materials.append(m)

def addobj( x, y, ch ):
    bpy.ops.object.select_all(action='DESELECT')
    bpy.context.scene.objects.active=cube
    cube.select=True
    bpy.ops.object.duplicate()
    bpy.ops.transform.translate(value=(x*1.5,y,0))
    if ch=='#':
        bpy.ops.object.mode_set(mode='EDIT')
        bm=bmesh.from_edit_mesh(bpy.context.object.data)
        bm.faces.ensure_lookup_table()
        bm.faces[3].material_index=1
        bpy.ops.object.mode_set(mode='OBJECT')

filename = "c:/Users/takk/Desktop/banner.txt"
f=open(filename)
lines=f.readlines()

for y, line in enumerate(lines):
    for x, ch in enumerate(line):
        addobj(y,x,ch)


camera=bpy.data.objects['Camera']
camera.location=(10,20,60)
camera.rotation_euler[0]=0
camera.rotation_euler[1]=0
camera.rotation_euler[2]=math.pi/2

こうなると導火線を引くのは簡単です。指定した座標に配置するだけです。

for y in range(0,24):
    addobj(y-0.5, -2, ' ')
    bpy.ops.transform.rotate(value=-math.pi/2,axis=(0,0,1))
    addobj(y-0.1, -1.4, ' ')
    bpy.ops.transform.rotate(value=-math.pi/6,axis=(0,0,1))

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA