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

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

【FreeCADプログラミング】フェースの法線ベクトルを取得

本日のお題は『フェースの法線ベクトルを取得』です。

法線ベクトルという言葉は、普段の生活の中ではなかなか出てこないため、とっつきにくいですかね。

簡単に言えば、面の向いている方向(ベクトル)です。

理屈と意味さえ分かってしまえば難しくはないので、あまり身構えず、ゆるく学んでいきましょう。

1. 環境

今回はFreeCADのtopoShape APIを使って、法線ベクトルを取得します。

  • FreeCAD 0.18

2. 法線ベクトルとは何か?

冒頭でフェースの法線ベクトルは簡単に言えば、フェースの向いている方向(ベクトル)と説明しましたが、実際はこれだと説明不足です。

もう少し踏み込むと、あるフェースのある位置における、フェースに垂直なベクトルです。

例えば、平面であれば法線方向はどこで取っても同じ方向になりますし、曲面であれば面上の位置によって方向が変わります。以下の画でなんとなく分かりますかね?

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

曲面の場合、位置によって法線ベクトルの方向が異なる

3. 法線ベクトルの取得方法

フェースの法線方向を取得する方法が本家『freecadweb.org』で紹介されています。

私の場合、ある意味見つかったのが奇跡かもしれませんが、本家のページの右上に『normal』と打って検索したら、ジャストミートな答えが出てきました。

Gui.Selection.getSelectionEx()[0].SubObjects[0].Faces[0].normalAt(0,0)

www.interested-or-not.com

ただ、引数の意味(特にnormalAt)が分からなかったため、もう少しネット上を調べていたところ、ヘビーユーザの多いfreecadweb.orgのフォーラムに有益な情報が掲載されていました。

forum.freecadweb.org

どうやら、このnormalAtは『UV空間』の概念を利用したAPIのようです。

『UV空間』というのは言ってみれば、曲面をピンとした平面に延ばした空間のようなものです。

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

UV空間のイメージ

UとVは、この縦と横の位置を表します。ただし、縦と横のどちらがU,Vになるかは不定だったはずなので、その点は注意が必要です。

上記リンク先に記載頂いているロジックは、ユーザが選択した面上点のUVを取得し、その位置の法線ベクトルをnormalAtで取得しています。

素晴らしいですね。正直、FreeCADにこれだけの機能が付いていると思いませんでした。

ドキュメントをあさると、もっと有用なAPIが出てくるかもしれませんね。

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

書くといっても、上記のリンクを引用させて頂いたもので、ほとんど変わりません。
(分かりやすいようにコメントだけ入れさせてもらいました。)

このプログラムは、事前に選択しておいたフェースの法線ベクトルを表示します。

# -*- 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.getSelectionEx()

if(len(sel) != 0):
    # 選択した位置
    pickCoord = sel[0].PickedPoints[0]
# 選択したフェース要素 selectedFace = sel[0].SubObjects[0]
# フェースからサーフェスを取得 # コレに関しては詳細不明。 # サーフェスじゃないとuvパラメータが取れないのかもしれないです) faceSurface = selectedFace.Surface
# UVパラメータを取得 uvCoord = faceSurface.parameter(pickCoord)
# 選択した位置の法線ベクトルを取得 normalVec = selectedFace.normalAt(uvCoord[0], uvCoord[1])
print(str(normalVec))

 

Vector (0.0, -1.0, 0.0)

5. まとめ

  • 法線ベクトルを取得するにはnormalAtを利用する
  • 法線ベクトルを取得する際はUV空間の概念を利用する

6. 最後に

フォーラムにいらっしゃるヘビーユーザの方々の意見は、有益なものが多いですね。

今度時間があったら、ネットサーフィンしてみたいと思います。

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

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

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

www.interested-or-not.com