[Blender×Python]   ランダムをマスターしよう!!

今回は、オブジェクトを大量に、かつランダムに配置する仕組みを紹介していきます。

#目次
0.ランダムな数値を取得する方法
1.ランダムな位置に立方体を出現させる
2.関数をつくって処理をまとめる
3.サンプルコード
4.英単語
参考資料


---

#0.ランダムな数値を取得する方法

今回は、**numpy**というライブラリ(便利なコードの集まり)の中の``rand()``関数を使っていきます。

rand()関数は、**0から1までのランダムな値**を返します。
引数(パラメータ)には、幾つのランダムな数値を返すかを指定します。
rand(3)ならば、ランダムな数値を3つ返します。

```.py
import numpy as np

#np.randomは右向きの矢印と考え無視して構いません。
np.random.rand(3)
```
Point:**import numpy as np**
numpyというライブラリをコード中でnpという略称で表記するということ。

```.py
array([0.90681482, 0.04813658, 0.47969033])
```

↑
0から1の範囲のランダムな値が3つ出力されます。

※arrayは配列という意味ですが、今回は気にしなくて大丈夫です。
数字が順番に入っている入れ物みたいなものです。







#1.ランダムな位置に立方体を出現させる

##1-0.立方体をランダムな位置に出現させよう!!

数値計算のためのライブラリ``numpy``を利用する

```.py
import bpy
import numpy as np

bpy.ops.mesh.primitive_cube_add(location = np.random.rand(3))
```


Point:**rand( )**
0から1までのランダムな値を生成する。
引数で、値を何個返すのか決定する。rand(3)なら、ランダムな値を3つ返す。

![スクリーンショット 2020-11-16 5.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/b60fc854-5a0e-8907-1c83-f6fdb49158ce.png)

※写真では、変数locationに、3つのランダムな値→(0.0291909, 0.379929, 0.395483)が代入された。



##1-1.立方体が出現する範囲を指定できるようにしよう

○-10以上10未満の範囲のランダムな数値を取得します。
コードは以下のような構造になっています。

変数□にデータ(情報)を代入して、そのデータを使って処理を実行する。
そして、ドットは右向き矢印と考えてOK(ほぼ無視して良い).

```
□ ← ランダムな数値データ
===> 関数( □ )
```

```.py
import bpy
import numpy as np

#変数random_locationをつくって、ランダムな値を代入する
random_location = (10 - (-10)) * np.random.rand(3) + (-10)
bpy.ops.mesh.primitive_cube_add(location = random_location)
```
![スクリーンショット 2020-11-16 6.16.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/6aef67ef-e3a7-1347-3711-78822f9c23bb.png)

Point:**ある範囲内の数値**
min以上max未満の範囲のランダムな値を取得する式は、
**(max-min) * np.random.rand() + min**
です。

つまり、
**数値が変動する範囲 * 0から1までのランダムな値 + 範囲のはじまり**
ということです。

今回の例で言うと、-10から、+20の範囲内の(ランダムな)数値を取得する。
範囲→(-10,..-9,..0,..9,..10)



##2.関数をつくって処理をまとめる

##2-0.ランダムな数値を返す関数と、それを使って立方体を出現させる関数をつくる

```.py
import bpy
import numpy as np

#ランダムな値を3つ生成するための関数の定義
def get_random_location(min,max):
    return (max - min) * np.random.rand(3) + min

#get_random_location()関数が生成した値を使って立方体を出現させる関数の定義
def generate_random_cube(min,max):
    random_location = get_random_location(min,max)
    bpy.ops.mesh.primitive_cube_add(location = random_location)

generate_random_cube(-10,10)
```

Point:**Return**
関数が何らかの情報を出力する時に``return 情報``という形で使います。

![スクリーンショット 2020-11-16 8.55.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/af8a478b-a8a7-b562-3f32-f6c2d147f3b8.png)




##2-1.複数の立方体をランダムな位置に出現させる関数をつくる


```.py
import bpy
import numpy as np

#ランダムな値を3つ生成するための関数の定義
def get_random_location(min,max):
    return (max - min) * np.random.rand(3) + min

#get_random_location()関数が生成した値を使って立方体を出現させる関数の定義
def generate_random_cube(min,max):
    random_location = get_random_location(min,max)
    bpy.ops.mesh.primitive_cube_add(location = random_location)

#複数の立方体をランダムな位置に出現させる関数の定義
def generate_random_cubes(min,max,num):
    for i in range(0,num):
        generate_random_cube(min,max)

generate_random_cubes(-10,10,200)
```

![スクリーンショット 2020-11-16 8.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/304a8d97-c303-9795-f7f6-a05c086065da.png)



##2-2.ランダムな位置にランダムな角度の立方体を複数出現させる

```.py
import bpy
import math
import numpy as np

#ランダムな値を3つ生成するための関数の定義
def get_random_location(min,max):
    return (max - min) * np.random.rand(3) + min

#random_number()関数が生成した値を使って立方体を回転、出現させる関数の定義
def generate_random_rotate_cube(min,max):
    random_location = get_random_location(min,max)
    bpy.ops.mesh.primitive_cube_add(location = random_location,rotation = math.pi * np.random.rand(3))

#複数の立方体をランダムな位置に回転、出現させる関数の定義
def generate_random_rotate_cubes(min,max,num):
    for i in range(0,num):
        generate_random_rotate_cube(min,max)

generate_random_rotate_cubes(-10,10,200)
```
![スクリーンショット 2020-11-16 9.47.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/a7552b41-9710-c631-1728-dc0578bdc048.png)


---


#3.サンプルコード

##色をランダムに決める関数をつくる

○カラフルな立方体をランダムな位置にランダムな角度で配置します。

```.py
import bpy
import math
import numpy as np

#マテリアルを決める関数の定義
def material(name = 'material'):
    material_glass = bpy.data.materials.new(name)
    #ノードを使えるようにする
    material_glass.use_nodes = True
    p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]
    #0→BaseColor/7→roughness(=粗さ)/15→transmission(=伝播)
    #default_value = (R, G, B, A)
    p_BSDF.inputs[0].default_value = np.random.rand(4)
    p_BSDF.inputs[7].default_value = 0
    p_BSDF.inputs[15].default_value = 1
    #オブジェクトにマテリアルの要素を追加する
    bpy.context.object.data.materials.append(material_glass)

#ランダムな値を3つ生成するための関数の定義
def get_random_location(min,max):
    return (max - min) * np.random.rand(3) + min

#random_number()関数が生成した値を使って立方体を回転、出現させる関数の定義
def generate_random_rotate_cube(min,max):
    random_location = get_random_location(min,max)
    bpy.ops.mesh.primitive_cube_add(location = random_location,rotation = math.pi * np.random.rand(3))

#複数の立方体をランダムな位置に回転、出現させる関数の定義
def generate_random_rotate_colorful_cubes(min,max,num):
    for i in range(0,num):
        generate_random_rotate_cube(min,max)
        material('Random')


generate_random_rotate_colorful_cubes(-10,10,200)

    
```

![c1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/c5f7c400-6c81-d37f-b3e2-c2c4d777c03c.png)



---

##立方体を回転させながら並べる関数をつくる

```.py
import bpy
import math
import numpy as np

#マテリアルを決める関数の定義
def material(name = 'material'):
    material_glass = bpy.data.materials.new(name)
    #ノードを使えるようにする
    material_glass.use_nodes = True
    p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]
    #0→BaseColor/7→roughness(=粗さ)/15→transmission(=伝播)
    #default_value = (R, G, B, A)
    p_BSDF.inputs[0].default_value = np.random.rand(4)
    p_BSDF.inputs[7].default_value = 0
    p_BSDF.inputs[15].default_value = 1
    #オブジェクトにマテリアルの要素を追加する
    bpy.context.object.data.materials.append(material_glass)

#カラフルな立方体を回転させながら並べる関数の定義
def spiral_colorful_cubes():
    #100回反復処理をする
    for i in range(0,100):
        bpy.ops.mesh.primitive_cube_add(
            #少しずつ上にずらす
            location=(0, 0, i/50),
            scale=(1, 1, 0.05),
            #180 * i * 36(度)ずつずらしていく
            rotation = (0, 0, math.pi*i*10/360)
            )
        #オブジェクトにマテリアルの要素を追加する
        material('Random')

#処理を実行する
spiral_colorful_cubes()
```

![スクリーンショット 2020-11-16 15.08.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/6f89df2d-f3fb-ad0d-6e7e-70fb1fc1995d.png)

---

##トーラスを変形させて回転し、並べていく関数をつくる

```.py
import bpy
import math
import numpy as np

#マテリアルを決める関数の定義
def material(name = 'material'):
    material_glass = bpy.data.materials.new(name)
    #ノードを使えるようにする
    material_glass.use_nodes = True
    p_BSDF = material_glass.node_tree.nodes["Principled BSDF"]
    #0→BaseColor/7→roughness(=粗さ)/15→transmission(=伝播)
    #default_value = (R, G, B, A)
    p_BSDF.inputs[0].default_value = np.random.rand(4)
    p_BSDF.inputs[7].default_value = 0
    p_BSDF.inputs[15].default_value = 1
    #オブジェクトにマテリアルの要素を追加する
    bpy.context.object.data.materials.append(material_glass)

#トーラスを変形してずらしながら並べ、それぞれに色をつける関数の定義
def colorful_torus_spiral():
    for i in range(0,36):
        bpy.ops.mesh.primitive_torus_add(
            location=(0, 0, 0),
            major_radius=1.0,
            minor_radius=0.01,
            )
        #Y軸方向に縮める
        bpy.ops.transform.resize(value=(1, 0.3, 1))
        #Z軸を中心に回転する
        bpy.ops.transform.rotate(value=math.pi*i*10/360,orient_axis='Z')
        #オブジェクトにマテリアルの要素を追加する
        material('Random')

colorful_torus_spiral()
```
![c4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654004/c7fe0bee-efe3-b5dc-8192-74934b582d7b.png)



---

#4.英単語
|英単語|訳|
|:--|:--|
|spiral|螺旋|
|material|素材、材質|
|principled|原理、原則の|
|primitive|原始的な|
|math|数学|
|add|追加する|
|context|文脈、環境|
|value|値|
|default|既定の|
|append|追加する|
|generate|生み出す|
|inputs|取得する|


#参考資料

参考資料:[Blender×Pythonでパーティクルライブの素材を大量に自動生成する](https://styly.cc/ja/tips/blender-python-particlelive/)