ハーフエッジを使った凹凸判定
山折りのエッジのみをグループする
// 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