blender2.9のスクリプトモードで閉曲線を作る

# はじめに
　blenderのscriptingでカーブオブジェクトの閉曲線を作る操作がわかったので記事にします。scriptingはエクセルマクロのようなもので、実行するとそこに書いてある内容が一通り実行される仕組みになっています。カーブオブジェクトを作るための頂点の追加や、選択、モード切替、押し出し操作などいろんな機能がコードを実行するだけですべて行われます。UIを使った操作だと数学的な形が作りづらいので、場合によっては便利だったりするみたいです（まだ慣れてないので・・）。APIについては、
　[blenderAPI](https://docs.blender.org/api/current/index.html)
を見れば一通り書いてあります（膨大なのでcurveなどキーワードをボックスに入力して読みたいところだけ読む感じですね・・）。

## コード全文
　円を描きながら一定の割合で上昇して一周し、頭とつなぐ感じの閉曲線を作ります。

```py
import bpy
from math import pi, cos, sin

def main():

  # 最初に、プリミティブを作って編集に行ってそれ削除して、ってのを追加
  bpy.ops.curve.primitive_bezier_curve_add()
  bpy.ops.object.editmode_toggle()
  bpy.ops.curve.delete(type='VERT')

  # ここからがメインスクリプト
  for i in range(0,40):
    t = 2 * pi * i / 40
    x = 4 * cos(t)
    y = 3 * sin(t)
    z = t / 2
    bpy.ops.curve.vertex_add(location = (x, y, z))
  # カーブが作れたらすべての頂点を選択する
  bpy.ops.curve.select_all(action='SELECT')

  # 参考：
  # https://docs.blender.org/api/current/bpy.ops.curve.html#bpy.ops.curve.select_all
  # https://docs.blender.org/api/current/bpy.ops.curve.html#bpy.ops.curve.make_segment

  bpy.ops.curve.make_segment()
  # 作成し終わったら選択解除
  bpy.ops.curve.select_all(action='DESELECT')
  # オブジェクトモードに戻す
  bpy.ops.object.editmode_toggle()

if __name__ == "__main__":
  main()
```
実行結果：
画面は初期状態とし、立方体を消したうえで、そのままscriptingに移動してこれを実行することを想定しています。
[![実行結果.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437349/27c6e122-18c5-575e-9bf0-e4889f072b9c.png)
](curveExample)

## 説明
　まずここでは、カーブオブジェクトのデフォルトを作ったうえで、編集モードに移行しそれを消す、という操作を行っています。

```py
  # 最初に、プリミティブを作って編集に行ってそれ削除して、ってのを追加
  bpy.ops.curve.primitive_bezier_curve_add()
  bpy.ops.object.editmode_toggle()
  bpy.ops.curve.delete(type='VERT')
```
その状態でたとえばCtrl+右クリックで頂点を置いたり、ぐりぐりペンで描いて曲線を作るといったことができるようになります。その状態で、次のスクリプトでカーブオブジェクトを作っていきます。

```py
  # ここからがメインスクリプト
  for i in range(0,40):
    t = 2 * pi * i / 40
    x = 4 * cos(t)
    y = 3 * sin(t)
    z = t / 2
    bpy.ops.curve.vertex_add(location = (x, y, z))
```
ここでは円を描きつつ上昇させています。それが済んだら頭とおしりをつなぐのですが、そのために頂点を選択する必要があります。

```py
  # カーブが作れたらすべての頂点を選択する
  bpy.ops.curve.select_all(action='SELECT')

  # 参考：
  # https://docs.blender.org/api/current/bpy.ops.curve.html#bpy.ops.curve.select_all
  # https://docs.blender.org/api/current/bpy.ops.curve.html#bpy.ops.curve.make_segment

  bpy.ops.curve.make_segment()
  # 作成し終わったら選択解除
  bpy.ops.curve.select_all(action='DESELECT')
  # オブジェクトモードに戻す
  bpy.ops.object.editmode_toggle()
```
すべての頂点を選択するにはcurveのselect_allというメソッドを使います。SELECTで全選択、DESELECTで選択をすべて解除します。全選択された状態でmake_segmentを実行すると端っこ同士がつながって閉曲線ができます。終わったら選択を解除します。
　最後にオブジェクトモードに戻したら終了です。

## 複数の閉曲線を作る場合
　プリミティブを作って消すところからやり直せばそのまま別の曲線になります。こんな風に。

```py
import bpy
from math import pi, cos, sin

def main():

  for k in range(-2, 3):
  # 最初に、プリミティブを作って編集に行ってそれ削除して、ってのを追加
    bpy.ops.curve.primitive_bezier_curve_add()
    bpy.ops.object.editmode_toggle()
    bpy.ops.curve.delete(type='VERT')

  # ここからがメインスクリプト
    for i in range(0,8):
      t = 2 * pi * i / 8
      x = 4 * cos(t) + k
      y = 3 * sin(t) + k
      z = t / 2 + k
      bpy.ops.curve.vertex_add(location = (x, y, z))
  # カーブが作れたらすべての頂点を選択する
    bpy.ops.curve.select_all(action='SELECT')

    bpy.ops.curve.make_segment()
  # 作成し終わったら選択解除
    bpy.ops.curve.select_all(action='DESELECT')
  # オブジェクトモードに戻す
    bpy.ops.object.editmode_toggle()

if __name__ == "__main__":
  main()
```
実行結果：
[![実行結果2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437349/2d86d415-d168-62db-72db-ebde2a7366cd.png)
](kekka)

# おわりに
　具体的に数式で書けるカーブオブジェクトを生成するのに使えそうです。