RhinoPython の Tips #1 – スクリプトから Rhino のコマンドを実行する
前回の記事では、スクリプトを用いたファイル統合について書きました。その中の Python プログラムの細かな部分には触れていなかったので、これから RhinoPython の Tips を少しずつ書いていければと思っています。
まず初回は、rs.Command() という関数について書いていきます。
# 前回記事内32行目
rs.Command("-New \"Large Objects - Millimeters.3dm\"")
# 前回記事内38行目
rs.Command('_-Import {} _Enter'.format(base_path))
Rhino.Python について
はじめにオフィシャルのドキュメントへのリンクから。
Rhino.Python についての概要はこちら
What is Rhino.Python?
https://developer.rhino3d.com/guides/rhinopython/what-is-rhinopython/
RhinoScriptSyntax についての概要はこちら
RhinoScriptSyntax in Python
https://developer.rhino3d.com/guides/rhinopython/python-rhinoscriptsyntax-introduction/
RhinoScriptSyntax の関数のリファレンスはこちら
RhinoScriptSyntax Docs
https://developer.rhino3d.com/api/RhinoScriptSyntax/
これらをざっくりまとめると、Rhino ではいくつかの言語でのスクリプティングがサポートされており、比較的書きやすい Python という言語もサポートされています。
さらに、Python でのスクリプティングに対して、RhinoScriptSyntax というモジュールが用意され、非常に使いやすい環境が整えられています、という感じです。
rs.Command() とは
この関数は、RhinoPython から Rhino のコマンドを実行します。引数として Rhino に渡すコマンドを文字列で渡し実行します。
rs.Command("TEXT")
(文字列はシングルクォーテーション、もしくは、ダブルクォーテーションで囲みます。これは Python の文字列型の仕様です(念のため))
リファレンスはこちら
rs.Command (RhinoScriptSyntax Docs)
https://developer.rhino3d.com/api/RhinoScriptSyntax/#collapse-Command
いくつか例を示します。
次のコマンドでは New というファイルを新規作成するコマンドを実行します。
rs.Command("New")
次のコマンドでは Circle という円を作成するコマンドを実行します。
rs.Command("Circle")
※ 円を書くならば rs.AddCircle() という関数があるのでそれを使えばいいですが、前述の New や Import、Save などの操作は、rs.Command() から実行する必要があります。
特殊文字について
# 前回記事内32行目
rs.Command("-New \"Large Objects - Millimeters.3dm\"")
New というコマンドの前にハイフンがついています。これは特殊文字をつけることで挙動を指定するという仕様を利用しています。
(Large Objects – Millimeters.3dm の前後に \” がついていますが、これは Python のエスケープシーケンスという仕様によるもので、それによりここでは Large Objects – Millimeters.3dm をひとまとめにして送っています(念のため))
特殊文字をいくつかを挙げてみます。
! (感嘆符) : 1つ前のコマンドをキャンセルする
Rhino のエイリアスに登録されているものを見ると感嘆符が付いたものがいくつかありますね。
_ (アンダースコア) : それぞれの国の言語にローカライズされたライノでも英語でコマンドを実行する
英語もしくは日本語環境で利用しているとコマンドは英語ですが、フランス語やドイツ語環境ではその言語でコマンドが実行できるようです。ライノマクロのドキュメントに以下のような記述がありました。
For example: In the English version of Rhino, the following macro works:
Circle 3Point 0,0,0 1,1,0 0,3,0
But in the French version of Rhino, this won’t work. Instead you need one of these macros:
Cercle 3Point 0,0,0 1,1,0 0,3,0
_Circle _3Point 0,0,0 1,1,0 0,3,0
To make sure macros work worldwide, write them in English and put _ in front of all command names and options.
http://docs.mcneel.com/rhino/5/help/en-us/index.htm#information/rhinoscripting.htm
- (ハイフン) : ダイアログを表示せず、直接引数を渡せる
これはバッチ処理の際にダイアログボックスを出さずに自動で処理を進めるために必須となります。
ミリメートルのテンプレートで新しくライノを5回開くするということを想定して実際に書いてみます。バッチ処理としては、ライノを新規で開き何らかの処理をして保存して次へ、という繰り返しをしますがここでは簡易的に開く部分だけを繰り返します。
まずはハイフン無しの場合。
import rhinoscriptsyntax as rs
for i in xrange(5):
rs.Command("New \"Large Objects - Millimeters.3dm\"")
ハイフン無しのこのスクリプトを実行すると、テンプレートを選ぶためにエクスプローラが毎回表示されます(この実行前に何らかの作業をしていた場合、それを保存するか聞かれるので適切に yes/no を選択してください)。
テキストで Large Objects – Millimeters.3dm と指定していますが指定できていないようです。プロンプトのログを見てみます。
ログを確認すると New が流し込まれて実行され(上のマーキング)、そこで立ち上がったエクスプローラから Large Objects – Millimeters.3dm を選択したので New の関数が終了しています。そののちさらに Large Objects – Millimeters.3dm という文字列が流し込まれて、これは特に何らかの関数ではないので Unknown command となっています(下のマーキング)。
今回は5回なのでポチポチ選択しても特に困りませんが、これでは大量のファイルを順繰りにバッチ処理する際に、都度都度必要な項目を選択するという操作をする必要がありそれは面倒です。
次にハイフン有りの場合。
import rhinoscriptsyntax as rs
for i in xrange(5):
rs.Command("-New \"Large Objects - Millimeters.3dm\"")
こちらを実行すると意図した通りにまっさらなライノファイルが5回立ち上がります (こちらもこの実行前に何らかの作業をしていた場合、それを保存するか聞かれるので適切に yes/no を選択してください) 。
一応プロンプトのログを見てみます。
ログを確認すると -New が流し込まれて実行される際に Large Objects – Millimeters.3dm という文字列が適切な引数として認識されているようです。こちらであれば大量のファイルを処理する際にも特に操作を必要とせずに走ってくれるはずです。
(ちなみに、アンダースコアとハイフン両方を付ける場合はアンダースコアが先についている例が多いようです。)
以上の3つは使う機会が多い特殊文字だと思います。
申し訳ないのですが、rs.Command() に用いる特殊文字に関してのリファレンスを見つけることができませんでした。一応、以下のコマンドマクロについてのドキュメントに特殊文字についての記述がありましたので気になる人は下のリンクからどうぞ。
特殊文字に関する記述が含まれたドキュメントをご存じの方はコメントで教えていただけると幸いです、、!
Command macros and scripting (Rhino Docs)
http://docs.mcneel.com/rhino/5/help/en-us/index.htm#information/rhinoscripting.htm
まとめ
今回は、スクリプトから Rhino のコマンドを実行する rs.Command() という関数について書いてみました。この関数を使うと簡単にバッチ処理を書くことができます(gh と合わせたバッチ処理に関してはこちらの記事を参照してください)。
次回は引数としてオブジェクトを渡す時にオブジェクトを取得する方法やそれに関する関数について書く予定です。