はじめに
概要
SideFXLabs19.5.519で追加されたLabs VEXについて少し深堀していこうと思う。
※本検証は2023/02/18時点で追加されている関数です。
環境
Houdini19.5
SideFXLabs19.5.519
そもそもLabs VEXってなに?
Labs VEXは新しいノードやVEX関数が追加されたわけではなく、SideFXLabsのインストールディレクトリ内にあるvex/includeに追加された、sidefxlabs_data.h
sidefxlabs_math.h
のことである。
ベクトル演算、データの並べ替え、変換などに便利なヘルパー関数が追加されているそうです。
使い方はAttributeWrangle SOPで以下のように記述すると使えるようになる。
#include <sidefxlabs_math.h>
#include <sidefxlabs_data.h>
include分の詳しい挙動に関しては以下を参照してください。
【Houdini】vexのinclude文の挙動@harayoki
VEX言語リファレンス
Labs VEXの関数一覧
Labs VEXはsidefxlabs_data.hに3種、sidefxlabs_math.hに19種の系22種の関数が用意されている。(2023/02/12現在)
labs_ftoa
labs_binary_search
labs_append_unique
labs_triarea
labs_planenormal
labs_istotheright
labs_isabove
labs_pointplanedist
labs_pointplaneproj
labs_pointlinedist
labs_pointlineproj
labs_pointsegmentdist
labs_pointsegmentproj
labs_isoutsidetri
labs_pointtriedgedist
labs_pointtriedgeproj
labs_pointtridist
labs_pointtriproj
labs_anglebetween
labs_rotatevector
labs_rotatevector2d
labs_getnoncollinear
この関数たちを1つずつ検証していきます。
sidefxlabs_data.h
labs_ftoa
float からStringに変換する関数
string labs_ftoa(number <float>)
string labs_ftoa(numer <float>, size <int>)
number : 変換したい数値
size : 小数点以下の桁数
ちなみにこちらはデフォルトだとエラーが出ます。(2023/02/18現在)
sidefxlabs_data.hファイルを書き換える必要があるため推奨しません。
修正方法
関数の順番を入れ替えることで使用可能になる
string labs_ftoa(const float f)
{
return labs_ftoa(f, 3);
}
string labs_ftoa(const float f; const int decimal_places)
{
return sprintf("%.*g", decimal_places + 1, f);
}
string labs_ftoa(const float f; const int decimal_places)
{
return sprintf("%.*g", decimal_places + 1, f);
}
string labs_ftoa(const float f)
{
return labs_ftoa(f, 3);
}
labs_binary_search
バイナリサーチを行う関数。
float labs_binary_search(array[] <int/float>, target <int/float>, &success <int>)
int labs_binary_search(array[] <string>, target <string>, &success <int>)
array[] : 探索元の配列
target : 検索したい値 (失敗時は-1)
&success : 検索成功か否かの値を返す(1 or 0)
&success
は返り値のため、変数を入れます。
labs_append_unique
配列に値が存在しない場合のみ値を追加できる関数。ある場合はスキップ。
void labs_append_unique(array[] <type[]>, value <type>)
void labs_append_unique(str <string>, value <string>)
array[] : 追加元の配列
value : 追加したい値
str : 追加元の文字列
int/float/vector2/vector/vector4/string配列対応
sidefxlabs_math.h
labs_triarea
Primitive(三角形)の面積を求める関数。
float labs_triarea(geohandle <int>, prim_num <int>)
float labs_triarea(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>)
float labs_triarea(a <vector>, b <vector>, c <vector>)
labs_planenormal
Primitive(三角形)の法線を求める関数。
vector labs_planenormal(geohandle <int>, prim_num <int>, is_normalize <int>)
vector labs_planenormal(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, is_normalize <int>)
vector labs_planenormal(a <vector>, b <vector>, c <vector>, is_normalize <int>)
is_normalize : 返り値を正規化するか否か。
左手の法則 (Houdini のデフォルトの面巻き順序) を使用します。
正規化されていない場合、出力ベクトルの大きさは入力三角形の面積になります。
labs_istotheright
任意点が特定の位置より右側にあるかを判定する関数。
int labs_istotheright(pivot <vector>, forward <vector>, up <vector>, pos <vector>)
forward : 前方ベクトル
up : 上向きベクトル
labs_isabove
任意点が面(三角形)より上(normal方向)にあるかを判定する関数。
int labs_isabove(geohandle <int>, prim_num <int>, pos <vector>)
int labs_isabove(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>)
int labs_isabove(plane_pos <vector>, plane_normal <vector>, pos <vector>)
int labs_isabove(a <vector>, b <vector>, c <vector>, pos <vector>)
labs_pointplanedist
ポイントからと無限平面までの距離を求める関数。
float labs_pointplanedist(geohandle <int>, prim_num <int>, pos <vector>)
float labs_pointplanedist(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>)
float labs_pointplanedist(plane_pos <vector>, plane_normal <vector>, pos <vector>)
float labs_pointplanedist(a <vector>, b <vector>, c <vector>, pos <vector>)
ポイントa/b/cまたはpt0/pt1/pt2の3点から構成される面が計算される。
labs_pointplaneproj
ポイントから無限平面までの距離と最近接点を求める関数。
float labs_pointplaneproj(geohandle <int>, prim_num <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointplaneproj(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointplaneproj(plane_pos <vector>, plane_unit_normal <vector>, pos <vector>, &nearest_pos <vector>)
float labs_pointplaneproj(a <vector>, b <vector>, c <vector>, pos <vector>, &nearest_pos <vector>)
&nearest_pos
は返り値のため、変数を入れます。
labs_pointlinedist
ポイントからと無限直線までの距離を求める関数。
float labs_pointlinedist(geohandle <int>, prim_num <int>, pos <vector>)
float labs_pointlinedist(geohandle <int>, pt0 <int>, pt1 <int>, pos <vector>)
float labs_pointlinedist(line_pos <vector>, line_direction <vector>, pos <vector>)
これは、外積 (三角面積) アプローチよりも正確です。
labs_pointlineproj
ポイントから無限直線までの距離と最近接点を求める関数。
float labs_pointlineproj(geohandle <int>, prim_num <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointlineproj(geohandle <int>, pt0 <int>, pt1 <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointlineproj(line_pos <vector>, line_direction <vector>, pos <vector>, &nearest_pos <vector>)
&nearest_pos
は返り値のため、変数を入れます。
labs_pointsegmentdist
ポイントから無限直線までの距離を求める関数。
float labs_pointsegmentdist(geohandle <int>, prim_num <int>, pos <vector>)
float labs_pointsegmentdist(geohandle <int>, pt0 <int>, pt1 <int>, pos <vector>)
float labs_pointsegmentdist(a <vector>, b <vector>, pos <vector>)
labs_pointsegmentproj
ポイントから無限直線までの距離と最近接点を求める関数。
float labs_pointsegmentproj(geohandle <int>, prim_num <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointsegmentproj(geohandle <int>, pt0 <int>, pt1 <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointsegmentproj(a <vector>, b <vector>, pos <vector>, &nearest_pos <vector>)
&nearest_pos
は返り値のため、変数を入れます。
labs_isoutsidetri
ポイントが三角面内にあるかを判定する関数。
int labs_isoutsidetri(geohandle <int>, prim_num <int>, pos <vector>)
int labs_isoutsidetri(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>)
int labs_isoutsidetri(a <vector>, b <vector>, c <vector>, pos <vector>)
三角面の内側の場合は-1、辺上なら0、外側なら1を返す。
labs_pointtriedgedist
ポイントが三角形の辺までの距離を求める関数。
float labs_pointtriedgedist(geohandle <int>, prim_num <int>, pos <vector>)
float labs_pointtriedgedist(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>)
float labs_pointtriedgedist(a <vector>, b <vector>, c <vector>, pos <vector>)
三角面の内側の場合は負、外側なら正の値を返す。
labs_pointtriedgeproj
ポイントが三角形の辺までの距離と最近接点を求める関数。
float labs_pointtriedgeproj(geohandle <int>, prim_num <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointtriedgeproj(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointtriedgeproj(a <vector>, b <vector>, c <vector>, pos <vector>, &nearest_pos <vector>)
&nearest_pos
は返り値のため、変数を入れます。
三角面の内側の場合は負、外側なら正の値を返す。
labs_pointtridist
ポイントが三角形の面(無限平面)までの距離を求める関数。
float labs_pointtridist(geohandle <int>, prim_num <int>, pos <vector>)
float labs_pointtridist(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>)
float labs_pointtridist(a <vector>, b <vector>, c <vector>, pos <vector>)
labs_pointtriproj
ポイントが三角形の面(無限平面)までの距離と最近接点を求める関数。
float labs_pointtriproj(geohandle <int>, prim_num <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointtriproj(geohandle <int>, pt0 <int>, pt1 <int>, pt2 <int>, pos <vector>, &nearest_pos <vector>)
float labs_pointtriproj(a <vector>, b <vector>, c <vector>, pos <vector>, &nearest_pos <vector>)
&nearest_pos
は返り値のため、変数を入れます。
labs_anglebetween
2辺の間の角度を求める関数。
float labs_anglebetween(a <vector>, b <vector>, is_degrees <int>)
is_degree : 返り値がDegreeなら1を、Radianなら0を設定する。
labs_rotatevector
ベクトルを回転する関数。
vector labs_rotatevector(v <vector>, angle <float>, axis <vector>, is_degrees <int>)
vector labs_rotatevector(v <vector>, a <vector>, b <vector>)
is_degree : angleの値がDegreeなら1を、Radianなら0を設定する。
aからbまで回転する量だけvを回転させる。
labs_rotatevector2d
2Dベクトルを回転する関数。
vector2 labs_rotatevector2d(v <vector2>, angle <float>, is_degrees <int>)
vector2 labs_rotatevector2d(v <vector2>, a <vector2>, b <vector2>)
is_degree : angleの値がDegreeなら1を、Radianなら0を設定する。
aからbまで回転する量だけvを回転させる。
labs_getnoncollinear
非コリニアベクトルを求める関数。
vector labs_getnoncollinear(v <vector>)
{Z,X,-Y}のベクトルを返す。
おわりに
基本的にはヘルパー関数なので、シンプルな関数が多い印象ですね。微妙に使える部分も多いのかな...?
もっと関数の種類が増えるといいですね。
それでは、しゃーした~。