エッジの凹凸
ハーフエッジを使った凹凸判定
山折りのエッジのみをグループする

// Run Over: Points
// 事前にプリミティブに法線を設定している必要あり
//
// 接続しているポイントをリストする
int neighbours[] = neighbours(0, @ptnum);
foreach(int distPoint; neighbours)
{
// 重複を避ける
if(@ptnum > distPoint)
{
vector binormal = normalize(point(0, "P", distPoint) - @P);
int hedge = pointhedge(0, @ptnum, distPoint);
if(hedge != -1)
{
// 共有するハーフエッジを求める
int hcount = hedge_equivcount(0, hedge);
// 通常は2本
if(hcount == 2)
{
int nextHedge = hedge_nextequiv(0,hedge);
// エッジが属すプリミティブを求める
int prim0 = hedge_prim(0, hedge);
int prim1 = hedge_prim(0, nextHedge);
// プリミティブの法線
vector n0 = prim(0, "N", prim0);
vector n1 = prim(0, "N", prim1);
// 法線とエッジの外積から従法線を求める
vector cross = cross(n1, binormal);
// 内積
float dot = dot(n0, cross);
f@dot = degrees(acos(dot))+90;
if(dot < 0)
{
setedgegroup(0, "reflexAngle", @ptnum, distPoint, 1);
//printf(':' + sprintf('%g', @ptnum) + '\n');
}
}
}
}
}
角度で閾値を設けてグループする

下のコードは角度(30°)以下の山折りのエッジを選択している。
// Run Over: Points
// 事前にプリミティブに法線を設定している必要あり
//
float thresholdAngle = radians(30); // 制限角度
int neighbours[] = neighbours(0, @ptnum);
foreach(int distPoint; neighbours)
{
// 重複を避ける
if(@ptnum > distPoint)
{
vector binormal = normalize(point(0, "P", distPoint)-@P);
int hedge = pointhedge(0, @ptnum, distPoint);
if(hedge != -1)
{
// 共有するハーフエッジを求める
int hcount = hedge_equivcount(0, hedge);
// 通常は2本
if(hcount == 2)
{
int nextHedge = hedge_nextequiv(0,hedge);
// エッジが属すプリミティブを求める
int prim0 = hedge_prim(0, hedge);
int prim1 = hedge_prim(0, nextHedge);
// プリミティブの法線
vector n0 = prim(0, "N", prim0);
vector n1 = prim(0, "N", prim1);
// 法線とエッジの外積から従法線を求める
vector cross = cross(n1, binormal);
// 内積
float dot = dot(n0, cross);
float angle = acos(dot(n0, -n1));
// 角度の条件で選ぶ
if(dot < 0 && angle < thresholdAngle)
{
setedgegroup(0, "reflexAngle", @ptnum, distPoint, 1);
}
}
}
}
}
エッジの関数
neighbours() 指定したポイントとエッジを通じて隣り合うポイント(複数)を返す
pointhedge() 2つのポイントを指定してハーフエッジを取得する
hedge_equivcount() 共有するハーフエッジの数を取得する 隣接するプリミティブがなければ1が返る
hedge_nextequiv() エッジからもう片方のハーフエッジを取得する
hedge_prim() ハーフエッジが含まれるプリミティブを取得する
setedgegroup() ハーフエッジのグループを設定する
参考 https://www.sidefx.com/ja/docs/houdini/vex/halfedges.html