ghPython での、RhinoScriptSyntax と RhinoCommon のパフォーマンス比較
Grasshopper 上で Python を書くサンプルとして、RhinoScriptSyntax を使っているものをよく見かけるが、RhinoScriptSyntax ではなく、RhinoCommon を使うという方法がある。(そもそも別のモノであるので、互換という意味ではないので、あしからず。)
ご認識があったらすみません。
参考記事
RhinocerosとGrasshopperでPythonを使う方法(Qiita)
Rhinoceros / Grasshopperでコーディングしたい人のためのレファレンス参照先(Qiita)
RhinoScriptSyntax と RhinoCommmon
RhinoScriptSyntax では、RhinoCommon を Python でラップしているので、早くなる理由が無い。RhinoScriptSyntax の中身を見たければここ。
C:\Users\NAME\AppData\Roaming\McNeel\Rhinoceros\6.0\Plug-ins\IronPython (XXXX-XXX-XXXX-XXXX)\settings\lib\rhinoscript
参考までに、rs.AddLine() の実装は以下。
### curve.py
def AddLine(start, end):
"""Adds a line curve to the current model.
Parameters:
start, end (point|guid) end points of the line
Returns:
guid: id of the new curve object
Example:
import rhinoscriptsyntax as rs
start = rs.GetPoint("Start of line")
if start:
end = rs.GetPoint("End of line")
if end: rs.AddLine(start, end)
See Also:
CurveEndPoint
CurveStartPoint
IsLine
"""
start = rhutil.coerce3dpoint(start, True)
end = rhutil.coerce3dpoint(end, True)
rc = scriptcontext.doc.Objects.AddLine(start, end)
if rc==System.Guid.Empty: raise Exception("Unable to add line to document")
scriptcontext.doc.Views.Redraw()
return rc
パフォーマンス比較
話題がそれたが、ghPython での、RhinoScriptSyntax と RhinoCommon のパフォーマンス比較をざっくり書く。把握できていない関数や引数もおそらく多くあるので厳密ではないです。
#######################################
## Grasshopper Performance Test ##
## RhinoScriptSyntax / RhinoCommon ##
#######################################
import time
import Rhino.Geometry as rg
import rhinoscriptsyntax as rs
### RhinoScriptSyntax
def center_box_by_rss(cx, cy, cz, w, h, d):
pl_base = rs.MovePlane(rs.WorldXYPlane(), (cx, cy, cz))
rc = rs.AddRectangle(pl_base, w, h)
rc_c = rs.CopyObject(rc)
rc_mv = rs.MoveObject(rc_c, ((-1)*0.5*w, (-1)*0.5*h, (-1)*0.5*d))
bx = rs.ExtrudeCurveStraight(rc_mv, (0,0,0), (0,0,d))
cap_tf = rs.CapPlanarHoles(bx)
return pl_base, bx
### RhinoCommon
def center_box_by_rg(cx, cy, cz, w, h, d):
pl_base = rg.Plane.WorldXY
pl_base.Translate(rg.Vector3d(cx,cy,cz))
w_i = rg.Interval((-1)*0.5*w, 0.5*w)
h_i = rg.Interval((-1)*0.5*h, 0.5*h)
rc = rg.Rectangle3d(pl_base, w_i, h_i)
rc.Transform(rg.Transform.Translation(0, 0, (-1)*0.5*d))
rc_curve = rc.ToNurbsCurve()
bx = rg.Extrusion.Create(rc_curve, d, True)
return pl_base, bx
COUNT = 1000
########################
time1 = time.time()
########################
### Run RhinoScriptSyntax
pl = []
bx = []
for i in xrange(COUNT):
p, b = center_box_by_rss((i+1)*3, (i+1)*3 ,(i+1)*3, 1,1,1)
pl.append(p)
bx.append(b)
########################
time2 = time.time()
########################
### Run RhinoCommon
pl = []
bx = []
for i in xrange(COUNT):
p, b = center_box_by_rg((i+1)*3, (i+1)*3 ,(i+1)*3, 1,1,1)
pl.append(p)
bx.append(b)
########################
time3 = time.time()
########################
time_rss = time2 - time1
time_rg = time3 - time2
print("RhinoScriptSyntax - time : {} sec".format(time_rss))
print("RhinoCommon - time : {} sec".format(time_rg))
結果は以下の通り。環境は、Intel Core i5 第四世代、メモリ8GB
RhinoScriptSyntax - time : 1.26507568359 sec
RhinoCommon - time : 0.0220031738281 sec
RhinoCommon のほうが早く、かなりの差がある(RhinoScriptSyntax のほうの実装でパフォーマンスが悪い関数を使ってしまっているいう可能性はある)。コード内の COUNT の値を変えても、この傾向は変わらない。
RhinoScriptSyntax には高級な関数がそろっているため比較的簡単に書けるというメリットがあると思うが、パフォーマンスは落ちてしまうということがわかる。
ほかにも、RhinoCommonと RhinoScriptSyntax に加えて、ghpythonlib という、Grasshopper のコンポーネントを呼び出すという方法もある。これは、csharp で書かれビルド済みのコンポーネントを呼び出しているので、おそらく RhinoScriptSyntax より早いかと(確認はしていません)。
(終わり)