PolyReduce SOP

トライアングルあたりの面積でリダクションする

任意の面積を設定し、三角形あたりの平均面積を求めて、その割合でリダクションする。メッシュが複数あり、同じ密度でリダクションしたい場合に有効。

// Run Over: Detail

// 目標の1トライアングル当たりの面積(m^2)
float target = 100.0;

float sum = 0;
for(int i = 0; i < nprimitives(0); i++)
{
    int npts[] = primpoints(0, i);
    vector p0 = point(0, "P", npts[0]);
    vector p1 = point(0, "P", npts[1]);
    vector p2 = point(0, "P", npts[2]);
    
    vector cross = cross(p0 - p1, p2 - p1);
    float area = length(cross) / 2;
    sum += area;
}

f@__area = sum; // 合計面積
f@__aveArea = sum / nprimitives(0); // 平均面積

f@ratio = (sum / nprimitives(0)) / target * 100;

続けてつないだPolyReduce SOPのPercent to Keepに以下のExpressionを入力する。

detail(0, "ratio", 0)

見えない場所をリダクションする

ポイントを置き、そのポイントから遮蔽されている場所を0、そうでないところを1.0にする。

// Input0: Mesh
// Input1: Points
// Run Over: Points

float sight = 0;
for(int i = 0; i < npoints(1); i++)
{
    // 視点の座標
    vector origin = point(1, "P", i);
    
    // ターゲットは地形のポイント
    vector pos;
    vector uv;
    vector dir = @P - origin;
    intersect(0, origin, dir, pos, uv);
    
    // 遮蔽されていない条件(衝突点までの距離と実際の距離の差がほぼ0)
    if(length(@P - origin) - length(pos - origin) < 0.0001)
    {
        sight += 1;
    }
}

f@retention = clamp(sight, 0, 1);
//@Cd = sight;

結果にSmooth SOPをつないでぼかして、頂点カラーで視覚化したところ。

PolyReduce SOPにつなぎ、Retain Density by Attributeにアトリビュート名を入れて、Weightを10あたりにする。すると1.0に近い部分はリダクションが掛からず、0になる部分ほどリダクションがかかるようになる。

稜線を保持したい場合

編集中

タイトルとURLをコピーしました