カスタムPolyframe

XZ平面を基準としたポリラインに対して、進行ベクトルNとアップベクトルupを設定する。

Nが青、upが緑

ループしている場合の始点と終点

始点と終点が重なっている場合

16角形の円をつくる。インデックスは0~16で、0と16が同じ位置にある。

始点のインデックスは0で、終点は16。

int pts[] = primpoints(0, @primnum);

printf('pts[-1]:' + sprintf('%g', pts[-1]) + '\n');
printf('pts[-2]:' + sprintf('%g', pts[-2]) + '\n');

終点のインデックスは16でその一つ前は15になる。

始点と終点が結合している場合

Fuse SOPで始点と終点を結合すると、始点も終点もインデックスは0になる。

終点のインデックスは0でその一つ前は15になる。

First Edge

ポイントから次のポイントへのベクトルをNとする。upベクトルはNに直交させる。

//
// Custom Polyframe First Edge
// Run Over: Primitive
// 
int pts[] = primpoints(0, @primnum);

vector start = point(0, "P", pts[0]);
vector end = point(0, "P", pts[-1]);

// ループフラグ
int isClosed = 0;
if(length(start - end) < 0.00001)
    isClosed = 1;
    
for(int i = 0; i < len(pts); i++)
{
    vector p0 = point(0, "P", pts[i]);
    vector p1 = point(0, "P", pts[(i+1)%len(pts)]);
    vector n = normalize(p1 - p0);
    
    if(isClosed)
    {
        if(i == 0 || i == len(pts)-1)
        {
            // Two Edges
            p0 = point(0, "P", pts[-2]);
            p1 = point(0, "P", pts[0]);
            vector p2 = point(0, "P", pts[1]);
            n = normalize((p2 - p1) + (p1 - p0));
        }
    }
    else
    {
        if(i == len(pts)-1)
        {
            p0 = point(0, "P", pts[i-1]);
            p1 = point(0, "P", pts[i]);
            n = normalize(p1 - p0);
        }
    }
    
    // 始点または終点
    if(i == 0 || i == len(pts)-1)
    {
        if(isClosed)
        {
            // Two Edges
            p0 = point(0, "P", pts[-2]);
            p1 = point(0, "P", pts[0]);
            vector p2 = point(0, "P", pts[1]);
            n = normalize((p2 - p1) + (p1 - p0));
        }
    }
    
    vector up = set(0, 1, 0);
    vector left = cross(up, n);
    up = cross(n, left);
    
    setpointattrib(0, "N", pts[i], n);
    setpointattrib(0, "up", pts[i], up);
}

Two Edges

ポイントの乗っている2つのエッジの和をNとする。

始点と終点がFuseされている場合はインデックス[-1]のポイントは0になる。始点はインデックス[-2]のポイントを前のポイントとする必要がある。

//
// Custom Polyframe Two Edges
// Run Over: Primitive
// 
int pts[] = primpoints(0, @primnum);

vector start = point(0, "P", pts[0]);
vector end = point(0, "P", pts[-1]);

// ループフラグ
int isClosed = 0;
if(length(start - end) < 0.00001)
    isClosed = 1;
    
for(int i = 0; i < len(pts); i++)
{
    vector p0 = point(0, "P", pts[i-1]);
    vector p1 = point(0, "P", pts[i]);
    vector p2 = point(0, "P", pts[(i+1)%len(pts)]);
    
    // 始点または終点
    if(i == 0 || i == len(pts)-1)
    {
        if(isClosed)
        {
            // Two Edges
            p0 = point(0, "P", pts[-2]);
            p1 = point(0, "P", pts[0]);
            p2 = point(0, "P", pts[1]);
        }
    }
    
    vector n = normalize((p2 - p1) + (p1 - p0));
    vector up = set(0, 1, 0);
    vector left = cross(up, n);
    up = cross(n, left);
    
    setpointattrib(0, "N", pts[i], n);
    setpointattrib(0, "up", pts[i], up);
}
タイトルとURLをコピーしました