興味があろうがなかろうが。

なるべく役に立つ、とがった内容を記していきたいと思います。

【FreeCADプログラミング】バウンディングボックス(AABB)の取得

本日は『バウンディングボックスの取得』について説明していきたいと思います。

この単語を知らない方はいきなり意味不明ですよね。

今回は長くなりそうなので、早速解説にいってみたいと思います。

1. 環境

  • FreeCAD 0.18

2. バウンディングボックスの取得方法

2.1. バウンディングボックスとは?

バウンディングボックスはまたの名を『境界ボックス』、『バウンダリボックス』と呼んだりします。

一言で言ってしまうと、『ある物体を包含する箱』のことを指します。

例えば、以下のような感じですね。

f:id:appli-get:20200516173307j:plain

バウンディングボックスのイメージ(AABB)

実際には箱の形状は作成せず、座標の1番小さい位置の座標と、1番大きい座標を取得します。

いくつかのCADを見てきましたが、ほぼ全てに算出用のAPIが用意されていました。

2.2. どういうところで使う?

よく言われるのは『物体同士の当たり判定』ですかね。あとは、複数のバウンディングボックスから、1番外側の位置を算出する時などに使います。

2.3. どうやって計算する?

残念ながら、自前でAPIを作れるほど簡単なロジックではないため、今回はFreeCADのAPIを使います。

取得方法は簡単で、各オブジェクトに用意されているBoundBoxプロパティを使用します。

2.4. バウンディングボックスは2種類ある

一般的に、バウンディングボックスには下記の2種類があり、使用用途によって、使い分けられています。

  1. 軸に平行なバウンディングボックス
    (Axis Aligned Bounding Box ⇒ AABBと呼ばれます)
  2. とある方向に関連づいたバウンディングボックス
    (Oriented Bounding Box ⇒ OBBと呼ばれます)

ちなみに2.2の絵で説明したのはAABBであり、OBBは以下のようなバウンディングボックスです。

f:id:appli-get:20200516173317j:plain

バウンディングボックスのイメージ(OBB)

3. プログラムを書いてみよう

今回のプログラムでは、選択した履歴から、ソリッド・とあるフェース・とあるエッジのAABBを取得していきます。

# -*- coding: utf-8 -*-

#import ptvsd
#print("Waiting for debugger attach")
# 5678 is the default attach port in the VS Code debug configurations
#ptvsd.enable_attach(address=('localhost', 5678), redirect_output=True)
#ptvsd.wait_for_attach()

import FreeCAD
import FreeCADGui

sel = FreeCADGui.Selection.getSelection()

if(len(sel) != 0):
	# ソリッドのAABBを取得
	solid = sel[0].Shape
	FreeCAD.Console.PrintMessage("ソリッドのAABB: " + str(solid.BoundBox) + "\n")
	
	# 1枚目のフェースのAABBを取得
	face = solid.Faces[0]
	FreeCAD.Console.PrintMessage("とあるフェースのAABB: " + str(face.BoundBox) + "\n")

	# 1本目のエッジのAABBを取得
	edge = solid.Edges[0]
	FreeCAD.Console.PrintMessage("とあるエッジのAABB: " + str(edge.BoundBox) + "\n")

 

ソリッドのAABB: BoundBox (15, 0, 0, 25, 10, 10)
とあるフェースのAABB: BoundBox (15, 0, 0, 15, 10, 10)
とあるエッジのAABB: BoundBox (15, 0, 0, 15, 0, 10)

ひとまず、値は取れているようですね。

取得された値の各位置は、下図のような感じになります。

f:id:appli-get:20200516181307p:plain

ソリッドから取得された座標位置(赤ポチの位置)

f:id:appli-get:20200516181314p:plain

フェースから取得された座標位置(赤ポチの位置)

f:id:appli-get:20200516181324p:plain

エッジから取得された座標位置(赤ポチの位置)

4. 補足

4.1. OBB取得用のAPIは無い?

今回調査した感じでは、OBBを取得するAPIはどうやら用意されていないようです。

OBBの取得は、AABBの取得よりも使用頻度が高く、できれば使いたいところですが、こればっかりは仕方ないですね。

とはいえ、OBBが必要になってくるタイミングは絶対にあります。

ということで、いずれ強引な方法でOBBを取得する方法を紹介したいと思います。
(まだロジックしか検討できていないので、絶対にできるかわかりませんが、できたら紹介します)

もしOBBを取得するAPIをご存じの方がいらっしゃいましたら、コメントを頂けると幸いです。

5. まとめ

  • バウンディングボックスは、オブジェクトを包含する箱である
  • バウンディングボックスには、AABBとOBBがある
  • バウンディングボックスを取得できるのは、ソリッドだけではない
    (フェースやエッジも取得可能)

6. 最後に

バウンディングボックスは様々なシーンで利用されます。

まずは、プログラムの書き方は覚えなくてもよいので、こういった概念があることを頭に入れておきましょう。

更なる情報をお探しの方は!

下記のリンクから、FreeCADプログラミングのトップページに飛びます。

よろしければご参照くださいませ。

www.interested-or-not.com