Chapter 05

Django Rest Frameworkのセットアップ③(Rhinoファンクション)

Rhinoファンクション

次にTwisted Towerを返すRhinoの関数を作ります。

ディレクトリを作成

まず、apiディレクトリ内にrhino_commandsというディレクトリを作り、その中に__init__.pycommands.pyを作ります。

mkdir api/rhino_commands
touch api/rhino_commands/__init__.py
touch api/rhino_commands/commands.py

関数を作成

次に、commands.pyに関数を書いていきます。
ポイントがいくつかあるので、下記で解説します。

import rhinoinside
rhinoinside.load()
import Rhino.Geometry as rg
import System
import Newtonsoft.Json
import json
import math

def twisted_tower_command(base_curve_json, center_point_json, angle, height):
    # desirialize : stringをjsonに戻してからRhinoオブジェクトに変換
    base_curve = Newtonsoft.Json.JsonConvert.DeserializeObject(json.loads(base_curve_json), rg.Curve)
    center_point = Newtonsoft.Json.JsonConvert.DeserializeObject(json.loads(center_point_json), rg.Point3d)
    # 角度をラジアンに変換
    rad = math.radians(angle)
    # 回転させるtransform
    print(rad, rg.Vector3d(0.0,0.0,1.0), center_point)
    rotation = rg.Transform.Rotation(rad, rg.Vector3d(0.0,0.0,1.0), center_point)
    # 上に動かすtransform
    move = rg.Transform.Translation(0.0,0.0,height)
    # transformを結合
    trns = rg.Transform.Multiply(rotation, move)
    # 上のカーブを作成
    top_curve = base_curve.Duplicate()
    top_curve.Transform(trns)
    # カーブのリスト
    curvs = System.Collections.Generic.List[rg.Curve]()
    curvs.Add(base_curve)
    curvs.Add(top_curve)
    # ロフト
    loft = rg.Brep.CreateFromLoft(curvs, rg.Point3d.Unset, rg.Point3d.Unset, rg.LoftType.Normal,False)[0]
    # シリアライズして更にstringに変換
    loft_json = json.dumps(Newtonsoft.Json.JsonConvert.SerializeObject(loft))
    return loft_json

①Rhino.Insideを読み込む

Python3上でRhinoのSDKを使うためには下記2点が必要です。

  • WindowsにRhino7がインストールされている
  • rhinoinsideのライブラリがインストールされている

その上で、Pythonファイルに下記2行を書くことでRhino上のIronPythonのようにRhinocommonがインポートできるようになります。
また、pythonnetという.NETを呼び出すためのライブラリもついでに読み込まれるので、IronPythonのように使うことができます。
ちなみに、clr.AddReferenceしなくてもRhinoに入っているDLLはインポートできます。

import rhinoinside
rhinoinside.load()
# Rhinocommonなどがインポートできる
import Rhino
import System

②RhinoオブジェクトをJson形式に変換する

HTTPリクエストでREST APIにアクセスするには、オブジェクトをシリアライズ(直列化)する必要があります。
Pythonではheaderやbodyをdictionary形式で書き、それをシリアライズしてリクエストしています。
当然Rhinoのオブジェクトはそのままでは送れないので一度文字列に変換する必要があり、逆に受け取った側は文字列からRhinoオブジェクトに変換しなければいけません。
compute.rhino3dでも同様のことが行われており、返ってきた結果をRhinoオブジェクトに戻すときにrhino3dm.CommonObject.Decode()と記述します。
説明が長くなりましたが、今回は.NETのNewtonsoft.Jsonを使ってシリアライズ・デシリアライズを行います。
シリアライズするときは、Newtonsoft.Jsonを使ってRhinoオブジェクトをJson化したあと、json.dumpsをするという2段階の操作をします。

import Newtonsoft.Json
import json
# シリアライズ
Newtonsoft.Json.JsonConvert.SerializeObject(json.dumps(rhino_obj))
# デシリアライズ
Newtonsoft.Json.JsonConvert.DeserializeObject(json.loads(serialized_data), rg.Curve)

例えば、今回読み込むカーブとかは下記のように変換されます。

{"version":10000,"archive3dm":60,"opennurbs":-1938524567,"data":"+n8CAEkBAAAAAAAA+/8CABQAAAAAAAAA5tTXTkfp0xG/5QAQgwEi8E6cu9v8/wIAEQEAAAAAAAAQCAAAAJ8TFwEmhnVALzCYPE0OMcAAAAAAAAAAAA2/hhDlj3RAnMwNC7JWD8AAAAAAAAAAAN0QSR4HEXVA0BDCbPVQIUAAAAAAAAAAACUqoq5F/nVAmzKrhloeFUAAAAAAAAAAAGakeJ1zrHZAOy4C4D4yJkAAAAAAAAAAAHqS72mH93ZAaDRC9q2k/b8AAAAAAAAAAJ3xODFianZAFq0NO+75J8AAAAAAAAAAAJ8TFwEmhnVALzCYPE0OMcAAAAAAAAAAAAgAAAAAAAAAAAAAAKUjiKBwPDRAs67ZGt6WQUCVRbkfdzFJQPjz10tyXU9AvPBdyE0gU0DeVyJLQnxWQI6H5JUZRVpAAwAAAA/MIvr/fwKAAAAAAAAAAAA="}