環境:Houdini 20.5.487
ポリラインの両端を任意の長さでカットし、カットした位置にポイントが置かれるようにします。
処理の流れ

始点と終点からどれくらいの距離をカットするか決めたら、それぞれの点がポリラインのどのポイント区間にあるかを調べる。位置の直前のポイントのインデックスを記録しておく。同時に座標も計算しておく。

プリミティブから頂点をすべて外した状態にしてから、再度ポイントを追加して構成しなおす。始点の位置までポイントを削除していき、始点の位置にはポリラインの最初のポイントpts[0]を移動させる。同じ要領で終点もポリラインの最後のポイントpts[-1]を移動させ、以後のポイントを削除する。
コード
f[]@cut_length = {2.0, 3.2};
事前にアトリビュートを持たせておく。値は始点と終点からのカットする距離。始点から2m、終点から3.2mをカットする、といった感じ。
//
// ポリラインの両端をカットする
// Run Over: Primitives
//
// ポリラインを切る位置(始点側、終点側)
float cut_length[] = f[]@cut_length;
float start_length = cut_length[0];
float end_length = cut_length[1];
// カットするポリラインの座標やインデックスを探す
int start_idx = -1;
int end_idx = -1;
vector start_pos;
vector end_pos;
float curLength = 0;
int pts[] = primpoints(0, @primnum);
//
// 始点を調べる
//
if(start_length <= 0)
{
start_idx = 0;
start_pos = point(0, "P", pts[0]);
}
else
{
for(int i = 0; i < len(pts)-1; i++)
{
vector p0 = point(0, "P", pts[i]);
vector p1 = point(0, "P", pts[i+1]);
float dist = length(p1-p0);
// 始点と終点がどの範囲にあるか探す
if(curLength <= start_length && start_length <= curLength + dist)
{
start_idx = i;
float remainingDist = start_length - curLength;
start_pos = p0 + normalize(p1 - p0) * remainingDist;
break;
}
curLength += dist;
}
}
//
// 終点を調べる
//
curLength = 0;
if(end_length <= 0)
{
end_idx = pts[-1]-1;
end_pos = point(0, "P", pts[-1]);
}
else
{
float total_length = primintrinsic(0, "measuredperimeter", @primnum);
end_length = total_length - end_length;
for(int i = 0; i < len(pts)-1; i++)
{
vector p0 = point(0, "P", pts[i]);
vector p1 = point(0, "P", pts[i+1]);
float dist = length(p1-p0);
// 始点と終点がどの範囲にあるか探す
if(curLength <= end_length && end_length <= curLength + dist)
{
end_idx = i;
float remainingDist = end_length - curLength;
end_pos = p0 + normalize(p1 - p0) * remainingDist;
break;
}
curLength += dist;
}
}
// 頂点をポリラインからすべて除外する
int vertices[] = primvertices(0, @primnum);
for(int i = 0; i < len(vertices); i++)
removevertex(0, vertices[i]);
// 再構成
// 始点
setpointattrib(0, "P", pts[0], start_pos);
addvertex(0, @primnum, pts[0]);
// 中間点
for(int i = 1; i < len(pts)-1; i++)
{
if(i <= start_idx || end_idx < i)
removepoint(0, pts[i]);
else
addvertex(0, @primnum, pts[i]);
}
// 終点
setpointattrib(0, "P", pts[-1], end_pos);
addvertex(0, @primnum, pts[-1]);