※アイキャッチ画像はDALL·E 3で作成しました。
はじめに
AMDlab BIMエンジニアの河野(twitter@tatsukikouno)です。
RevitAPIで学ぶC#シリーズ、第2弾です。
前回の記事では、Revitのクラス構造と基本的な調べ方について掘り下げました。
今回はRevitクラスの継承関係を観察し、継承という概念が如何にしてBIMを構造化し、柔軟性を高めているのか見ていきましょう。
RevitAPIでつかわれている継承を確認しよう
C#をはじめとしたOOPでは、クラス間に親と子の関係を持たせることを継承と呼んでいます。
継承関係にある親のことは基底クラス、子のことは派生クラスと呼ばれます。
前回同様、OOPにおける継承とは…といった解説は省略し、さっそくRevitAPIを例にとって継承関係を見てみましょう。
はじめに、Revitに配置できる要素は全てIDを保持していることは皆さんご存知でしょうか。
ある壁インスタンスについて、Revit LookupでSnoop Selectionしてみると以下のとおりです。
Idというプロパティがあります。
このIdプロパティは、Revitプロジェクト内で重複することのないユニークな値が割り当てられるものです。
次に、ある床インスタンスについてもSnoop Selectionしてみましょう。
さて、RevitAPIにおいて、壁インスタンスはWallクラス、床インスタンスはFloorクラスとして表現されますが、その両方が同じくIdプロパティを保持していました。
Idプロパティはそれぞれのクラスで定義されているのでしょうか?
RevitAPI DocsでIDプロパティ確認してみると以下のようになっています。
(Inherited from Element .)とありますね。
それぞれのクラスで定義されているのではなく、基底クラスであるElementクラスで定義されているものを継承しているようです。
クラスの継承関係はInheritance Hierarchyに記載されているため、見てみましょう。
上側が基底クラス、下側が派生クラスという階層になっています。
WallクラスとFloorクラスはどちらもElementクラスから派生したクラスであり、ElementクラスのIdプロパティを利用できている、ということになります。
継承のメリット
建築要素としては別物だけれども、別の視点では共通の振る舞いをしてほしいとき、継承が有用です。
今回の例では、Floorクラスは床、Wallクラスは壁としてそれぞれ振る舞う一方で、Revitプロジェクトに配置されている「要素」として共通の振る舞いをして欲しいわけです。
互いに重複しないIdを保持するというのも共通の振る舞いですし、もっと分かりやすいのは要素を選択するシーンでしょうか。
Revitでは床インスタンスも壁インスタンスも同時に選択することができます。
当たり前の話ではありますが、この挙動をプログラム目線で考えてみると「いま選択可能なのは対象はFloorクラスとWallクラスと…」と選別するより、「選択可能なのはElementクラス」とできたほうが簡単で汎用的です。
このように、FloorクラスとWallクラスがElementクラスとして振る舞うことで得られるメリットがいくつもあるのです。
RevitAPIの2大基底クラス
RevitAPIのクラスは、ほぼ全てが2大基底クラス(私が勝手にそう呼んでます)から派生しています。
以下は、RevitAPIの代表的なクラスを基底クラスごとまとめた図になります。
随分前に作ったものの流用ですので、間違えてたら教えて下さい。
- Elementクラス・・・Revitデータベースに保存される建築要素は全ての基底クラスです。WallやFloorもElementクラスの派生クラスでした。
- APIObjectクラス・・・属性を表すパラメータやカテゴリ、形状を表すジオメトリ等の基底クラスです。
「Elementは建築要素で、APIObjectは建築要素に紐づくデータ」と解釈しても良いかもしれませんね。
おわりに
「RevitAPIで学ぶC#」第二弾として、Revitクラスにみる継承関係とそのメリットについて解説しました。
今回もコードを使った解説ができず恐縮ですが、次回以降があればそのときに。
弊社では随時BIMエンジニア、コンピュテーショナルデザイナーを募集しています。
ご興味のある方は、DMかContactからご連絡ください。
COMMENTS