マテリアル ID によってマルチマテリアルをソートする方法はありますか。
 
 
 

MAXScript に関する質問と回答 > オブジェクトのプロパティへのアクセス > マテリアル ID によってマルチマテリアルをソートする方法はありますか。

3ds Max 4 以降、マルチマテリアル内のマテリアル ID をサブマテリアルの順序とは無関係に指定できます。サブマテリアルを追加する長いプロセスを経ると、マテリアル ID が入り乱れていることがあります。特に他人にシーンを引き渡す場合、マテリアル ID でソートすることによってサブマテリアルを昇順に並べ替えることをお勧めします。

次の関数では、MAXScript によって提供されている sort または qsort といった組み込み関数を使用せずに、単純なバブル ソート アルゴリズムによってこの操作を実行します。

バブル ソート アルゴリズムとは、2 つの値を比較してその順序が正しくなければ場所を入れ替える方法です。変更が必要なくなるまでこのプロセスが繰り返されます。このメソッドの名前は、低い値は「表面」に浮かび上がってきて、高い値が「底へ」沈んでいく事象に基づいています。

この関数はフラグ変数を設定し、このフラグが true に設定されるまで while ループが繰り返されます。2 つのマテリアルの場所が入れ替えられたら、必ずフラグは false に設定され、ソートがまだ終了していないことを示します。while ループ内では、for ループがサブマテリアル全体を調べて、隣接するマテリアル ID 値同士を比較します。現在値が次の値より大きければ、ID、各サブマテリアル、名前、および使用可能スイッチの場所を変更する必要があります。

スクリプト:

fn sortMultiSubByIdm =
(
if classof m == MultiMaterial then--マテリアルがマルチマテリアルであることを確認します。
(
 local sorted = false--ローカル変数をソート ステータス フラグとして初期化します。
 while not sorted do--フラグが true に設定されるまで繰り返します。
 (
  sorted = true--最初のループで、最後を除くすべてのサブマテリアルに
  -- フラグを true に設定します。
  for i = 1 to m.numsubs-1 do
  (
   -- 現在のサブマテリアルの MatID が次のものより大きい場合...
   if m.materialIDList[i] != undefined and m.materialIDList[i+1] and m.materialIDList[i] > m.materialIDList[i+1] do
   (
    -- 現在のマテリアルを temp 変数に格納します。
    tmp = m.materialList [i]
    -- 次のマテリアルを現在のマテリアルにコピーします。
    m.materialList [i] = m.materialList[i+1]
    -- temp 変数を使用して、現在のマテリアルを次のマテリアルにコピーします。
    m.materialList[i+1] = tmp
    -- マテリアル ID についても同じことを実行します。
    tmp = m.materialIDList[i]
    m.materialIDList[i] = m.materialIDList[i+1]
    m.materialIDList[i+1] = tmp
    -- 次に、使用可能チェックボックスの状態をコピーします。
    tmp = m.mapEnabled[i]
    m.mapEnabled[i] = m.mapEnabled[i+1]
    m.mapEnabled[i+1] = tmp
    -- 最後に、ユーザ定義の名前の場所を入れ替えます。
    tmp = m.names[i]
    m.names[i] = m.names[i+1]
    m.names[i+1] = tmp 
    -- 場所の入れ替えを行ったのでフラグを false に設定します。 ゆえに続行されます。
    sorted = false
   )--if 終了
  )--for 終了
sortMultiSubById $Box01.material
 )--while 終了
)--if 終了
)--fn終了
 
サンプルの使用方法:
関連事項