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;
rollout TFB "Transform Box" width:870 height:30
(
label Movelabel "Move" pos:[0,5] width:32
spinner spn1 "X" range: [-1e+008,1e+007,0] pos:[40,5] width:70
spinner spn2 "Y" range: [-1e+008,1e+007,0] pos:[120,5] width:70
spinner spn3 "Z" range: [-1e+008,1e+007,0] pos:[200,5] width:70
label Rotlabel "Rotate" pos:[285,5] width:32
spinner spn4 "X" range: [-1e+008,1e+007,0] pos:[330,5] width:70
spinner spn5 "Y" range: [-1e+008,1e+007,0] pos:[410,5] width:70
spinner spn6 "Z" range: [-1e+008,1e+007,0] pos:[490,5] width:70
label Scalelabel "Scale" pos:[575,5] width:32
spinner spn7 "X" range: [-1e+008,1e+007,0] pos:[620,5] width:70 scale:0.01
spinner spn8 "Y" range: [-1e+008,1e+007,0] pos:[700,5] width:70 scale:0.01
spinner spn9 "Z" range: [-1e+008,1e+007,0] pos:[780,5] width:70 scale:0.01
fn redefineTransformHandlers selection =
(
deleteAllChangeHandlers id:#typeInTransform
if selection.count == 0 do return()
if selection.count == 1 do
(
spn1.value = $.pos.x
spn2.value = $.pos.y
spn3.value = $.pos.z
spn4.value = $.rotation.x
spn5.value = $.rotation.y
spn6.value = $.rotation.z
when transform $ changes id:#typeInTransform handleAt:#redrawViews do
(
spn1.value = $.pos.x
spn2.value = $.pos.y
spn3.value = $.pos.z
spn4.value = $.rotation.x
spn5.value = $.rotation.y
spn6.value = $.rotation.z
)
)
)
on spn1 changed val do if selection.count == 1 do selection[1].pos.x = val
on spn2 changed val do if selection.count == 1 do selection[1].pos.y = val
on spn3 changed val do if selection.count == 1 do selection[1].pos.z = val
on spn4 changed val do if selection.count == 1 do selection[1].rotation.x = val
on spn5 changed val do if selection.count == 1 do selection[1].rotation.y = val
on spn6 changed val do if selection.count == 1 do selection[1].rotation.z = val
on TFB open do
(
callbacks.removescripts id:#typeInTransform
callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform
)
on TFB close do
(
callbacks.removescripts id:#typeInTransform
)
)
createdialog TFB
cui.RegisterDialogBar TFB
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
rollout TFB "Transform Box" width:870 height:30 ( label Movelabel "Move" pos:[0,5] width:32 spinner spn1 "X" range: [-1e+008,1e+007,0] pos:[40,5] width:70 spinner spn2 "Y" range: [-1e+008,1e+007,0] pos:[120,5] width:70 spinner spn3 "Z" range: [-1e+008,1e+007,0] pos:[200,5] width:70 label Rotlabel "Rotate" pos:[285,5] width:32 spinner spn4 "X" range: [-1e+008,1e+007,0] pos:[330,5] width:70 spinner spn5 "Y" range: [-1e+008,1e+007,0] pos:[410,5] width:70 spinner spn6 "Z" range: [-1e+008,1e+007,0] pos:[490,5] width:70 label Scalelabel "Scale" pos:[575,5] width:32 spinner spn7 "X" range: [-1e+008,1e+007,0] pos:[620,5] width:70 scale:0.01 spinner spn8 "Y" range: [-1e+008,1e+007,0] pos:[700,5] width:70 scale:0.01 spinner spn9 "Z" range: [-1e+008,1e+007,0] pos:[780,5] width:70 scale:0.01 fn redefineTransformHandlers selection = ( deleteAllChangeHandlers id:#typeInTransform if selection.count == 0 do ( spn1.value = 0 spn2.value = 0 spn3.value = 0 spn4.value = 0 spn5.value = 0 spn6.value = 0 ) if selection.count == 1 do ( spn1.value = $.pos.x spn2.value = $.pos.y spn3.value = $.pos.z spn4.value = $.rotation.controller[1].value spn5.value = $.rotation.controller[2].value spn6.value = $.rotation.controller[3].value when transform $ changes id:#typeInTransform handleAt:#redrawViews do ( spn1.value = $.pos.x spn2.value = $.pos.y spn3.value = $.pos.z spn4.value = $.rotation.controller[1].value spn5.value = $.rotation.controller[2].value spn6.value = $.rotation.controller[3].value ) ) ) on spn1 changed val do if selection.count == 1 do selection[1].pos.x = val on spn2 changed val do if selection.count == 1 do selection[1].pos.y = val on spn3 changed val do if selection.count == 1 do selection[1].pos.z = val on spn4 changed val do if selection.count == 1 do selection[1].rotation.controller[1].value = val on spn5 changed val do if selection.count == 1 do selection[1].rotation.controller[2].value = val on spn6 changed val do if selection.count == 1 do selection[1].rotation.controller[3].value = val on TFB open do ( callbacks.removescripts id:#typeInTransform callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform ) on TFB close do ( callbacks.removescripts id:#typeInTransform ) ) createdialog TFBWhat about scale then?
It appears that the display value on the spinner: 1, 2, 3 corresponded into 100%, 200%, 300% value on the standard tti box..hmmmm..
rollout TFB "Transform Box" width:870 height:30 ( label Movelabel "Move" pos:[0,5] width:32 spinner spn1 "X" range: [-1e+008,1e+007,0] pos:[40,5] width:70 spinner spn2 "Y" range: [-1e+008,1e+007,0] pos:[120,5] width:70 spinner spn3 "Z" range: [-1e+008,1e+007,0] pos:[200,5] width:70 label Rotlabel "Rotate" pos:[285,5] width:32 spinner spn4 "X" range: [-1e+008,1e+007,0] pos:[330,5] width:70 spinner spn5 "Y" range: [-1e+008,1e+007,0] pos:[410,5] width:70 spinner spn6 "Z" range: [-1e+008,1e+007,0] pos:[490,5] width:70 label Scalelabel "Scale" pos:[575,5] width:32 spinner spn7 "X" range: [-1e+008,1e+007,0] pos:[620,5] width:70 scale:1.0 spinner spn8 "Y" range: [-1e+008,1e+007,0] pos:[700,5] width:70 scale:1.0 spinner spn9 "Z" range: [-1e+008,1e+007,0] pos:[780,5] width:70 scale:1.0 fn redefineTransformHandlers selection = ( deleteAllChangeHandlers id:#typeInTransform if selection.count == 0 do ( spn1.value = 0 spn2.value = 0 spn3.value = 0 spn4.value = 0 spn5.value = 0 spn6.value = 0 spn7.value = 0 spn8.value = 0 spn9.value = 0 ) if selection.count == 1 do ( spn1.value = $.pos.x spn2.value = $.pos.y spn3.value = $.pos.z spn4.value = $.rotation.controller[1].value spn5.value = $.rotation.controller[2].value spn6.value = $.rotation.controller[3].value spn7.value = ($.scale.x * 100) spn8.value = ($.scale.y * 100) spn9.value = ($.scale.z * 100) when transform $ changes id:#typeInTransform handleAt:#redrawViews do ( spn1.value = $.pos.x spn2.value = $.pos.y spn3.value = $.pos.z spn4.value = $.rotation.controller[1].value spn5.value = $.rotation.controller[2].value spn6.value = $.rotation.controller[3].value spn7.value = ($.scale.x * 100) spn8.value = ($.scale.y * 100) spn9.value = ($.scale.z * 100) ) ) ) on spn1 changed val do if selection.count == 1 do selection[1].pos.x = val on spn2 changed val do if selection.count == 1 do selection[1].pos.y = val on spn3 changed val do if selection.count == 1 do selection[1].pos.z = val on spn4 changed val do if selection.count == 1 do selection[1].rotation.controller[1].value = val on spn5 changed val do if selection.count == 1 do selection[1].rotation.controller[2].value = val on spn6 changed val do if selection.count == 1 do selection[1].rotation.controller[3].value = val on spn7 changed val do if selection.count == 1 do selection[1].scale.x = (val/100) on spn8 changed val do if selection.count == 1 do selection[1].scale.y = (val/100) on spn9 changed val do if selection.count == 1 do selection[1].scale.z = (val/100) on TFB open do ( callbacks.removescripts id:#typeInTransform callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform ) on TFB close do ( callbacks.removescripts id:#typeInTransform ) ) createdialog TFBThis should work. Think my max just bugged out
matchPattern "ASD BSD" pattern:"ASD*"
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
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;
when transform $ changes id:#typeInTransform handleAt:#redrawViews do ( case (toolmode.commandmode) of ( #move: print "temp mv" #rotate: print "temp rt" #uscale: print "temp sc" ) )..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?when transform $ changes id:#typeInTransform handleAt:#redrawViews do ( case (toolmode.commandmode) of ( #move: (print "temp mv") #rotate: (print "temp rt") #uscale: (print "uniform scale") #squash: (print "squash") #nuscale: (print "non uniform scale") ) )Here is what I've got so far;
rollout TFB "Transform Box" width:310 height:28 ( local isSpinner = false local firstUndo = false local spnID, spnVal, spnAxis, spnTFArray label xformLabel "XForm" pos:[5,5] width:40 spinner spn1 "X:" range: [-1e+008,1e+007,0] pos:[55,5] width:70 spinner spn2 "Y:" range: [-1e+008,1e+007,0] pos:[140,5] width:70 spinner spn3 "Z:" range: [-1e+008,1e+007,0] pos:[225,5] width:70 fn redefineTransformHandlers selection = ( deleteAllChangeHandlers id:#typeInTransform if selection.count == 1 then ( try ( case (toolmode.commandmode) of ( #move: ( spn1.value = $.pos.x spn2.value = $.pos.y spn3.value = $.pos.z ) #rotate: ( spn1.value = $.rotation.controller[1].value spn2.value = $.rotation.controller[2].value spn3.value = $.rotation.controller[3].value ) #uscale: ( spn1.value = ($.scale.x *100) spn2.value = ($.scale.y *100) spn3.value = ($.scale.z *100) ) ) ) catch() when transform $ changes id:#typeInTransform handleAt:#redrawViews do ( case (toolmode.commandmode) of ( #move: ( spn1.value = $.pos.x spn2.value = $.pos.y spn3.value = $.pos.z ) #rotate: ( spn1.value = $.rotation.controller[1].value spn2.value = $.rotation.controller[2].value spn3.value = $.rotation.controller[3].value ) #uscale: ( spn1.value = ($.scale.x *100) spn2.value = ($.scale.y *100) spn3.value = ($.scale.z *100) ) #nuscale: ( spn1.value = ($.scale.x *100) spn2.value = ($.scale.y *100) spn3.value = ($.scale.z *100) ) ) ) ) else ( spn1.indeterminate = true spn2.indeterminate = true spn3.indeterminate = true ) ) fn spnChanged spnID spnVal = ( if selection.count == 1 then ( local useUndo = (isSpinner and firstUndo) or (not isSpinner) undo "changed" useUndo ( case (toolmode.commandmode) of ( #move:case spnID of ( spn1: selection[1].pos.x = spnVal spn2: selection[1].pos.y = spnVal spn3: selection[1].pos.z = spnVal ) #rotate: case spnID of ( spn1: selection[1].rotation.controller[1].value = spnVal spn2: selection[1].rotation.controller[2].value = spnVal spn3: selection[1].rotation.controller[3].value = spnVal ) #uscale: case spnID of ( spn1: selection[1].scale.x = (spnVal/100) spn2: selection[1].scale.y = (spnVal/100) spn3: selection[1].scale.z = (spnVal/100) ) #select: spnID.indeterminate = true ) ) firstUndo = false completeRedraw() ) else spnID.indeterminate = true ) fn spnBtnDown spnID = ( if selection.count == 1 then ( isSpinner = true firstUndo = true ) else spnID.indeterminate = true ) fn spnBtnUp spnID= ( if selection.count == 1 then ( isSpinner = false if toolmode.commandmode == #select do spnID.indeterminate = true ) else spnID.indeterminate = true ) -- spinner X on spn1 changed val do spnChanged spn1 val on spn1 buttonDown do spnBtnDown spn1 on spn1 buttonUp do spnBtnUp spn1 -- spinner Y on spn2 changed val do spnChanged spn2 val on spn2 buttonDown do spnBtnDown spn2 on spn2 buttonUp do spnBtnUp spn2 -- spinner Z on spn3 changed val do spnChanged spn3 val on spn3 buttonDown do spnBtnDown spn3 on spn3 buttonUp do spnBtnUp spn3 on TFB open do ( callbacks.removescripts id:#typeInTransform callbacks.addScript #selectionSetChanged "TFB.redefineTransformHandlers selection" id:#typeInTransform ) on TFB close do ( callbacks.removescripts id:#typeInTransform ) ) createdialog TFB cui.RegisterDialogBar TFB cui.DockDialogBar TFB #cui_dock_bottomHey 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; ..so it'll somewhat context sensitive and didn't take so much space on my custom UIPPS: 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
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.
macroscript CustomStatusBar tooltip:"Custom Status Bar" category:" Kyle" ( global selCen global GetCoordSys global statusBar global oldXspinVal = 0 global oldYspinVal = 0 global oldZspinVal = 0 global spinToZero global VertArray global spinOff try(destroydialog StatusBar)catch() fn GetCoordSys = ( local CurCoordSys = getRefCoordSys() case of ( (CurCoordSys == #world): StatusBar.Coord.selection = 1 (CurCoordSys == #parent): StatusBar.Coord.selection = 2 (CurCoordSys == #screen): StatusBar.Coord.selection = 3 (CurCoordSys == #local): StatusBar.Coord.selection = 4 (CurCoordSys == #working_pivot): StatusBar.Coord.selection = 5 (CurCoordSys == #hybrid): StatusBar.Coord.selection = 6 (CurCoordSys == #gimbal): StatusBar.Coord.selection = 7 (CurCoordSys == #grid): StatusBar.Coord.selection = 8 ) ) 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 DisableCon = (StatusBar.xSpin.controller = undefined; StatusBar.ySpin.controller = undefined; StatusBar.zSpin.controller = undefined) fn AbMovSpin = (StatusBar.xSpin.controller = $.pos.X_Position.controller; StatusBar.ySpin.controller = $.pos.Y_Position.controller StatusBar.zSpin.controller = $.pos.Z_Position.controller) fn spinToZero = ( StatusBar.xSpin.value = 0 StatusBar.ySpin.value = 0 StatusBar.zSpin.value = 0 ) 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: (vertSel = undefined) 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 SelPos = ( local AvgVertPos = [0,0,0] local VertSel = VertArray() try ( 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 ) ) )catch(SpinOFF()) ) fn getPos = ( local AvgVertPos = [0,0,0] local VertSel = VertArray() if VertSel.count != 0 then ( 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 ) return (AvgVertPos / VertSel.count) ) ) fn moveX newVal = ( case subObjectLevel of ( 0:( ) 1: move $.selectedVerts [newVal,0,0] 2: move $.selectedEdges [newVal,0,0] 3: move $.selectedEdges [newVal,0,0] 4: move $.selectedFaces [newVal,0,0] 5: move $.selectedFaces [newVal,0,0] ) ) fn moveY newVal = ( case subObjectLevel of ( 0:( ) 1: move $.selectedVerts [0,newVal,0] 2: move $.selectedEdges [0,newVal,0] 3: move $.selectedEdges [0,newVal,0] 4: move $.selectedFaces [0,newVal,0] 5: move $.selectedFaces [0,newVal,0] ) ) fn moveZ newVal = ( case subObjectLevel of ( 0:( ) 1: move $.selectedVerts [0,0,newVal] 2: move $.selectedEdges [0,0,newVal] 3: move $.selectedEdges [0,0,newVal] 4: move $.selectedFaces [0,0,newVal] 5: move $.selectedFaces [0,0,newVal] ) ) rollout StatusBar "" ( local xOff = 40 local btnW = 24 local btnSmlW = 16 local btnYoff = -29 local btnRoff = -31 local spnYoff = -21 local drpYoff = -27 local isspinnerX = false local firstundoX = false local isspinnerY = false local firstundoY = false local isspinnerZ = false local firstundoZ = false button openBack "Autoback" height:btnW width: 55 align: #left offset: [0,-2] --across:50 --offset:[-300,0] button opentrack "Trackbar" height:btnW width: 55 align: #left offset: [55,btnYoff] --across:50 --offset:[-300,0] button soulBurn "Soulburn" height:btnW width: 55 align: #left offset: [110,btnYoff] --across:50 --offset:[-300,0] --button mLoop "M-Loop" height:btnW width: 45 align: #left offset: [220,btnYoff] --across:50 --offset:[-300,0] --button mRing "M-Ring" height:btnW width: 45 align: #left offset: [265,btnYoff] --across:50 --offset:[-300,0] button openTTI "" height:btnSmlW width:btnSmlW align: #center offset: [-170,spnYoff-2] --images: #("Maintoolbar_24i.bmp","Maintoolbar_24a.bmp", 104, 21, 21, 21, 21) checkbutton offset "A" height:btnSmlW width:btnSmlW align: #center offset: [-153,spnYoff] --across:3 --pos: [20+xOff,4] Spinner xSpin "" width: 75 Range:[-100000, 100000,0] align: #center offset: [-105,spnYoff] --scale: ScaleAmt pos: [20+xOff,4] Spinner ySpin "" width: 75 Range:[-100000, 100000,0] align: #center offset: [-30,spnYoff]--align: #centre --scale: ScaleAmt pos: [95+xOff,4] Spinner zSpin "" width: 75 Range:[-100000, 100000,0] align: #center offset: [45,spnYoff] --align: #centre --scale: ScaleAmt pos: [170+xOff,4] dropdownList Coord "" width: 65 align: #center offset: [150,drpYoff+3] items:#("World", "Parent", "Screen", "Local", "Working", "View", "Gimbal", "Grid") 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) button MxsList "Listener" height:btnW width:55 align: #right offset: [-40,btnYoff] --images: #("Maxscript_24i.bmp","Maxscript_24i.bmp", 5, 1, 1, 1, 1) button MxsEdit "Editor" height:btnW width:45 align: #right offset: [-95,btnYoff] --images: #("Maxscript_24i.bmp","Maxscript_24a.bmp", 5, 2, 2, 2, 2) button MxsRun "Run" height:btnW width:35 align: #right offset: [-140,btnYoff] --images: #("Maxscript_24i.bmp","Maxscript_24a.bmp", 5, 3, 3, 3, 3) --button fenceMarq "Fence" width:40 height:btnW align: #right offset: [-220,btnYoff] --button sprayMarq "Spray" width:40 height:btnW align: #right offset: [-260,btnYoff] --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) --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) -------------------------------------------------------------------EVENTS------------------------------------------------------------------------------------------------ on openBack pressed do try(macros.run "Zorb Tools" "ABLoader")catch() on openTrack pressed do try(macros.run "Kyle" "TrackbarToggle")catch() on soulBurn pressed do try(macros.run "SoulburnScripts" "soulburnScriptsListerUI")catch() on mRing pressed do try(macros.run "miauusScriptPack_vol2" "macroSP_vol2_SmartRingDotSelection_UI")catch() on mLoop pressed do try(macros.run "miauusScriptPack_vol2" "macroSP_vol2_SmartLoopDotSelection_UI")catch() on openTTI pressed do actionMan.executeAction 0 "40093" on offset changed val do ( if val == true then (DisableCon(); offset.text = "O"; spinToZero()) else if subObjectlevel == 0 then (offset.text = "A"; AbMovSpin()) else (offset.text = "A"; SelPos()) ) -------------------------------------------------------------------XSPIN EVENTS------------------------------------------------------------------------------------------------ on xspin buttondown do (isspinnerX = true; firstundoX = true; SubobjMoveCall = undefined; gc light:true; oldXspinVal = xspin.value) on xspin changed val isSpin do ( if isSpin == true then ( local useundoX = (isspinnerX and firstundoX) or (not isspinnerX) undo "changedxSpin" useundoX ( newVal = -oldXspinVal + xspin.value oldXspinVal = newVal + oldXspinVal moveX newVal ) firstundoX = false ) else() ) on xSpin entered spinArg cancelArg do ( if spinArg != true and cancelArg != true then ( local useundoX = (isspinnerX and firstundoX) or (not isspinnerX) undo "changedxEnter" useundoX ( if offset.state == true then (moveX xSpin.value; xSpin.value = 0) else moveX -((getPos()).x - xSpin.value ) ) firstundoX = false ) else ( if offset.state != true then ( local useundoX = (isspinnerX and firstundoX) or (not isspinnerX) undo "changedxEnter2" useundoX ( newVal = -oldXspinVal + xspin.value oldXspinVal = newVal + oldXspinVal moveX newVal ) firstundoX = false ) ) ) on xspin buttonup do ( isspinnerX = false; if offset.state == true then xSpin.value = 0 SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen ) -------------------------------------------------------------------YSPIN EVENTS------------------------------------------------------------------------------------------------ on ySpin buttondown do (isspinnerY = true; firstundoY = true; SubobjMoveCall = undefined; gc light:true; oldySpinVal = ySpin.value) on ySpin changed val isSpin do ( if isSpin == true then ( local useundoY = (isspinnerY and firstundoY) or (not isspinnerY) undo "changedySpin" useundoY ( newVal = -oldySpinVal + ySpin.value oldySpinVal = newVal + oldySpinVal moveY newVal ) firstundoY = false ) else() ) on ySpin entered spinArg cancelArg do ( if spinArg != true and cancelArg != true then ( local useundoY = (isspinnerY and firstundoY) or (not isspinnerY) undo "changedyEnter" useundoY ( if offset.state == true then (moveY ySpin.value; ySpin.value = 0) else moveY -((getPos()).y - ySpin.value ) ) firstundoY = false ) else ( if offset.state != true then ( local useundoY = (isspinnerY and firstundoY) or (not isspinnerY) undo "changedyEnter2" useundoY ( newVal = -oldySpinVal + ySpin.value oldySpinVal = newVal + oldySpinVal moveY newVal ) firstundoY = false ) ) ) on ySpin buttonup do ( isspinnerY = false; if offset.state == true then ySpin.value = 0 SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen ) -------------------------------------------------------------------ZSPIN EVENTS------------------------------------------------------------------------------------------------ on zSpin buttondown do (isspinnerZ = true; firstundoZ = true; SubobjMoveCall = undefined; gc light:true; oldzSpinVal = zSpin.value) on zSpin changed val isSpin do ( if isSpin == true then ( local useundoZ = (isspinnerZ and firstundoZ) or (not isspinnerZ) undo "changedzSpin" useundoZ ( newVal = -oldzSpinVal + zSpin.value oldzSpinVal = newVal + oldzSpinVal moveZ newVal ) firstundoZ = false ) else() ) on zSpin entered spinArg cancelArg do ( if spinArg != true and cancelArg != true then ( local useundoZ = (isspinnerZ and firstundoZ) or (not isspinnerZ) undo "changedzEnter" useundoZ ( if offset.state == true then (moveZ zSpin.value; zSpin.value = 0) else moveZ -((getPos()).z - zSpin.value ) ) firstundoZ = false ) else ( if offset.state != true then ( local useundoZ = (isspinnerZ and firstundoZ) or (not isspinnerZ) undo "changedzEnter2" useundoZ ( newVal = -oldzSpinVal + zSpin.value oldzSpinVal = newVal + oldzSpinVal moveZ newVal ) firstundoZ = false ) ) ) on zSpin buttonup do ( isspinnerZ = false; if offset.state == true then zSpin.value = 0 SubobjMoveCall = NodeEventCallback geometryChanged:SelCen subobjectSelectionChanged:SelCen ) on Coord selected i do ( case i of ( 1: toolMode.coordsys #world 2: toolMode.coordsys #parent 3: toolMode.coordsys #screen 4: toolMode.coordsys #local 5: toolMode.coordsys #working_pivot 6: toolMode.coordsys #view 7: toolMode.coordsys #gimbal 8: toolMode.coordsys #grid ) ) --on PPcenter pressed do toolMode.pivotCenter() on squareMarq pressed do actionMan.executeAction 0 "59232" on sprayMarq pressed do actionMan.executeAction 0 "59236" on fenceMarq pressed do actionMan.executeAction 0 "59234" on MxsHelp pressed do actionMan.executeAction 0 "40366" on MxsList pressed do actionMan.executeAction 0 "40472" on MxsEdit pressed do actionMan.executeAction 0 "40839" on MxsRun pressed do actionMan.executeAction 0 "40470" on statusBar open do ( callbacks.addscript #spacemodeChange "GetCoordSys()" id:#CoordSysCallback SelPos() ) on statusBar closed do ( callbacks.removeScripts #spacemodeChange id:#CoordSysCallback ) ) createdialog StatusBar width:1423 height:30 pos:[303,sysInfo.desktopSize.y-65] style:#(#style_border) )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() )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.
In my next post is the final script.
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.