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

// 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になる部分ほどリダクションがかかるようになる。

稜線を保持したい場合
編集中