カーブに沿ったグリッドメッシュの生成

環境: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をもとにポイントを並べる
// Run Over: Detail
//

float curveLength = primintrinsic(1, "measuredperimeter", 0); // 長さ
float depth = `chs("../controller/depth")`; // 幅
float width = `chs("../controller/divWidth")`; // 分割幅

int num = int(curveLength / width);

for(int i = 0; i < num; i++)
{
    int prim = addprim(0, "polyline");

    float L = chramp("op:../controller/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;
    // 直前のポイントとの差が少ない場合は直前のポイントを最後のポイントに移動させる
    if(remainder / width > 0.1)
    {
        pt = addpoint(0, pos);
        addvertex(0, prim, pt);
        setpointattrib(0, "uv", pt, uv);
    }
    // 新しくポイントを打つ
    else
    {
        setpointattrib(0, "P", pt, pos);
        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);
タイトルとURLをコピーしました