Revitで実際の形状に基づくBoundingBoxの取得

皆様こんにちは。
AMDlabのテキです。

今回はBoundingBoxの話をしたいと思います。
BoundingBoxは要素の位置や大きさを取得する際によく使用されます。
干渉判定や自動配置、寸法配置など、Revitアドインを開発していると利用する機会は非常に多くあります。
Revit APIには get_BoundingBox() が用意されているため、一見すると簡単に取得できそうに思えるでしょう。
しかし、実際に使用してみると、「思ったよりBoundingBoxが大きい」「実際の形状と一致しない」といったケースに遭遇することがあります。
今回は、その原因と、Solidの実際の形状に基づくBoundingBoxの取得方法を紹介します。


1. BoundingBoxの種類

BoundingBoxには主に次の2種類があります。

AABB(Axis-Aligned Bounding Box)

AABBは座標軸に平行なBoundingBoxです。
Revit APIの BoundingBoxXYZ が採用している方式であり、モデル座標系のX・Y・Z軸に常に平行となります。
AABBは計算が非常に高速であるため、多くのCAD・BIMソフトウェアで採用されています。
一方で、斜めに配置された部材では、実際の形状よりも大きな領域を持ってしまうという特徴があります。


OBB(Oriented Bounding Box)

OBBは部材の向きに合わせて回転したBoundingBoxです。
実際の形状によりフィットするため、余分な空間をほとんど持ちません。
その反面、計算量はAABBより大きくなります。
Revit APIではOBBは標準では提供されておらず、BoundingBoxXYZ が返すBoundingBoxはすべてAABBとなります。


2. Revitの get_BoundingBox() の落とし穴

Revit APIでは、次のように簡単にBoundingBoxを取得できます。
BoundingBoxXYZ? bbox = element.get_BoundingBox(null);
一見すると、要素の実際の形状に基づくBoundingBoxが取得できるように思えます。
しかし、Autodesk公式ドキュメントには、BoundingBoxについて次のような記載があります。

Original(Remarks)

Also note that this bounding box volume may enclose geometry that is not obvious. For example, the “flip controls” that could be part of a family will be included in the computation of the bounding box even though they are not always visible in the family instance of the family.

参考:https://help.autodesk.com/cloudhelp/2026/ENU/Revit-API-MainReference/files/html/def2f9f2-b23a-bcea-43a3-e6de41b014c8.htm
日本語訳

BoundingBoxには、一見分かりにくいジオメトリが含まれる場合があります。例えば、ファミリに含まれる「Flip Control」は、ファミリインスタンス上では常に表示されるわけではありませんが、BoundingBoxの計算には含まれます。

実際には、Autodesk CommunityやDynamo Forumでも、VisibilityをOFFにしたジオメトリがBoundingBoxに含まれるという報告が複数挙がっています。
参考:https://forums.autodesk.com/t5/revit-api-forum/element-boundingbox-ignore-non-visible-items/td-p/8924771
すなわち、get_BoundingBox()で取得したBoundingBoxは、Solidの実際の形状と一致しないケースがあります。
私も実際の開発で、ファミリ内で非表示(Invisible)に設定した部材が BoundingBox に含まれる現象に遭遇しました。
配置判定や寸法配置などで、実際の形状に基づいた範囲を取得したい場合は、get_BoundingBox() の結果をそのまま利用すると、意図しない位置判定や寸法位置のずれが発生する可能性があります。


3.Solidの実際の形状に基づくBoundingBoxを取得する

実際の形状により近いBoundingBoxを取得したい場合は、Solidの境界からBoundingBoxを再計算します。
処理の流れは非常にシンプルです。

各Edgeを Tessellate() により点列へ変換し、それらの最小座標・最大座標を求めることでBoundingBoxを作成します。
コードは次のようになります。

この方法では、Solidの境界からBoundingBoxを算出するため、get_BoundingBox() が実際の形状により近いBoundingBoxを取得できます。
特に、ファミリ内のFlip Controlなど、実際のモデル形状に関係しない要素の影響を受けずにBoundingBoxを取得したい場合に有効です。


まとめ

今回紹介したポイントは次のとおりです。

  • BoundingBoxにはAABBとOBBの2種類がある
  • Revit APIの BoundingBoxXYZ はAABBを採用している
  • get_BoundingBox() は、実際のSolid形状以外の要素を含んで計算される場合がある
  • より実際の形状に近いBoundingBoxが必要な場合は、Solidの境界から再計算する方法が有効である

なお、今回紹介した方法も、最終的に算出されるBoundingBoxはAABBです。
そのため、斜めのエレメントは依然として余分な領域が含まれる場合があります。
今後機会があれば、部材のローカル座標系を利用したOBBの生成方法についても紹介したいと思います。

最後

AMDlabでは、開発に力を貸していただけるエンジニアさんを大募集しております。少しでもご興味をお持ちいただけましたら、カジュアルにお話するだけでも大丈夫ですのでお気軽にご連絡ください!
中途求人ページ: https://www.amd-lab.com/recruit-list/mid-career

カジュアル面談がエントリーフォームからできるようになりました。
採用種別を「カジュアル面談(オンライン)」にして必要事項を記載の上送信してください!
エントリーフォーム: https://www.amd-lab.com/entry

AMDlabのSNSアカウントです!ぜひフォローお願いします✨

■ X(旧Twitter):https://x.com/amdlabinc
■ Instagram:https://www.instagram.com/amdlabinc/
■ Facebook:https://www.facebook.com/amdlab.lnc/

BIM
Revit アドイン
Tech
C#
ARTICLES