環境:Houdini 20.0.751
元となるカーブを作成する
Rampカーブをつかってグラフを作ってみた。
カーブの確認
Rampカーブの値を取得できているかを確認するためにポリラインにしてみる。
//
// Ramp Curveをもとにポイントを並べる
//
float curveLength = primintrinsic(1, "measuredperimeter", 0); // 長さ
float depth = `chs("op:../controller/depth")`; // 幅
float width = `chs("op:../controller/divWidth")`; // 分割幅
int prim = addprim(0, "polyline");
int num = int(curveLength / width);
for(int i = 0; i < num; i++)
{
float L = chramp("op:../controller/ramp_curve", i/(float)(num-1)) * depth;
float z = curveLength / (float)(num - 1) * i; // z座標
vector pos = set(L, 0, z);
int pt = addpoint(0, pos);
addvertex(0, prim, pt);
}
ポイントの生成
メッシュを生成するためのポイントをポリラインごとに並べる。閾値を決めて最後のポイントが手前のポイントと差がない場合は手前のポイントを動かして最後のポイントとする。
//
// Ramp Curveをもとにポイントを並べる
//
float curveLength = primintrinsic(1, "measuredperimeter", 0);
float depth = `chs("../depth")`;
float width = `chs("../width")`;
//int num = npoints(1);
int num = int(curveLength / width);
num = npoints(1);
// 一定間隔ごとにポリラインを生成していく
for(int i = 0; i < num; i++)
{
int prim = addprim(0, "polyline");
float L = chramp("../ramp_curve", i/(float)(num-1)) * depth;
float z = curveLength / (float)(num - 1) * i; // z座標
int numPt = int(L / width) + 1; // 長さに対してのポイント数
float remainder = L % width; // 余り
// UV
vector uv;
uv.x = z / width;
vector pos = set(0, 0, z);
int pt = addpoint(0, pos);
addvertex(0, prim, pt);
uv.y = 0;
setpointattrib(0, "uv", pt, uv);
// ポリラインにポイントを追加していく
for(int j = 1; j < numPt; j++)
{
pos = set(width * j, 0, z);
pt = addpoint(0, pos);
addvertex(0, prim, pt);
uv.y = width * j / width;
setpointattrib(0, "uv", pt, uv);
}
// 最後のポイント
pos = set(L, 0, z);
uv.y = L / width;
// 直前のポイントとの差が少ない場合は直前のポイントを最後のポイントに移動させる
// ただしポイントが2つめ以降なのが条件
if(numPt > 1 && remainder / width < 0.1)
{
setpointattrib(0, "P", pt, pos);
setpointattrib(0, "uv", pt, uv);
}
// 新しくポイントを打つ
else
{
pt = addpoint(0, pos);
addvertex(0, prim, pt);
setpointattrib(0, "uv", pt, uv);
}
}
ポリゴンを描画する
となりのポリラインと比較して、並んでいるところまでは四角形を生成する。隣のポイント数が多い、または少ない場合は三角形を生成していく。
//
// ポリゴンの描画
// Run Over: Detail
//
for(int i = 0; i < nprimitives(0)-1; i++)
{
int pts[] = primpoints(0, i);
int npts[] = primpoints(0, i+1);
// となりのポリラインのポイント数が同じ場合
if(len(pts) == len(npts))
{
for(int j = 0; j < len(pts)-1; j++)
{
int prim = addprim(0, "poly");
addvertex(0, prim, pts[j]);
addvertex(0, prim, pts[j+1]);
addvertex(0, prim, npts[j+1]);
addvertex(0, prim, npts[j]);
}
}
// となりのポリラインのポイント数のほうが多い場合
else if(len(pts) < len(npts))
{
// 四角形
for(int j = 0; j < len(pts)-1; j++)
{
if(j < len(npts))
{
int prim = addprim(0, "poly");
addvertex(0, prim, pts[j]);
addvertex(0, prim, pts[j+1]);
addvertex(0, prim, npts[j+1]);
addvertex(0, prim, npts[j]);
}
}
// 三角形(でっぱり部分)
for(int j = 0; j < len(npts)-len(pts); j++)
{
int prim = addprim(0, "poly");
addvertex(0, prim, pts[-1]);
addvertex(0, prim, npts[len(pts)-1 + j + 1]);
addvertex(0, prim, npts[len(pts)-1 + j]);
}
}
// となりのポリラインのポイント数のほうが少ない場合
else if(len(pts) > len(npts))
{
// 四角形
for(int j = 0; j < len(npts)-1; j++)
{
if(j < len(pts))
{
int prim = addprim(0, "poly");
addvertex(0, prim, pts[j]);
addvertex(0, prim, pts[j+1]);
addvertex(0, prim, npts[j+1]);
addvertex(0, prim, npts[j]);
}
}
// 三角形(でっぱり部分)
for(int j = 0; j < len(pts)-len(npts); j++)
{
int prim = addprim(0, "poly");
addvertex(0, prim, pts[len(npts)-1 + j]);
addvertex(0, prim, pts[len(npts)-1 + j + 1]);
addvertex(0, prim, npts[-1]);
}
}
}
for(int i = 0; i < nprimitives(0); i++)
removeprim(0, i, 1);