2011年4月11日 星期一

MAX Script 教學-5




    這個教學覆蓋4個部分: 陣列(Arrays),錯誤檢查(Error Checking),訊息盒(Message Box),及使用者介面(User Interfaces).

前次的亂數旋轉有兩個錯誤.
  1. 如果沒選物件會出錯
  2. 沒法設定亂數範圍


陣列(Arrays)

    簡單的說, 一個陣列就是一列物件. Maxscript中幾乎每個物件都可以被指定為變數, 然後再存入陣列中.
    先建立一個空的陣列, 再給一個名稱, 先在Listener 輸入指令並執行...

ourFirstArray = #()


   ourFirstArray是陣列名稱, #是Maxscript中的陣列符號, ()括弧中是要放陣列內容, 在這裡是空的.現在要放一些東西到陣列中,會用到一個 append 函數來放東西到陣列中.

append ourFirstArray 1
append ourFirstArray 3


    之後再輸入

ourFirstArray


    得到 #(1,3), 裡面有兩個元件 1 及 3

    我們可以繼續增加陣列內容, 但要如何取得陣列的內容呢? 陣列中每一個元件的編號是以1遞增, 所以要取得ourFirstArray第二個元件, 可以輸入

ourFirstArray[2]


    得到之前存入的整數3

    陣列還有一個常用的特性(property),名稱叫 .count ,在MaxScript Listener 中輸入

ourFirstArray.count


    得到2, 表示陣列長度.



錯誤檢查(Error Checking)

    打開之前所寫的程式,

MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
  for obj in $ do ( -- 對所選物執行迴圈...
    randXrot = random -3.0 3.0 -- 建立X軸旋轉亂數範圍
    randYrot = random -3.0 3.0 -- 建立Y軸旋轉亂數範圍
    randZrot = random -3.0 3.0 -- 建立Z軸旋轉亂數範圍
    rotObj = eulerangles randXrot randYrot randZrot -- 建立尤拉旋轉物件
    rotate obj rotObj -- 應用到當前執行物件
  )
)

    現在已經知道用$可以存取當前所選物件, 另一個方法是存取 "selection", 這是一個MAX內建陣列. 選取場景中多個物件後, 輸入

selection.count


    得到現在所選物件的數量.

    再輸入...

selection[1]


    得到所選的第一個物件資料, 現在不選任何場景物件, 輸入

selection.count

    得到 0 , 表示沒有選取任何物件. 所以知道可以增加一小段script來測試是否有選到物件.

MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
  if (selection.count > 0) then ( -- 如果所選物大於0,則執行以下...
    for obj in $ do (
      randXrot = random -3.0 3.0
      randYrot = random -3.0 3.0
      randZrot = random -3.0 3.0
      rotObj = eulerangles randXrot randYrot randZrot
      rotate obj rotObj
    )
  )
)

   加上if判斷式後, 就可以避免沒有選取物時執行程式,而出現錯誤.
   若再加上一個警告訊息提醒出錯會更好.


訊息盒(Message Box)

    這裡會用到 else 語法. 若沒選任何物件, 就執行else的內容, 跳出警告訊息盒.

MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
   for obj in $ do -- Loop over currently selected objects (
    if (selection.count > 0) then (
      randXrot = random -3.0 3.0
      randYrot = random -3.0 3.0
      randZrot = random -3.0 3.0
      rot_obj = eulerangles randXrot randYrot randZrot
      rotate obj rot_obj
    ) else (
      messagebox "You must have at least one object selected!" -- 警告訊息盒
    )
  )
)

    加入if/then 及 else 語法及內容後, 我們解決了第一個問題.



使用者介面(User Interfaces)

    為了解決第二個問題,必須建立一個介面,讓使用者輸入旋轉的亂數範圍.

    執行 Maxscript > visual Maxscript editor
    開啟Visual Maxscript Editor, 它可以很簡單的建立介面.






     設計好介面後, 存成.vms(Visual Maxscript Editor)格式, 再另存成.ms, 可用來修改程式碼.

     用Maxscript Editor開啟之前的.ms 檔, 裡面已經有一些關於介面的程式碼,如下.

rollout RandomRotateRollout "Random Rotate" width:162 height:122
(
groupBox grp1 "Random Rotation Range" pos:[10,12] width:142 height:99
button btn1 "Randomly Rotate!" pos:[19,81] width:125 height:22
spinner spn1 "Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]
spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]
)

再做進一步修改, 將主程式放進 on btn1 pressed do 括號裡面,

rollout RandomRotateRollout "Random Rotate" width:162 height:122 (
  groupBox grp1 "Random Rotation Range" pos:[10,12] width:142 height:99
    button btn1 "Randomly Rotate!" pos:[19,81] width:125 height:22
    spinner spn1 "Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]
    spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]


 on btn1 pressed do (-- 當btn1被按...
  if (selection.count > 0) then ( -- 選取物件數量大於0,才執行...
    for obj in $ do (-- 對所選物執行迴圈...
      randXrot = random -3.0 3.0 -- 建立X軸旋轉亂數範圍
      randYrot = random -3.0 3.0 -- 建立Y軸旋轉亂數範圍
      randZrot = random -3.0 3.0 -- 建立Z軸旋轉亂數範圍
      rot_obj = eulerangles randXrot randYrot randZrot -- 建立尤拉旋轉物件
      rotate obj rot_obj -- 應用到當前執行物件
    ) else (
      messagebox "You must have at least one object selected!"
    )
  )
 )
)

    接下來要做一些處理, 用spn1.value 與 spn2.value 取代 -3.0 及 3.0 , 以後最小最大值就由spn1與spn2的輸入值決定.

    執行Script時, 發現沒顯示出程式介面, 所以必須加上一行程式, 包裝成一個正式的MacroScript 程式.

createDialog RandomRotateRollout 162 120 -- 寬162, 高120


最後版本如下


MacroScript Random_Rotate category:"Rhys Tools" buttonText:"Random Rotate" tooltip:"Random Rotate" (
  rollout RandomRotateRollout "Random Rotate" width:162 height:122 (
    groupBox grp1 "Random Rotation Range" pos:[10,12] width:142 height:99
    button btn1 "Randomly Rotate!" pos:[19,81] width:125 height:22
    spinner spn1 "Minimum value " pos:[22,34] width:122 height:16 range:[-360.0,360.0,0.0]
    spinner spn2 "Maximum value" pos:[23,56] width:122 height:16 range:[-360.0,360.0,0.0]


    on btn1 pressed do ( -- when btn1 is pressed do...
      for obj in $ do ( -- Loop over currently selected objects
       if (selection.count > 0) then (
        randXrot = random spn1.value spn2.value
        randYrot = random spn1.value spn2.value
        randZrot = random spn1.value spn2.value
        rot_obj = eulerangles randXrot randYrot randZrot
        rotate obj rot_obj
       else (
        messagebox "You must have at least one object selected!"
       )
    )
  )
 )
  createDialog RandomRotateRollout 162 120
)


執行後,開啟自訂介面, 將Script以自己喜好方式呈現.




結果如圖所示




MAX Script 教學-4

4 則留言:

  1. http://vimeo.com/42498838

    請問類似這樣要如何寫
    將一個物件貼到另一物件上
    並且要復製
    或是
    線拉升後,分開

    謝謝

    回覆刪除
  2. 這個問題有難度,過去沒寫過類似的,目前不知如何回答,有空會去研究研究...謝謝您的提問,雖然幫不了什麼忙...

    回覆刪除
  3. http://www.softimageblog.com/archives/33

    回覆刪除
    回覆
    1. http://www.3dtotal.com/index_tutorial_detailed.php?id=1138#.UOVleXd93To

      刪除

LinkWithin

Related Posts Plugin for WordPress, Blogger...