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;
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

  • haiddasalami
    Options
    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.
    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 TFB
    
  • Revel
    Options
    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
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Edit:Whoops :P
    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 TFB
    

    This should work. Think my max just bugged out :/
  • Revel
    Options
    Offline / Send Message
    Revel interpolator
    Alright! thanks so much haiddasalami! Now all 3 works as expected :D
  • Revel
    Options
    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
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Look up matchPattern. Example:

    matchPattern "ASD BSD" pattern:"ASD*"
  • Revel
    Options
    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
    Options
    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;
    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?
  • miauu
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    This works for me, except that when in Uniform Scale the script prints non uniform
    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")
                    )
                )
    
  • Revel
    Options
    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;
    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_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
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    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
    Options
    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
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    Why do you need a custom TTI?
  • Revel
    Options
    Offline / Send Message
    Revel interpolator
    For my custom UI :)

    hpHkKG9.jpg
  • miauu
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    I think that the best way is to find a way(if it is possible) to rearange the controls in the default TTI. :)
  • Revel
    Options
    Offline / Send Message
    Revel interpolator
    Eh? and the question is; is it possible to re-arrage the default TTI? haha :)
  • kman108
    Options
    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.
    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()
    )
    
    
  • Pedro Amorim
    Options
    Offline / Send Message
    Yeah, would like to get a custom coordinates toolbar for myself as well. :)
    Mgkg1Af.png
  • miauu
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    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
    Options
    Offline / Send Message
    Will it wor for 2012?
  • Revel
    Options
    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
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    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
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    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
    Options
    Offline / Send Message
    very nice! Is it dockable to the toolbar?
  • miauu
    Options
    Offline / Send Message
    miauu polycounter lvl 14
    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.