[3ds Max]スムージンググループをスクリプトから設定する方法。Set Smoothing group by MaxScript


はじめに

3dsmaxのmaxscriptでポリゴンなどのスムージンググループを設定する際に、polyop.setFaceSmoothGroupを使用すると思います。
そのメソッドを使用すると思った通りの動作にならず戸惑う方がいそうなので今回記事にしました。

setFaceSmoothGroup について

このメソッドは第一引数に対象のポリゴンオブジェクト、第二引数に対象のフェイスIDそして、第三にスムージンググループの整数を入れるよう指定されています。
以下 ヘルプの引用


polyop.setFaceSmoothGroup <Poly poly> <facelist> <int smoothing_group> add:<boolean=false>
指定された面のスムージング グループを設定します。

<smoothing_group> の各ビットの状態は、対応するスムージング グループにその面が属しているかどうかを示します。

<add> が true の場合、<smoothing_group> は各面に指定された既存のスムージング グループ データに追加されます。

<add> が false の場合、既存のスムージング グループ データが上書きされます。

この第三引数が曲者。
単純にオンにしたいスムージンググループの数字を打つのではなく。
32桁の2進数で、1がONで0がOFFだとして、10進数の数字を入れないと正常に動作しないという、難解仕様。

なので、第三引数に1を入れるとスムージンググループは1。
2を入れると「2」、
3を入れると「1と2」、
4を入れると「3」。

っという風になるわけです。

10進数 2進数 smoothing group
1 1 1
2 10 2
3 11 1,2
4 100 3

対処法

これじゃあわかりにくいので、bitarrayから整数に変換するスクリプトを用意しました。
(整数からbitarrayに変換する関数も入ってます)
以下スクリプトです。

ConvertBitarrayFrom32Int.ms

fn ConvertBitarrayFrom32Int num  =
(
    local sgroup_val= num
    local sg_bitarray=#{}
    if sgroup_val < 0 do
    (
    sg_bitarray[32]=true
    sgroup_val -= 2^31
    )
    for i = 1 to 31 do
    (
    sg_bitarray[i]= (mod sgroup_val 2 > .5)
    sgroup_val /= 2
    )
    sg_bitarray
)
fn ConvertIntFromBitarray bitary = 
(
    result  = 0 
    for i = 1 to 32 do
    (
        if bitary[i] then 
        (
            result +=  2 ^ (i  - 1)
        )
    )
    return result 
)

format "-----------------------\n%\n" (ConvertBitarrayFrom32Int 5)
format "-----------------------\n%\n" (ConvertIntFromBitarray #{1,3,6,8})

こちらを使用して、以下のように記述すると、少しはわかりやすいかも。

polyop.setFaceSmoothGroup  $Box001 1 (ConvertIntFromBitarray #{1,3,6})

ちなみに、スムージンググループ以外にも、この形式で指定するメソッドがちらほらmaxの内部にあります。
それは引数で、とか<32bit int>とかそんな感じで表記されているので、その場合は、この2進数を10進数に変えて指定する方法を疑ってもいいかもしれません。
是非、ご参考までに。