メンガーのスポンジ

はい。blenderpythonメンガーのスポンジを作るよ。メンガーのスポンジって何?って人はWikipedaでも見るといいかもしれない。

メンガーのスポンジ - Wikipedia


コードはこちら

import bpy
            
check = [1,1,1,
            1,0,1,
            1,1,1,
            1,0,1,
            0,0,0,
            1,0,1,
            1,1,1,
            1,0,1,
            1,1,1]    #オブジェクトを置くかどうかを決めるためのリスト。1なら置く。

def menger(num, size):
    global check
    p = 0
    for i in [0.9,2.7,4.5]:    #配置するオブジェクトの原点のx座標
        for j in [0.9,2.7,4.5]:    #y座標
            for k in [0.9,2.7,4.5]:    #z座標
                if check[p] == 1:
                    if num == 0:    #最初は単に立方体を並べていくだけ
                        bpy.ops.mesh.primitive_cube_add(location=(k,j,i))
                        bpy.ops.transform.resize(value=(0.9,0.9,0.9))
                    else:    #それ以外はオブジェクトをコピー、移動、設置を繰り返す
                        if (i == 0.9 and j == 0.9 and k == 0.9):
                            pass    #最初の位置(手前左下)はすでに設置されているのでpassする
                        else:
                            bpy.ops.object.duplicate()    #オブジェクトをコピー
                            ob = bpy.context.object    #オブジェクトのプロパティをいじるためのインスタンスを生成する
                            ob.location = (k, j, i)
                p += 1    
    bpy.ops.object.select_by_type(type = 'MESH')    #積んだオブジェクトをすべて選択する(カメラやライトは含まれない)
    bpy.ops.object.join()    #1つのオブジェクトにまとめる
    bpy.ops.object.origin_set(type = 'ORIGIN_GEOMETRY', center = 'MEDIAN')    #オブジェクトの原点をド真ん中に移動する
    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.remove_doubles(limit = 0.0001)    #重複した頂点を取り除く
    bpy.ops.object.editmode_toggle()
    if num != size:    #指定したステップ数に達していない場合
        ob = bpy.context.object
        ob.scale = (ob.scale[0]/3,ob.scale[1]/3,ob.scale[2]/3)    #オブジェクトを1/3の大きさにする
        bpy.ops.transform.translate(value=(-1.8, -1.8, -1.8))    #最初の位置に移動する
    
def main():
    n = 3    #どの程度細かくするかのステップ数
    for i in range(n + 1):
        menger(i, n)
    
if __name__ == '__main__':
    main()


立方体の手前左下が原点になるようにしている。最初(n = 0)のときは、checkに従って左下から立方体を並べていき、次のステップに移る時に、出来たオブジェクトを1/3の大きさにして手前左下の最初の位置に持っていき、それをコピーしながらcheckに従って並べていく、という流れになる。(文字だけだと表現しにくい・・・)
オブジェクトを並べる座標が中途半端に見えるのは、3できれいに割り切れるようにしたかったから。3で割り切れるならなんでもいいのかな。

n = 3の場合は次のようなものができる。


ちなみにこのときのオブジェクトはメモリを200MBほど消費しているので、nを4にするとこれを20個並べるわけだから単純計算で4GBほど持ってかれることになる。重複した頂点は消すようにしているけど、それでもかなり持ってかれるので注意。