Home Technical Talk

[MAXScript] Custom Transform Type-in

interpolator
Offline / Send Message
Revel interpolator
Hey guys, me for one like to customize my UI to fit my need and as 'minimal' as possible. For instance, there is no necessary tools on Max's status panel that I really need to be on the whole time except the transform type-in. Yes I can use shortcut F12 to bring up the floater dialog, but honestly it looks ugly to have many floating thing above my viewport.

I have no experience in MAXScript before so what I did was just chop people code here and there and try to combine them together and make my own version of TTI, dockable version. Searched around the internet and seems like there is none that actually finished, the closest clue that I can get was this but sadly it's not updated anymore, so I decided to mod it and this is what I've got so far;
  1. rollout TFB "Transform Box" width:870 height:30
  2. (
  3. label Movelabel "Move" pos:[0,5] width:32
  4. spinner spn1 "X" range: [-1e+008,1e+007,0] pos:[40,5] width:70
  5. spinner spn2 "Y" range: [-1e+008,1e+007,0] pos:[120,5] width:70
  6. spinner spn3 "Z" range: [-1e+008,1e+007,0] pos:[200,5] width:70
  7. label Rotlabel "Rotate" pos:[285,5] width:32
  8. spinner spn4 "X" range: [-1e+008,1e+007,0] pos:[330,5] width:70
  9. spinner spn5 "Y" range: [-1e+008,1e+007,0] pos:[410,5] width:70
  10. spinner spn6 "Z" range: [-1e+008,1e+007,0] pos:[490,5] width:70
  11. label Scalelabel "Scale" pos:[575,5] width:32
  12. spinner spn7 "X" range: [-1e+008,1e+007,0] pos:[620,5] width:70 scale:0.01
  13. spinner spn8 "Y" range: [-1e+008,1e+007,0] pos:[700,5] width:70 scale:0.01
  14. spinner spn9 "Z" range: [-1e+008,1e+007,0] pos:[780,5] width:70 scale:0.01
  15. fn redefineTransformHandlers selection =
  16. (
  17. deleteAllChangeHandlers id:#typeInTransform
  18. if selection.count == 0 do return()
  19. if selection.count == 1 do
  20. (
  21. spn1.value = $.pos.x
  22. spn2.value = $.pos.y
  23. spn3.value = $.pos.z
  24. spn4.value = $.rotation.x
  25. spn5.value = $.rotation.y
  26. spn6.value = $.rotation.z
  27. when transform $ changes id:#typeInTransform handleAt:#redrawViews do
  28. (
  29. spn1.value = $.pos.x
  30. spn2.value = $.pos.y
  31. spn3.value = $.pos.z
  32. spn4.value = $.rotation.x
  33. spn5.value = $.rotation.y
  34. spn6.value = $.rotation.z
  35. )
  36. )
  37. )
  38. on spn1 changed val do if selection.count == 1 do selection[1].pos.x = val
  39. on spn2 changed val do if selection.count == 1 do selection[1].pos.y = val
  40. on spn3 changed val do if selection.count == 1 do selection[1].pos.z = val
  41. on spn4 changed val do if selection.count == 1 do selection[1].rotation.x = val
  42. on spn5 changed val do if selection.count == 1 do selection[1].rotation.y = val
  43. on spn6 changed val do if selection.count == 1 do selection[1].rotation.z = val
  44. on TFB open do
  45. (
  46. callbacks.removescripts id:#typeInTransform
  47. callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform
  48. )
  49. on TFB close do
  50. (
  51. callbacks.removescripts id:#typeInTransform
  52. )
  53. )
  54.  
  55. createdialog TFB
  56. cui.RegisterDialogBar TFB
  57. cui.DockDialogBar TFB #cui_dock_bottom
The move is working fine, it even update the number when I select/ reselect/ select another object without any issue. But when continue on the rotation it's just stuck for some reason And apparently it limited the rotation on the spinner to be 1 to -1, instead of the full 360deg... Does anyone know what's the problem with the code I used on these? I'm guessing the $.rotation.x/ y/ z is just wrong to use on that context (since it appear to be not in 'degree' value), but I can't find any alternative for accessing rotation through MAXScript.

Anyone, help?

Replies

  • haiddasalami
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Use the rotation controller value to feed the spinner. Also just made the values go back to 0 if you have nothing selected.
    1. rollout TFB "Transform Box" width:870 height:30
    2. (
    3. label Movelabel "Move" pos:[0,5] width:32
    4. spinner spn1 "X" range: [-1e+008,1e+007,0] pos:[40,5] width:70
    5. spinner spn2 "Y" range: [-1e+008,1e+007,0] pos:[120,5] width:70
    6. spinner spn3 "Z" range: [-1e+008,1e+007,0] pos:[200,5] width:70
    7. label Rotlabel "Rotate" pos:[285,5] width:32
    8. spinner spn4 "X" range: [-1e+008,1e+007,0] pos:[330,5] width:70
    9. spinner spn5 "Y" range: [-1e+008,1e+007,0] pos:[410,5] width:70
    10. spinner spn6 "Z" range: [-1e+008,1e+007,0] pos:[490,5] width:70
    11. label Scalelabel "Scale" pos:[575,5] width:32
    12. spinner spn7 "X" range: [-1e+008,1e+007,0] pos:[620,5] width:70 scale:0.01
    13. spinner spn8 "Y" range: [-1e+008,1e+007,0] pos:[700,5] width:70 scale:0.01
    14. spinner spn9 "Z" range: [-1e+008,1e+007,0] pos:[780,5] width:70 scale:0.01
    15. fn redefineTransformHandlers selection =
    16. (
    17. deleteAllChangeHandlers id:#typeInTransform
    18. if selection.count == 0 do
    19. (
    20. spn1.value = 0
    21. spn2.value = 0
    22. spn3.value = 0
    23. spn4.value = 0
    24. spn5.value = 0
    25. spn6.value = 0
    26. )
    27. if selection.count == 1 do
    28. (
    29. spn1.value = $.pos.x
    30. spn2.value = $.pos.y
    31. spn3.value = $.pos.z
    32. spn4.value = $.rotation.controller[1].value
    33. spn5.value = $.rotation.controller[2].value
    34. spn6.value = $.rotation.controller[3].value
    35. when transform $ changes id:#typeInTransform handleAt:#redrawViews do
    36. (
    37. spn1.value = $.pos.x
    38. spn2.value = $.pos.y
    39. spn3.value = $.pos.z
    40. spn4.value = $.rotation.controller[1].value
    41. spn5.value = $.rotation.controller[2].value
    42. spn6.value = $.rotation.controller[3].value
    43. )
    44. )
    45. )
    46. on spn1 changed val do if selection.count == 1 do selection[1].pos.x = val
    47. on spn2 changed val do if selection.count == 1 do selection[1].pos.y = val
    48. on spn3 changed val do if selection.count == 1 do selection[1].pos.z = val
    49. on spn4 changed val do if selection.count == 1 do selection[1].rotation.controller[1].value = val
    50. on spn5 changed val do if selection.count == 1 do selection[1].rotation.controller[2].value = val
    51. on spn6 changed val do if selection.count == 1 do selection[1].rotation.controller[3].value = val
    52. on TFB open do
    53. (
    54. callbacks.removescripts id:#typeInTransform
    55. callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform
    56. )
    57. on TFB close do
    58. (
    59. callbacks.removescripts id:#typeInTransform
    60. )
    61. )
    62.  
    63. createdialog TFB
  • Revel
    Offline / Send Message
    Revel interpolator
    Hey man! that works great!! Couldn't figure that out by myself, thanks!

    What about scale then? :3
    It appears that the display value on the spinner: 1, 2, 3 corresponded into 100%, 200%, 300% value on the standard tti box..hmmmm..
  • haiddasalami
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Edit:Whoops :P
    1. rollout TFB "Transform Box" width:870 height:30
    2. (
    3. label Movelabel "Move" pos:[0,5] width:32
    4. spinner spn1 "X" range: [-1e+008,1e+007,0] pos:[40,5] width:70
    5. spinner spn2 "Y" range: [-1e+008,1e+007,0] pos:[120,5] width:70
    6. spinner spn3 "Z" range: [-1e+008,1e+007,0] pos:[200,5] width:70
    7. label Rotlabel "Rotate" pos:[285,5] width:32
    8. spinner spn4 "X" range: [-1e+008,1e+007,0] pos:[330,5] width:70
    9. spinner spn5 "Y" range: [-1e+008,1e+007,0] pos:[410,5] width:70
    10. spinner spn6 "Z" range: [-1e+008,1e+007,0] pos:[490,5] width:70
    11. label Scalelabel "Scale" pos:[575,5] width:32
    12. spinner spn7 "X" range: [-1e+008,1e+007,0] pos:[620,5] width:70 scale:1.0
    13. spinner spn8 "Y" range: [-1e+008,1e+007,0] pos:[700,5] width:70 scale:1.0
    14. spinner spn9 "Z" range: [-1e+008,1e+007,0] pos:[780,5] width:70 scale:1.0
    15. fn redefineTransformHandlers selection =
    16. (
    17. deleteAllChangeHandlers id:#typeInTransform
    18. if selection.count == 0 do
    19. (
    20. spn1.value = 0
    21. spn2.value = 0
    22. spn3.value = 0
    23. spn4.value = 0
    24. spn5.value = 0
    25. spn6.value = 0
    26.  
    27. spn7.value = 0
    28. spn8.value = 0
    29. spn9.value = 0
    30. )
    31. if selection.count == 1 do
    32. (
    33. spn1.value = $.pos.x
    34. spn2.value = $.pos.y
    35. spn3.value = $.pos.z
    36. spn4.value = $.rotation.controller[1].value
    37. spn5.value = $.rotation.controller[2].value
    38. spn6.value = $.rotation.controller[3].value
    39.  
    40. spn7.value = ($.scale.x * 100)
    41. spn8.value = ($.scale.y * 100)
    42. spn9.value = ($.scale.z * 100)
    43. when transform $ changes id:#typeInTransform handleAt:#redrawViews do
    44. (
    45. spn1.value = $.pos.x
    46. spn2.value = $.pos.y
    47. spn3.value = $.pos.z
    48. spn4.value = $.rotation.controller[1].value
    49. spn5.value = $.rotation.controller[2].value
    50. spn6.value = $.rotation.controller[3].value
    51.  
    52. spn7.value = ($.scale.x * 100)
    53. spn8.value = ($.scale.y * 100)
    54. spn9.value = ($.scale.z * 100)
    55. )
    56. )
    57. )
    58. on spn1 changed val do if selection.count == 1 do selection[1].pos.x = val
    59. on spn2 changed val do if selection.count == 1 do selection[1].pos.y = val
    60. on spn3 changed val do if selection.count == 1 do selection[1].pos.z = val
    61. on spn4 changed val do if selection.count == 1 do selection[1].rotation.controller[1].value = val
    62. on spn5 changed val do if selection.count == 1 do selection[1].rotation.controller[2].value = val
    63. on spn6 changed val do if selection.count == 1 do selection[1].rotation.controller[3].value = val
    64. on spn7 changed val do if selection.count == 1 do selection[1].scale.x = (val/100)
    65. on spn8 changed val do if selection.count == 1 do selection[1].scale.y = (val/100)
    66. on spn9 changed val do if selection.count == 1 do selection[1].scale.z = (val/100)
    67. on TFB open do
    68. (
    69. callbacks.removescripts id:#typeInTransform
    70. callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform
    71. )
    72. on TFB close do
    73. (
    74. callbacks.removescripts id:#typeInTransform
    75. )
    76. )
    77.  
    78. createdialog TFB

    This should work. Think my max just bugged out :/
  • Revel
    Offline / Send Message
    Revel interpolator
    Alright! thanks so much haiddasalami! Now all 3 works as expected :D
  • Revel
    Offline / Send Message
    Revel interpolator
    Hmm after a while using it, there is some situation where max throw an error though, it's when an object with the transformation locked; something like target camera/ target light where it's rotation is locked..is there any way to exclude the name pattern with "target" at the beginning of it's class name in the maxscript? I thought using pattern matching like RegEx would work but I tried classOf $ == target*, classOf $ == target\w+ wont work either...
  • haiddasalami
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Look up matchPattern. Example:

    matchPattern "ASD BSD" pattern:"ASD*"
  • Revel
    Offline / Send Message
    Revel interpolator
    You sir, is amazing! it works! haha..
    Actually there is so much more that I wanted to improve on this, one of them would be effecting the subobject selection, but probably that's for another time :)
  • Revel
    Offline / Send Message
    Revel interpolator
    EDIT:
    Whoops sorry about that,found out the problem is #uscale stands for uniform scale and when I want to scale it non uniformly just add the #nuscale and it all works as expected :)



    Hello guys I'm updating my Transform Box script but have a quick question;
    1. when transform $ changes id:#typeInTransform handleAt:#redrawViews do
    2. (
    3. case (toolmode.commandmode) of
    4. (
    5. #move: print "temp mv"
    6. #rotate: print "temp rt"
    7. #uscale: print "temp sc"
    8. )
    9. )
    ..is there any particular reason why the above code didn't work for #uscale? when I mode my object it'll print "temp mv" or when rotate it'll print "temp rt" on the listener as expected, but when I scale the object, it didn't do anything..huh?
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    This works for me, except that when in Uniform Scale the script prints non uniform
    1. when transform $ changes id:#typeInTransform handleAt:#redrawViews do
    2. (
    3. case (toolmode.commandmode) of
    4. (
    5. #move: (print "temp mv")
    6. #rotate: (print "temp rt")
    7. #uscale: (print "uniform scale")
    8. #squash: (print "squash")
    9. #nuscale: (print "non uniform scale")
    10. )
    11. )
  • Revel
    Offline / Send Message
    Revel interpolator
    Hello miauu, yeah thanks and i did play around with it quite a while and it seems that Max will auto-detect which scale we are using so when scale using the center gizmo it'll detect #uscale, but if scale just by dragging one of the handle (even though we still on uniform scale) it'll detect the action as #nuscale :)

    Here is what I've got so far;
    1. rollout TFB "Transform Box" width:310 height:28
    2. (
    3. local isSpinner = false
    4. local firstUndo = false
    5. local spnID, spnVal, spnAxis, spnTFArray
    6. label xformLabel "XForm" pos:[5,5] width:40
    7. spinner spn1 "X:" range: [-1e+008,1e+007,0] pos:[55,5] width:70
    8. spinner spn2 "Y:" range: [-1e+008,1e+007,0] pos:[140,5] width:70
    9. spinner spn3 "Z:" range: [-1e+008,1e+007,0] pos:[225,5] width:70
    10. fn redefineTransformHandlers selection =
    11. (
    12. deleteAllChangeHandlers id:#typeInTransform
    13. if selection.count == 1 then
    14. (
    15. try
    16. (
    17. case (toolmode.commandmode) of
    18. (
    19. #move:
    20. (
    21. spn1.value = $.pos.x
    22. spn2.value = $.pos.y
    23. spn3.value = $.pos.z
    24. )
    25. #rotate:
    26. (
    27. spn1.value = $.rotation.controller[1].value
    28. spn2.value = $.rotation.controller[2].value
    29. spn3.value = $.rotation.controller[3].value
    30. )
    31. #uscale:
    32. (
    33. spn1.value = ($.scale.x *100)
    34. spn2.value = ($.scale.y *100)
    35. spn3.value = ($.scale.z *100)
    36. )
    37. )
    38. ) catch()
    39. when transform $ changes id:#typeInTransform handleAt:#redrawViews do
    40. (
    41. case (toolmode.commandmode) of
    42. (
    43. #move:
    44. (
    45. spn1.value = $.pos.x
    46. spn2.value = $.pos.y
    47. spn3.value = $.pos.z
    48. )
    49. #rotate:
    50. (
    51. spn1.value = $.rotation.controller[1].value
    52. spn2.value = $.rotation.controller[2].value
    53. spn3.value = $.rotation.controller[3].value
    54. )
    55. #uscale:
    56. (
    57. spn1.value = ($.scale.x *100)
    58. spn2.value = ($.scale.y *100)
    59. spn3.value = ($.scale.z *100)
    60. )
    61. #nuscale:
    62. (
    63. spn1.value = ($.scale.x *100)
    64. spn2.value = ($.scale.y *100)
    65. spn3.value = ($.scale.z *100)
    66. )
    67. )
    68. )
    69. )
    70. else
    71. (
    72. spn1.indeterminate = true
    73. spn2.indeterminate = true
    74. spn3.indeterminate = true
    75. )
    76. )
    77. fn spnChanged spnID spnVal =
    78. (
    79. if selection.count == 1 then
    80. (
    81. local useUndo = (isSpinner and firstUndo) or (not isSpinner)
    82. undo "changed" useUndo
    83. (
    84. case (toolmode.commandmode) of
    85. (
    86. #move:case spnID of
    87. (
    88. spn1: selection[1].pos.x = spnVal
    89. spn2: selection[1].pos.y = spnVal
    90. spn3: selection[1].pos.z = spnVal
    91. )
    92. #rotate: case spnID of
    93. (
    94. spn1: selection[1].rotation.controller[1].value = spnVal
    95. spn2: selection[1].rotation.controller[2].value = spnVal
    96. spn3: selection[1].rotation.controller[3].value = spnVal
    97. )
    98. #uscale: case spnID of
    99. (
    100. spn1: selection[1].scale.x = (spnVal/100)
    101. spn2: selection[1].scale.y = (spnVal/100)
    102. spn3: selection[1].scale.z = (spnVal/100)
    103. )
    104. #select: spnID.indeterminate = true
    105. )
    106. )
    107. firstUndo = false
    108. completeRedraw()
    109. )
    110. else spnID.indeterminate = true
    111. )
    112. fn spnBtnDown spnID =
    113. (
    114. if selection.count == 1 then
    115. (
    116. isSpinner = true
    117. firstUndo = true
    118. )
    119. else spnID.indeterminate = true
    120. )
    121. fn spnBtnUp spnID=
    122. (
    123. if selection.count == 1 then
    124. (
    125. isSpinner = false
    126. if toolmode.commandmode == #select do spnID.indeterminate = true
    127. )
    128. else spnID.indeterminate = true
    129. )
    130. -- spinner X
    131. on spn1 changed val do spnChanged spn1 val
    132. on spn1 buttonDown do spnBtnDown spn1
    133. on spn1 buttonUp do spnBtnUp spn1
    134. -- spinner Y
    135. on spn2 changed val do spnChanged spn2 val
    136. on spn2 buttonDown do spnBtnDown spn2
    137. on spn2 buttonUp do spnBtnUp spn2
    138. -- spinner Z
    139. on spn3 changed val do spnChanged spn3 val
    140. on spn3 buttonDown do spnBtnDown spn3
    141. on spn3 buttonUp do spnBtnUp spn3
    142. on TFB open do
    143. (
    144. callbacks.removescripts id:#typeInTransform
    145. callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform
    146. )
    147. on TFB close do
    148. (
    149. callbacks.removescripts id:#typeInTransform
    150. )
    151. )
    152.  
    153. createdialog TFB
    154. cui.RegisterDialogBar TFB
    155. cui.DockDialogBar TFB #cui_dock_bottom
    Hey miauu, if you got any idea how to improve this, feel free to post up, ok? :)
    The most top point on my to-do list for this script is making it to work with sub-object mode.

    PS: I do have a scipt to cycle between transform tool using a single hotkey, each press of a button on that other script will affect my TFB as well, like so;
    case toolmode.commandmode of
    (
        #select: 
        (
            max move
            TFB.xformLabel.caption = "Move"
            if selection.count == 1 then
            (
                TFB.spn1.value = $.pos.x
                TFB.spn2.value = $.pos.y
                TFB.spn3.value = $.pos.z
            )
            else
            (
                TFB.spn1.indeterminate = true
                TFB.spn2.indeterminate = true
                TFB.spn3.indeterminate = true
            )
        )
        #move:
        (
            max rotate
            TFB.xformLabel.caption = "Rotate"
            if selection.count == 1 then
            (
                TFB.spn1.value = $.rotation.controller[1].value
                TFB.spn2.value = $.rotation.controller[2].value
                TFB.spn3.value = $.rotation.controller[3].value
            )
            else
            (
                TFB.spn1.indeterminate = true
                TFB.spn2.indeterminate = true
                TFB.spn3.indeterminate = true
            )
        )
        #rotate:
        (
            max scale
            TFB.xformLabel.caption = "Scale"
            if selection.count == 1 then
            (
                TFB.spn1.value = ($.scale.x *100)
                TFB.spn2.value = ($.scale.y *100)
                TFB.spn3.value = ($.scale.z *100)
            )
            else
            (
                TFB.spn1.indeterminate = true
                TFB.spn2.indeterminate = true
                TFB.spn3.indeterminate = true
            )
        )
        #uscale:
        (
            max move
            TFB.xformLabel.caption = "Move"
            if selection.count == 1 then
            (
                TFB.spn1.value = $.pos.x
                TFB.spn2.value = $.pos.y
                TFB.spn3.value = $.pos.z
            )
            else
            (
                TFB.spn1.indeterminate = true
                TFB.spn2.indeterminate = true
                TFB.spn3.indeterminate = true
            )
        )
    )
    
    ..and another one to enter select mode;
    max select
    TFB.xformLabel.caption = "XForm"
    TFB.spn1.indeterminate = true
    TFB.spn2.indeterminate = true
    TFB.spn3.indeterminate = true
    
    ..so it'll somewhat context sensitive and didn't take so much space on my custom UI :)

    PPS: Ah, miauu on the other thread we're talking about mouse.buttonStates, can you try to press right mouse button and print the result after that?it seems like Max will stuck on the limbo of RMB being always held down (and this bugs also confirmed on the MXS help file, I believe....too bad :()
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    For making the script to works in sub-object mode you have to use:

    when geometry $ changes

    Open maxscript help file and read about WHEN COSNTRUCT.

    Is is written in mxs help file mouse.buttonStates and the right mouse button are not a friends. :)
  • Revel
    Offline / Send Message
    Revel interpolator
    Hi miauu, thanks for the info! but now after I read it, it seems there's more thing to work rather then just adding when geometry $. The script will only detect and update accordingly but wont affect the SO itself (unable to move the SO using the spinner), also to detect multiple selection is a whole new thing..haha. Currently my Transform Box wont even detect the multiple selected object yet :(
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    Why do you need a custom TTI?
  • Revel
    Offline / Send Message
    Revel interpolator
    For my custom UI :)

    hpHkKG9.jpg
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    I think that the best way is to find a way(if it is possible) to rearange the controls in the default TTI. :)
  • Revel
    Offline / Send Message
    Revel interpolator
    Eh? and the question is; is it possible to re-arrage the default TTI? haha :)
  • kman108
    Offline / Send Message
    kman108 polycounter lvl 10
    here's a custom status bar i use, has a scripted version of the tti that works with subobject selections. Currently needs work, has some bugs and i'm sure there's a lot of redundant code,but the functionality is there. Haven't spent much time on rotate or scale. Careful with selecting large amounts of edges or faces in a high density mesh :D to use it you need to assign you move, rotate, and scale hotkeys to the macros provided. if you make any progress with it i'd love a copy.
    1. macroscript CustomStatusBar
    2. tooltip:"Custom Status Bar"
    3. category:" Kyle"
    4.  
    5. (
    6. global selCen
    7. global GetCoordSys
    8. global statusBar
    9. global oldXspinVal = 0
    10. global oldYspinVal = 0
    11. global oldZspinVal = 0
    12. global spinToZero
    13. global VertArray
    14. global spinOff
    15. try(destroydialog StatusBar)catch()
    16.  
    17. fn GetCoordSys =
    18. (
    19. local CurCoordSys = getRefCoordSys()
    20. case of
    21. (
    22. (CurCoordSys == #world): StatusBar.Coord.selection = 1
    23. (CurCoordSys == #parent): StatusBar.Coord.selection = 2
    24. (CurCoordSys == #screen): StatusBar.Coord.selection = 3
    25. (CurCoordSys == #local): StatusBar.Coord.selection = 4
    26. (CurCoordSys == #working_pivot): StatusBar.Coord.selection = 5
    27. (CurCoordSys == #hybrid): StatusBar.Coord.selection = 6
    28. (CurCoordSys == #gimbal): StatusBar.Coord.selection = 7
    29. (CurCoordSys == #grid): StatusBar.Coord.selection = 8
    30. )
    31. )
    32.  
    33. fn SpinOFF = (StatusBar.xSpin.enabled = false; StatusBar.ySpin.enabled = false; StatusBar.zSpin.enabled = false
    34. StatusBar.xSpin.indeterminate = true; StatusBar.ySpin.indeterminate = true; StatusBar.zSpin.indeterminate = true)
    35. fn SpinON = (StatusBar.xSpin.indeterminate = false; StatusBar.ySpin.indeterminate = false; StatusBar.zSpin.indeterminate = false
    36. StatusBar.xSpin.enabled = true; StatusBar.ySpin.enabled = true; StatusBar.zSpin.enabled = true)
    37.  
    38. fn DisableCon = (StatusBar.xSpin.controller = undefined; StatusBar.ySpin.controller = undefined; StatusBar.zSpin.controller = undefined)
    39.  
    40. fn AbMovSpin = (StatusBar.xSpin.controller = $.pos.X_Position.controller; StatusBar.ySpin.controller = $.pos.Y_Position.controller
    41. StatusBar.zSpin.controller = $.pos.Z_Position.controller)
    42. fn spinToZero =
    43. (
    44. StatusBar.xSpin.value = 0
    45. StatusBar.ySpin.value = 0
    46. StatusBar.zSpin.value = 0
    47. )
    48.  
    49. fn VertArray =
    50. (
    51. VertSel = #()
    52. case (classof $) of
    53. (
    54. (Editable_Poly):
    55. (
    56. case subObjectLevel of
    57. (
    58. 0: ()
    59. 1: VertSel = (getvertselection $)as array
    60. 2: VertSel = (polyop.getVertsUsingedge $ (getedgeselection $))as array
    61. 3: VertSel = (polyop.getVertsUsingedge $ (getedgeselection $))as array
    62. 4: VertSel = (polyop.getVertsUsingFace $ (getfaceselection $))as array
    63. 5: VertSel = (polyop.getVertsUsingFace $ (getfaceselection $))as array
    64. )
    65. )
    66. (Editable_Mesh):
    67. (
    68. case subObjectLevel of
    69. (
    70. 0: (vertSel = undefined)
    71. 1: VertSel = (getvertselection $)as array
    72. 2: VertSel = (meshop.getVertsUsingedge $ (getedgeselection $))as array
    73. 3: VertSel = (meshop.getVertsUsingedge $ (getedgeselection $))as array
    74. 4: VertSel = (meshop.getVertsUsingFace $ (getfaceselection $))as array
    75. 5: VertSel = (meshop.getVertsUsingFace $ (getfaceselection $))as array
    76. )
    77. )
    78. )
    79. try(return VertSel)catch(return #())
    80. )
    81.  
    82. fn SelPos =
    83. (
    84. local AvgVertPos = [0,0,0]
    85. local VertSel = VertArray()
    86. try
    87. (
    88. if VertSel.count == 0 then SpinOFF()
    89. else
    90. (
    91. if StatusBar.offset.state == true then (SpinOn(); spinToZero())
    92. else
    93. (
    94. SpinOn()
    95. case (classof $) of
    96. (
    97. (Editable_Poly): for v in VertSel do AvgVertPos += polyop.getvert $ v
    98. (Editable_Mesh): for v in VertSel do AvgVertPos += meshop.getvert $ v
    99. )
    100. StatusBar.xSpin.value = (AvgVertPos / VertSel.count).X
    101. StatusBar.ySpin.value = (AvgVertPos / VertSel.count).Y
    102. StatusBar.zSpin.value = (AvgVertPos / VertSel.count).Z
    103. )
    104. )
    105. )catch(SpinOFF())
    106. )
    107.  
    108. fn getPos =
    109. (
    110. local AvgVertPos = [0,0,0]
    111. local VertSel = VertArray()
    112. if VertSel.count != 0 then
    113. (
    114. case (classof $) of
    115. (
    116. (Editable_Poly): for v in VertSel do AvgVertPos += polyop.getvert $ v
    117. (Editable_Mesh): for v in VertSel do AvgVertPos += meshop.getvert $ v
    118. )
    119. return (AvgVertPos / VertSel.count)
    120. )
    121. )
    122.  
    123. fn moveX newVal =
    124. (
    125. case subObjectLevel of
    126. (
    127. 0:( )
    128. 1: move $.selectedVerts [newVal,0,0]
    129. 2: move $.selectedEdges [newVal,0,0]
    130. 3: move $.selectedEdges [newVal,0,0]
    131. 4: move $.selectedFaces [newVal,0,0]
    132. 5: move $.selectedFaces [newVal,0,0]
    133. )
    134. )
    135.  
    136. fn moveY newVal =
    137. (
    138. case subObjectLevel of
    139. (
    140. 0:( )
    141. 1: move $.selectedVerts [0,newVal,0]
    142. 2: move $.selectedEdges [0,newVal,0]
    143. 3: move $.selectedEdges [0,newVal,0]
    144. 4: move $.selectedFaces [0,newVal,0]
    145. 5: move $.selectedFaces [0,newVal,0]
    146. )
    147. )
    148.  
    149. fn moveZ newVal =
    150. (
    151. case subObjectLevel of
    152. (
    153. 0:( )
    154. 1: move $.selectedVerts [0,0,newVal]
    155. 2: move $.selectedEdges [0,0,newVal]
    156. 3: move $.selectedEdges [0,0,newVal]
    157. 4: move $.selectedFaces [0,0,newVal]
    158. 5: move $.selectedFaces [0,0,newVal]
    159. )
    160. )
    161.  
    162. rollout StatusBar ""
    163. (
    164. local xOff = 40
    165. local btnW = 24
    166. local btnSmlW = 16
    167. local btnYoff = -29
    168. local btnRoff = -31
    169. local spnYoff = -21
    170. local drpYoff = -27
    171.  
    172. local isspinnerX = false
    173. local firstundoX = false
    174. local isspinnerY = false
    175. local firstundoY = false
    176. local isspinnerZ = false
    177. local firstundoZ = false
    178.  
    179. button openBack "Autoback" height:btnW width: 55 align: #left offset: [0,-2] --across:50 --offset:[-300,0]
    180. button opentrack "Trackbar" height:btnW width: 55 align: #left offset: [55,btnYoff] --across:50 --offset:[-300,0]
    181. button soulBurn "Soulburn" height:btnW width: 55 align: #left offset: [110,btnYoff] --across:50 --offset:[-300,0]
    182. --button mLoop "M-Loop" height:btnW width: 45 align: #left offset: [220,btnYoff] --across:50 --offset:[-300,0]
    183. --button mRing "M-Ring" height:btnW width: 45 align: #left offset: [265,btnYoff] --across:50 --offset:[-300,0]
    184. button openTTI "" height:btnSmlW width:btnSmlW align: #center offset: [-170,spnYoff-2] --images: #("Maintoolbar_24i.bmp","Maintoolbar_24a.bmp", 104, 21, 21, 21, 21)
    185. checkbutton offset "A" height:btnSmlW width:btnSmlW align: #center offset: [-153,spnYoff] --across:3 --pos: [20+xOff,4]
    186. Spinner xSpin "" width: 75 Range:[-100000, 100000,0] align: #center offset: [-105,spnYoff] --scale: ScaleAmt pos: [20+xOff,4]
    187. Spinner ySpin "" width: 75 Range:[-100000, 100000,0] align: #center offset: [-30,spnYoff]--align: #centre --scale: ScaleAmt pos: [95+xOff,4]
    188. Spinner zSpin "" width: 75 Range:[-100000, 100000,0] align: #center offset: [45,spnYoff] --align: #centre --scale: ScaleAmt pos: [170+xOff,4]
    189. dropdownList Coord "" width: 65 align: #center offset: [150,drpYoff+3] items:#("World", "Parent", "Screen", "Local", "Working", "View", "Gimbal", "Grid")
    190. button MxsHelp "Help" height:btnW width:40 align: #right offset: [0,btnYoff-1] --images: #("Maxscript_24i.bmp","Maxscript_24i.bmp", 5, 5, 5, 5, 5)
    191. button MxsList "Listener" height:btnW width:55 align: #right offset: [-40,btnYoff] --images: #("Maxscript_24i.bmp","Maxscript_24i.bmp", 5, 1, 1, 1, 1)
    192. button MxsEdit "Editor" height:btnW width:45 align: #right offset: [-95,btnYoff] --images: #("Maxscript_24i.bmp","Maxscript_24a.bmp", 5, 2, 2, 2, 2)
    193. button MxsRun "Run" height:btnW width:35 align: #right offset: [-140,btnYoff] --images: #("Maxscript_24i.bmp","Maxscript_24a.bmp", 5, 3, 3, 3, 3)
    194. --button fenceMarq "Fence" width:40 height:btnW align: #right offset: [-220,btnYoff]
    195. --button sprayMarq "Spray" width:40 height:btnW align: #right offset: [-260,btnYoff]
    196. --button squareMarq "Square" width:40 height:btnW align: #right offset: [-300,btnYoff] --items:#("Square", "Circle", "Fence", "Lasso", "Spray") --images: #("Maintoolbar_24i.bmp","Maintoolbar_24a.bmp", 104, 13, 13, 13, 13)
    197. --button PPcenter "Pivot" width:40 height:btnW align: #right offset: [-360,btnYoff] --items:#("Transform", "Selection","Pivot" ) --images: #("Maintoolbar_24i.bmp","Maintoolbar_24a.bmp", 104, 35, 35, 35, 35)
    198.  
    199.  
    200.  
    201. -------------------------------------------------------------------EVENTS------------------------------------------------------------------------------------------------
    202. on openBack pressed do try(macros.run "Zorb Tools" "ABLoader")catch()
    203. on openTrack pressed do try(macros.run "Kyle" "TrackbarToggle")catch()
    204. on soulBurn pressed do try(macros.run "SoulburnScripts" "soulburnScriptsListerUI")catch()
    205. on mRing pressed do try(macros.run "miauusScriptPack_vol2" "macroSP_vol2_SmartRingDotSelection_UI")catch()
    206. on mLoop pressed do try(macros.run "miauusScriptPack_vol2" "macroSP_vol2_SmartLoopDotSelection_UI")catch()
    207. on openTTI pressed do actionMan.executeAction 0 "40093"
    208. on offset changed val do
    209. (
    210. if val == true then (DisableCon(); offset.text = "O"; spinToZero())
    211. else if subObjectlevel == 0 then (offset.text = "A"; AbMovSpin()) else (offset.text = "A"; SelPos())
    212. )
    213. -------------------------------------------------------------------XSPIN EVENTS------------------------------------------------------------------------------------------------
    214. on xspin buttondown do (isspinnerX = true; firstundoX = true; SubobjMoveCall = undefined; gc light:true; oldXspinVal = xspin.value)
    215. on xspin changed val isSpin do
    216. (
    217. if isSpin == true then
    218. (
    219. local useundoX = (isspinnerX and firstundoX) or (not isspinnerX)
    220. undo "changedxSpin" useundoX
    221. (
    222. newVal = -oldXspinVal + xspin.value
    223. oldXspinVal = newVal + oldXspinVal
    224. moveX newVal
    225. )
    226. firstundoX = false
    227. )
    228. else()
    229. )
    230. on xSpin entered spinArg cancelArg do
    231. (
    232. if spinArg != true and cancelArg != true then
    233. (
    234. local useundoX = (isspinnerX and firstundoX) or (not isspinnerX)
    235. undo "changedxEnter" useundoX
    236. (
    237. if offset.state == true then (moveX xSpin.value; xSpin.value = 0)
    238. else moveX -((getPos()).x - xSpin.value )
    239. )
    240. firstundoX = false
    241. )
    242. else
    243. (
    244. if offset.state != true then
    245. (
    246. local useundoX = (isspinnerX and firstundoX) or (not isspinnerX)
    247. undo "changedxEnter2" useundoX
    248. (
    249. newVal = -oldXspinVal + xspin.value
    250. oldXspinVal = newVal + oldXspinVal
    251. moveX newVal
    252. )
    253. firstundoX = false
    254. )
    255. )
    256. )
    257. on xspin buttonup do
    258. (
    259. isspinnerX = false; if offset.state == true then xSpin.value = 0
    260. SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen
    261. )
    262. -------------------------------------------------------------------YSPIN EVENTS------------------------------------------------------------------------------------------------
    263. on ySpin buttondown do (isspinnerY = true; firstundoY = true; SubobjMoveCall = undefined; gc light:true; oldySpinVal = ySpin.value)
    264. on ySpin changed val isSpin do
    265. (
    266. if isSpin == true then
    267. (
    268. local useundoY = (isspinnerY and firstundoY) or (not isspinnerY)
    269. undo "changedySpin" useundoY
    270. (
    271. newVal = -oldySpinVal + ySpin.value
    272. oldySpinVal = newVal + oldySpinVal
    273. moveY newVal
    274. )
    275. firstundoY = false
    276. )
    277. else()
    278. )
    279. on ySpin entered spinArg cancelArg do
    280. (
    281. if spinArg != true and cancelArg != true then
    282. (
    283. local useundoY = (isspinnerY and firstundoY) or (not isspinnerY)
    284. undo "changedyEnter" useundoY
    285. (
    286. if offset.state == true then (moveY ySpin.value; ySpin.value = 0)
    287. else moveY -((getPos()).y - ySpin.value )
    288. )
    289. firstundoY = false
    290. )
    291. else
    292. (
    293. if offset.state != true then
    294. (
    295. local useundoY = (isspinnerY and firstundoY) or (not isspinnerY)
    296. undo "changedyEnter2" useundoY
    297. (
    298. newVal = -oldySpinVal + ySpin.value
    299. oldySpinVal = newVal + oldySpinVal
    300. moveY newVal
    301. )
    302. firstundoY = false
    303. )
    304. )
    305. )
    306. on ySpin buttonup do
    307. (
    308. isspinnerY = false; if offset.state == true then ySpin.value = 0
    309. SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen
    310. )
    311. -------------------------------------------------------------------ZSPIN EVENTS------------------------------------------------------------------------------------------------
    312. on zSpin buttondown do (isspinnerZ = true; firstundoZ = true; SubobjMoveCall = undefined; gc light:true; oldzSpinVal = zSpin.value)
    313. on zSpin changed val isSpin do
    314. (
    315. if isSpin == true then
    316. (
    317. local useundoZ = (isspinnerZ and firstundoZ) or (not isspinnerZ)
    318. undo "changedzSpin" useundoZ
    319. (
    320. newVal = -oldzSpinVal + zSpin.value
    321. oldzSpinVal = newVal + oldzSpinVal
    322. moveZ newVal
    323. )
    324. firstundoZ = false
    325. )
    326. else()
    327. )
    328. on zSpin entered spinArg cancelArg do
    329. (
    330. if spinArg != true and cancelArg != true then
    331. (
    332. local useundoZ = (isspinnerZ and firstundoZ) or (not isspinnerZ)
    333. undo "changedzEnter" useundoZ
    334. (
    335. if offset.state == true then (moveZ zSpin.value; zSpin.value = 0)
    336. else moveZ -((getPos()).z - zSpin.value )
    337. )
    338. firstundoZ = false
    339. )
    340. else
    341. (
    342. if offset.state != true then
    343. (
    344. local useundoZ = (isspinnerZ and firstundoZ) or (not isspinnerZ)
    345. undo "changedzEnter2" useundoZ
    346. (
    347. newVal = -oldzSpinVal + zSpin.value
    348. oldzSpinVal = newVal + oldzSpinVal
    349. moveZ newVal
    350. )
    351. firstundoZ = false
    352. )
    353. )
    354. )
    355. on zSpin buttonup do
    356. (
    357. isspinnerZ = false; if offset.state == true then zSpin.value = 0
    358. SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen
    359. )
    360. on Coord selected i do
    361. (
    362. case i of
    363. (
    364. 1: toolMode.coordsys #world
    365. 2: toolMode.coordsys #parent
    366. 3: toolMode.coordsys #screen
    367. 4: toolMode.coordsys #local
    368. 5: toolMode.coordsys #working_pivot
    369. 6: toolMode.coordsys #view
    370. 7: toolMode.coordsys #gimbal
    371. 8: toolMode.coordsys #grid
    372. )
    373. )
    374. --on PPcenter pressed do toolMode.pivotCenter()
    375. on squareMarq pressed do actionMan.executeAction 0 "59232"
    376. on sprayMarq pressed do actionMan.executeAction 0 "59236"
    377. on fenceMarq pressed do actionMan.executeAction 0 "59234"
    378. on MxsHelp pressed do actionMan.executeAction 0 "40366"
    379. on MxsList pressed do actionMan.executeAction 0 "40472"
    380. on MxsEdit pressed do actionMan.executeAction 0 "40839"
    381. on MxsRun pressed do actionMan.executeAction 0 "40470"
    382. on statusBar open do
    383. (
    384. callbacks.addscript #spacemodeChange "GetCoordSys()" id:#CoordSysCallback
    385. SelPos()
    386. )
    387. on statusBar closed do
    388. (
    389. callbacks.removeScripts #spacemodeChange id:#CoordSysCallback
    390. )
    391. )
    392. createdialog StatusBar width:1423 height:30 pos:[303,sysInfo.desktopSize.y-65] style:#(#style_border)
    393. )
    macroscript KMove
    category:"  Kyle"
    tooltip:"Move"
    
    (	
    
    global SelChangeMOV
    global StatusBar
    global SelCen
    global SubObjChange
    	
    
    fn RemoveSelChangeCall = callbacks.removeScripts #selectionSetChanged id:#SelChangeMOVCallback
    	
    fn SpinOFF = (StatusBar.xSpin.enabled = false; StatusBar.ySpin.enabled = false; StatusBar.zSpin.enabled = false
    			 StatusBar.xSpin.indeterminate = true; StatusBar.ySpin.indeterminate = true; StatusBar.zSpin.indeterminate = true) 
    			 
    fn SpinON = (StatusBar.xSpin.indeterminate = false; StatusBar.ySpin.indeterminate = false; StatusBar.zSpin.indeterminate = false
    			StatusBar.xSpin.enabled = true; StatusBar.ySpin.enabled = true; StatusBar.zSpin.enabled = true)
    			
    fn AbMovSpin = (StatusBar.xSpin.controller = $.pos.X_Position.controller; StatusBar.ySpin.controller = $.pos.Y_Position.controller
    	            StatusBar.zSpin.controller = $.pos.Z_Position.controller) 
    				
    fn DisableCon = (StatusBar.xSpin.controller = undefined; StatusBar.ySpin.controller = undefined; StatusBar.zSpin.controller = undefined)
    
    fn spinToZero = (StatusBar.xSpin.value = 0; StatusBar.ySpin.value = 0; StatusBar.zSpin.value = 0)
    
    fn SelChangeMOV =  
    (
    	if selection.count == 0 do SpinOFF()
    	if selection.count > 1 do SpinOFF()
    	if selection.count == 1 do (SpinON(); ABmovSpin())
    )
    
    fn VertArray = 
    (
    	VertSel = #()
    	case (classof $) of
    	(
    		(Editable_Poly):
    		(
    			case subObjectLevel of 
    			(
    				0: ()
    				1: VertSel = (getvertselection $)as array
    				2: VertSel = (polyop.getVertsUsingedge $ (getedgeselection $))as array 
    				3: VertSel = (polyop.getVertsUsingedge $ (getedgeselection $))as array 
    				4: VertSel = (polyop.getVertsUsingFace $ (getfaceselection $))as array 
    				5: VertSel = (polyop.getVertsUsingFace $ (getfaceselection $))as array 
    			)
    		)
    		(Editable_Mesh):
    		(
    			case subObjectLevel of 
    			(
    				0: ()
    				1: VertSel = (getvertselection $)as array
    				2: VertSel = (meshop.getVertsUsingedge $ (getedgeselection $))as array 
    				3: VertSel = (meshop.getVertsUsingedge $ (getedgeselection $))as array 
    				4: VertSel = (meshop.getVertsUsingFace $ (getfaceselection $))as array 
    				5: VertSel = (meshop.getVertsUsingFace $ (getfaceselection $))as array 
    			)
    		)
    	)
    	
    	try(return VertSel)catch(return #())
    )
    
    fn setSpinners vertSel = 
    (
    	local AvgVertPos = [0,0,0]
    	if vertSel.count == 0 then SpinOFF()
    	else
    	(
    		if StatusBar.offset.state == true then (SpinOn(); spinToZero())
    		else
    		(
    			SpinOn()
    			case (classof $) of
    			(
    				(Editable_Poly): for v in VertSel do AvgVertPos += polyop.getvert $ v
    				(Editable_Mesh): for v in VertSel do AvgVertPos += meshop.getvert $ v
    			)
    			StatusBar.xSpin.value = (AvgVertPos / VertSel.count).X
    			StatusBar.ySpin.value = (AvgVertPos / VertSel.count).Y
    			StatusBar.zSpin.value = (AvgVertPos / VertSel.count).Z
    		)
    	)
    )
    
    fn SelCen eventName animHandle = (setSpinners (VertArray()))
    
    fn SubObjChange = 
    (
    	local vertSel = VertArray()
    	local AvgVertPos = [0,0,0]
    	--callbacks.removeScripts #selectionSetChanged id:#SelChangeMOVCallback
        case subObjectLevel of
        (
    	    0:
    		(
    			try(SubobjMoveCall = undefined; gc light:true)catch
    			callbacks.addscript #selectionSetChanged "SelChangeMOV()" id:#SelChangeMOVCallback
    		    if selection.count ==0 do (SpinOFF(); DisableCon)
                if selection.count > 1 do (SpinOFF(); DisableCon)
                if selection.count ==1 do (SpinON(); AbMovSpin()) --if Statusbar.offset.state == true then (SpinON(); DisableCon()) else 
    		)
    	    1:(RemoveSelChangeCall(); SpinON(); DisableCon();setSpinners (VertArray()))
    	    2:(RemoveSelChangeCall(); SpinON(); DisableCon();setSpinners (VertArray()))
    	    3:(RemoveSelChangeCall(); SpinON(); DisableCon();setSpinners (VertArray()))
    	    4:(RemoveSelChangeCall(); SpinON(); DisableCon();setSpinners (VertArray()))
    	    5:(RemoveSelChangeCall(); SpinON(); DisableCon();setSpinners (VertArray()))
    	)
    	NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen
    )
    
    SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen 
    callbacks.removeScripts #selectionSetChanged id:#SelChangeROTCallback
    max move
    SubObjChange()
    callbacks.addscript	#ModPanelSubObjectLevelChanged "SubObjChange()" id:#SubObjChangeMOVCallback
    callbacks.addscript #selectionSetChanged "SelChangeMOV()" id:#SelChangeMOVCallback
    
    )
    
    
    
    macroscript KRotate
    category:"  Kyle"
    tooltip:"Rotate"
    
    (	
    callbacks.removeScripts #selectionSetChanged id:#SelChangeMOVCallback
    global SelChangeROT
    global StatusBar
    	
    fn SpinOFF = (StatusBar.xSpin.indeterminate = true; StatusBar.ySpin.indeterminate = true; StatusBar.zSpin.indeterminate = true) -----------------disables spinners
    fn SpinON = (StatusBar.xSpin.indeterminate = false; StatusBar.ySpin.indeterminate = false; StatusBar.zSpin.indeterminate = false)----------------enables spinners
    fn AbRotSpin = (StatusBar.xSpin.controller = $.rotation.X_rotation.controller; StatusBar.ySpin.controller = $.rotation.Y_rotation.controller
    	            StatusBar.zSpin.controller = $.rotation.Z_rotation.controller) ----------------------------sets spinners to rotation controller of selected
    	
    fn SelChangeROT =
    (
    	if selection.count == 0 do SpinOFF()
    	if selection.count > 1 do SpinOFF()
    	if selection.count == 1 do (SpinON(); AbRotSpin())
    )
    
    max rotate
    case subObjectLevel of
    (
    	0:
    	( 
    		if selection.count ==0 do SpinOFF()
            if selection.count > 1 do SpinOFF()
            if selection.count ==1 do (SpinON(); AbRotSpin())
        )
    	1:()
    	2:()
    	3:()
    	4:()
    	5:()
    )
    callbacks.addscript #selectionSetChanged "SelChangeROT()" id:#SelChangeROTCallback
    )
    
    macroscript KScale
    category:"  Kyle"
    tooltip:"Scale"
    
    (
    try(
    	max SCALE
    	StatusBar.xSpin.controller = $.scale.X_scale.controller
    	StatusBar.ySpin.controller = $.scale.Y_scale.controller
    	StatusBar.zSpin.controller = $.scale.Z_scale.controller
    	
    )
    catch()
    )
    
    
  • Pedro Amorim
    Yeah, would like to get a custom coordinates toolbar for myself as well. :)
    Mgkg1Af.png
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    Revel wrote: »
    Eh? and the question is; is it possible to re-arrage the default TTI? haha :)
    The answer is - Yes, the default TTI can be rearanged. But, most propably this rearangement will works for 3dsMax 2014 and up and I don't know if the resulting dialog an be docked and the titlebar removed. But the spinners in the TTI can be rearanged and the size of the TTI dan be changed.
  • Pedro Amorim
    Will it wor for 2012?
  • Revel
    Offline / Send Message
    Revel interpolator
    miauu, any clues on how to do that? but if we can modified it, means we have an access to the spinner control itself, if that so shouldn't we be able to assign those spinner control to our own custom spinner?
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    Revel wrote: »
    miauu, any clues on how to do that? but if we can modified it, means we have an access to the spinner control itself, if that so shouldn't we be able to assign those spinner control to our own custom spinner?

    Linking custom spinners to the Tti spinners is not a problem. I thought about this after I post my previous post. I don't know if it will gives the same speed as when we use the Tti spinners, but it wil work with max9+. Tonight I will try to post a solution, if someone not post it before me.
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    I've tried to link custom spinners to the spinners of the TTI, but the result is not as expected. The object is moved/scaled/rotated when the mouse button is released after it was pressed over the spinner's arrow.
    In my next post is the final script.
  • Pedro Amorim
    very nice! Is it dockable to the toolbar?
  • miauu
    Offline / Send Message
    miauu polycounter lvl 15
    The script is ready. You can find it here.
    The mini TTI can't be docked, but when the title bar and the borders are removed you can't move it, so place it in proper place and it will stay there.
    Watch the video to see how to use the script. Tested on 3dsMax 2009 through 2015, Windows 7 and Windows 8.1.

    Video demonstration.
Sign In or Register to comment.