0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wrangleでメンガーのスポンジ

Posted at

image.png

以下は、Houdini上でWrangleを使ってメンガーのスポンジ(Menger Sponge)を生成する一例です。
この例では、DetailWrangleノード内で再帰的に各立方体の中心位置とサイズ(pscale)を計算し、後段のCopy to PointsノードでCube(Box)をインスタンスする方法を示します。

手順

  1. 新規ジオメトリノードを作成
    HoudiniのNetwork Viewで新しいジオメトリ(Geometry)ノードを作成し、中に入ります。

  2. Detail Wrangleノードの配置
    中に「Attribute Wrangle」ノードを作成し、Run Over を「Detail (only once)」に設定します。
    このWrangleで、再帰的なメンガーのスポンジの点群(各立方体の中心位置とサイズ)を生成します。

  3. パラメータの追加
    Wrangleノードのパラメータペインで、以下のパラメータを作成してください。

    • iterations (Integer):再帰回数(例:3~4程度)
    • size (Float):初期の立方体のサイド長(例:1.0)
  4. 以下のVEXコードをDetail Wrangleに貼り付け

    // パラメータ取得
    int iterations = chi("iterations");   // 再帰回数
    float init_size = chf("size");          // 初期立方体のサイド長
    vector start_pos = {0, 0, 0};           // 初期位置(原点)
    
    // 配列を用意:positions と scales
    vector positions[];   // 各立方体の中心位置
    float scales[];       // 各立方体のサイド長
    
    // 初期状態:1個の立方体(原点、サイズ = init_size)
    append(positions, start_pos);
    append(scales, init_size);
    
    // 各反復で、各立方体を3x3x3に分割し、メンガーのスポンジとして不要な部分を除去する
    for (int iter = 0; iter < iterations; iter++)
    {
        vector new_positions[];  // 次段での立方体中心位置
        float new_scales[];      // 次段での立方体サイズ
        int n = len(positions);
        for (int j = 0; j < n; j++)
        {
            vector pos = positions[j];
            // 子立方体のサイズは親のサイズの1/3
            float s = scales[j] / 3.0;
            // 3x3x3のグリッド(ix, iy, iz = 0,1,2)
            for (int ix = 0; ix < 3; ix++)
            {
                for (int iy = 0; iy < 3; iy++)
                {
                    for (int iz = 0; iz < 3; iz++)
                    {
                        // 3軸それぞれで、中央(値が1)の数をカウント
                        int cnt = 0;
                        if (ix == 1) cnt++;
                        if (iy == 1) cnt++;
                        if (iz == 1) cnt++;
                        // メンガーのスポンジのルール:中央および面中央は除去(カウントが2以上なら除外)
                        if (cnt < 2)
                        {
                            // 子立方体の中心位置は、親の中心から (ix-1, iy-1, iz-1) * s だけずらす
                            vector newpos = pos + set((ix - 1) * s, (iy - 1) * s, (iz - 1) * s);
                            append(new_positions, newpos);
                            append(new_scales, s);
                        }
                    }
                }
            }
        }
        // 次の反復用に更新
        positions = new_positions;
        scales = new_scales;
    }
    
    // 最終的に生成された各立方体の中心にポイントを作成し、"pscale" 属性にサイズを設定
    int npts = len(positions);
    for (int i = 0; i < npts; i++)
    {
        int pt = addpoint(0, positions[i]);
        // Copy to Pointsノードでインスタンスする際、pscale属性でサイズが決まる
        setpointattrib(0, "pscale", pt, scales[i], "set");
    }
    
  5. Copy to Pointsノードの配置

    • Detail Wrangleノードの出力に接続して、「Copy to Points」ノードを配置します。
    • 2番目の入力(右側)に、インスタンスとして用いるBox(Cube)ノードを接続してください。
      ※Boxのサイズは1単位としておき、pscale属性により各立方体のサイズが適用されます。
  6. 表示と調整

    • 作成したCopy to Pointsノードを表示すると、指定した反復回数に応じたメンガーのスポンジが得られます。
    • Wrangle内のiterationssizeの値を変えて、生成のレベルや大きさを調整してください。

以上の手順とコードで、SOPとWrangleを組み合わせたメンガーのスポンジの生成が可能です。
この基本手法をもとに、さらに色付けや変形、アニメーションなどを加えることで、より複雑な表現にも発展させることができます。

グラデーション例

// バウンディングボックスの最小/最大値を取得
vector bbmin, bbmax;
getbbox(0, bbmin, bbmax);

// ジオメトリ中心を算出
vector center = (bbmin + bbmax) * 0.5;

// バウンディングボックスの半径(中心から最も遠い距離のおおよその値)
float max_radius = length(bbmax - bbmin) * 0.5;

// 各ポイントの中心からの距離を計算
float d = length(@P - center);

// 0~max_radius を0~1に正規化
float t = fit(d, 0, max_radius, 0, 1);

// Rampパラメータ "color_ramp" に基づいてグラデーションカラーを設定
@Cd = relbbox(0, @P)*chramp("color_ramp", t);

メンガーのスポンジについては
すでに数年前に堀川さんがYoutubeにもあげられています
https://www.youtube.com/watch?v=-bass6YzWEA

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?