環境:Houdini 20.5.487
作図する時に便利な矢印メッシュをつくってみた。
ノードネットワーク
ポリラインを引き、そのポリラインの長さで真っ直ぐな矢印メッシュをつくり、それをポリラインに沿って座標変換する流れ。

矢印を引くためのポリラインを用意する。

ポリラインには進行ベクトルNとアップベクトルupをアトリビュートに設定しておく。
矢印のメッシュをつくる

Z軸方向へメッシュを生成する。
//
// 矢印のシェイプを生成する
// RunOver: Detail
// input1: Polyline
//
float arrow_width = 2.5;
float arrow_height = 3;
float line_width = 1;
float step = 0.5;
// カーブの長さ
float curveLength = primintrinsic(1, "measuredperimeter", 0);
int num = int((curveLength - arrow_height) / step);
float dist = (curveLength - arrow_height) / (num-1);
// ポイントを配置していく
int pt[];
for(int i = 0; i < num; i++)
{
vector p0 = set(line_width/2*-1, 0, i * dist);
vector p1 = set(line_width/2, 0, i * dist);
pt[i*2] = addpoint(0, p0);
pt[i*2+1] = addpoint(0, p1);
}
// メッシュを張る
for(int i = 0; i < len(pt)/2-1; i++)
{
int prim = addprim(0, "poly");
addvertex(0, prim, pt[i*2]);
addvertex(0, prim, pt[i*2+1]);
addvertex(0, prim, pt[i*2+3]);
addvertex(0, prim, pt[i*2+2]);
}
// 矢印の根元の座標
float offset = (num-1) * dist;
vector arrow_pos[];
arrow_pos[0] = set(arrow_width/2, 0, offset);
arrow_pos[1] = set(0, 0, arrow_height + offset);
arrow_pos[2] = set(arrow_width/2*-1, 0, offset);
int prim = addprim(0, "poly");
addvertex(0, prim, pt[-2]);
addvertex(0, prim, pt[-1]);
for(int i = 0; i < len(arrow_pos); i++)
{
int arrow_pt = addpoint(0, arrow_pos[i]);
addvertex(0, prim, arrow_pt);
}

ポイントの並びはこのようになる。
ポリラインに沿って座標変換する


//
// ポイント座標をポリラインの空間に合わせて変換する
// RunOver: Points
// input1: Polyline
//
float curveLength = primintrinsic(1, "measuredperimeter", 0);
// 実際の長さで割る
float dist = @P.z / curveLength;
vector2 posuv = set(dist, 0);
// 実際のカーブ上の座標
vector curvepos = primuv(1, "P", 0, posuv);
// 行列計算
vector N = primuv(1, "N", 0, posuv);
vector up = primuv(1, "up", 0, posuv);
matrix m = maketransform(N, up, curvepos);
@P.z = 0.0;
@P *= m;