RhinoPython の Tips #2 – オブジェクトを適切に選択するための関数

最終更新日

スクリプトから Rhino のコマンドを実行した前回の記事に引き続き、RhinoPython について書いていきます。

今回は、連番処理や重い作業の自動化の中で必要なオブジェクトを適切に選択するための関数についてまとめてみようと思います。

(筆者が使ったことのある関数を中心に書いていくので抜けはありますがご容赦ください & ほかにも便利な関数があるよとコメント等で教えて下さい)

RhinoScriptSyntax の選択に関する関数について

まずは、RhinoScriptSyntax のドキュメントより選択に関する関数はこちら

https://developer.rhino3d.com/api/RhinoScriptSyntax/#selection


いくつか関数を挙げてみます。細かな引数やオプションについてはドキュメントを参照してください。

すべてのオブジェクトを選択し guid(注1)を取得する

rs.AllObjects()

デフォルト引数として select=False というものが設定されています。これはライノ上でオブジェクトを選択状態にするかどうかという設定で、RhinoPython で処理する上では基本的に False で良いです。

前回の記事のように rs.Command() を用いて Rhino の関数をスクリプト内で実行するときには Select=Ture にして Rhino のコマンドにオブジェクトを渡す必要があります。

select=False の場合(select=False がデフォルト引数なので何も書かなければ False となります)
select=True の場合。ライノ上のオブジェクトが選択状態になる

オブジェクトをマウス操作で選ばせ、それらのオブジェクトの guid を返す

rs.GetObject()
rs.GetObjectEx()
rs.GetObjects()

### Curve をユーザに指定させる場合
###     message により、Select Curve というメッセージが出ます。
###     filter により、選択できるオブジェクトはカーブだけになります。
curve_ids = rs.GetObject(message="Select Curve", filter=4)

rs.GetObjectEx() に関しては使ったことがないので使い勝手はわかりませんが、返り値として情報がまとまって返ってくるようです。デフォルト引数‘の select=False については前述のとおり。

message という引数(デフォルトは None)があり、これは実行時に表示するメッセージを設定できます。選ぶべきオブジェクトについて説明しておくと親切だと思います。例えば断面の曲線をユーザに選んでほしい場合には message=”Select Profile-Curve” などが設定できると思います。

filter という引数(デフォルトは 0)もあり、これは選択できるオブジェクトの種別を指定できます。これにより間違ったオブジェクトを選ぶことを防ぐことができます。例えば断面の曲線をユーザに選んでほしい場合には filter=4 とすると選択可能なオブジェクトがカーブだけになります。filter に渡すべきはジオメトリの種別を数値で渡しますが、それは後述します。

現在 Rhino で選択状態のオブジェクトの guid を取得する

rs.SelectedObjects()

ライノ上のオブジェクトの選択状態を解放する

rs.SelectedObjects() で guid を取得したあとにこの関数で選択状態を開放することが多いです。

rs.UnselectAllObjects()

指定したレイヤーに含まれるオブジェクトの guid を返す

rs.ObjectsByLayer(layer_name)

Elefront でも似たような機能がありますがこれが便利。デフォルト引数の select=False については前述のとおり。

指定した型のオブジェクトの guid を返す

rs.ObjectsByType(geometry_type)

"""
geometry_type
        Value        Description
         0           All objects
         1           Point
         2           Point cloud
         4           Curve
         8           Surface or single-face brep
         16          Polysurface or multiple-face
         32          Mesh
         256         Light
         512         Annotation
         4096        Instance or block reference
         8192        Text dot object
         16384       Grip object
         32768       Detail
         65536       Hatch
         131072      Morph control
         134217728   Cage
         268435456   Phantom
         536870912   Clipping plane
         1073741824  Extrusion
"""

### Point を取得する場合
point_ids = rs.ObjectsByType(1)

### Curve を取得する場合
curve_ids = rs.ObjectsByType(4)

Elefront でも似たような機能がありますがこれが便利。オブジェクトの種類の指定は数値で指定します。デフォルト引数の select=False については前述のとおり。

オブジェクトを guid で指定して、ライノ上で選択状態にする

rs.SelectObject(id)
rs.SelectObjects(ids)

スクリプト内では guid で受け渡ししているので選択状態にする必要はないですが、処理の最後にこの関数でオブジェクトを選択状態にして終わることがあります。

手元にあったスクリプトを確認してみると以上のものが頻繁に使われてました。現在進行形のプロジェクトでは rs.ObjectByHoge() のような既存の関数によるフィルタリングと合わせて、オブジェクトに書き込まれた UserText を用いてフィルタリングも併せて行っています。近いうちにこれについても書ければと思います。

まとめ

面倒な作業をスクリプトで処理できれば便利ですが、選ぶべきものを適切に選ぶことができなければ、手作業でミスなくオブジェクトを選択する必要になったり、そもそもうまく機能しなかったりと面倒な作業を手放すことができません。

「手作業で」という部分を残すと、処理するファイルや選ぶべきオブジェクトの数が多ければ煩雑になり単純な作業ミスをしてしまう可能性は残ります。そのためには適切な関数を用いて自動で選ぶべきものを選ぶことやフィルターとして機能させることで、ミスなく処理していくための方法を考えることが大事と考えています。ミスをなく作業をしていくことの難しさを日々感じてるので似たような話が次回へ続きます。

(余談になりますが、毎回記事を書くにあたり公式のドキュメントを読み返すと、自分の誤認識や探していたあの機能が見つかります…。フォーラムに貼ってあるコードをガチャガチャ試すだけでなく、公式のドキュメントの読み込むことが手早く適切な実装をするための近道だと感じています。)



(注1) Rhino ではオブジェクトごとに guid (globally unique identifier) が振られて管理されています。詳しくは以下を参照。 https://developer.rhino3d.com/api/RhinoCommon/html/P_Rhino_DocObjects_RhinoObject_Id.htm

naoki.yoshioka

主にファサードプロジェクトを担当。使用言語は日本語と Python。C++(と英語)を勉強中。

シェアする