Home 3D Art Showcase & Critiques

Kevin Bryant - Maxscript thread

polycounter lvl 5
Offline / Send Message
Narlyteeth polycounter lvl 5
Hello, I made this thread to learn a few things about max script. I'm still very new to this and I don't expect to be pro at this anytime, but I just want to make scripts that just makes things easier for me. that includes Clean, and easy UI for the most part.


Here is what my UI looks like.
most of the toolbars are things like primitives, and the most common actions I use from the graphite toolbar(the Ribbon is redundant UI and hogs screenspace, but there are some functions that I use from it). then I also have buttons that toggle the timeslider, trackbar, and status bar independently. My command Panel is on my second monitor.
maxui201300.jpg

but the thing that actually required scripting are the transform spinners on the bottom. I just started getting in to maxscripting a couple days ago, and these spinners are what I have working so far to some extent.

here is my code for the spinners.
rollout Tformspinners "TformSpinners" width:640
(
label Movelabel "Move" pos:[0,0] width:32

spinner    MoveX "X" range: [-1000000,1000000,0] pos:[40,0] width:70
spinner    MoveY "Y" range: [-1000000,1000000,0] pos:[120,0] width:70
spinner    MoveZ "Z" range: [-1000000,1000000,0] pos:[200,0] width:70

label Rotlabel "Rotate" pos:[285,0] width:32
    
spinner    RotX "X" range: [-1000000,1000000,0] pos:[330,0] width:70
spinner    RotY "Y" range: [-1000000,1000000,0] pos:[410,0] width:70
spinner    RotZ "Z" range: [-1000000,1000000,0] pos:[490,0] width:70    
)
createdialog Tformspinners
cui.RegisterDialogBar Tformspinners
cui.DockDialogBar Tformspinners #cui_dock_bottom 

fn Refresh_controllers =
(
meshes = $

if meshes != undefined and meshes != $selection do 
(
Tformspinners.MoveX.controller = ($.pos.controller.x_position.controller)
Tformspinners.MoveY.controller = ($.pos.controller.y_position.controller)
Tformspinners.MoveZ.controller = ($.pos.controller.z_position.controller)

Tformspinners.RotX.controller = ($.rotation.controller.x_rotation.controller)
Tformspinners.RotY.controller = ($.rotation.controller.y_rotation.controller)
Tformspinners.RotZ.controller = ($.rotation.controller.z_rotation.controller)     
)

)
callbacks.addscript #selectionSetChanged "Refresh_controllers()" id:#callbackIDs


 
on Tformspinners close do
(    
callbacks.removescripts #selectionSetChanged id:#callbackIDs    
)


Like I said, I'm still new to this so anyone more intermediate with maxscript, let me know if I'm doing things efficiently or not.

I would like to point out that I have this script as a startup, for the most part it works fine for me, but I do get the error "--Type error: Call needs function or class, got: true" I guess it's not reading my callback function at first, but after that message, everything is fine. I would still like to know how to prevent this popup. on startup.

as for now, my spinner don't work with groups or multiple selections (I if'd those out for now) but later on, I would like to be able to use the spinners on multiple selections based on pivot modes.

Replies

  • Narlyteeth
    Options
    Offline / Send Message
    Narlyteeth polycounter lvl 5
    it also appears that the spinners don't affect the pivots only when in pivot mode. I'll look more into that when I get time.
  • Swordslayer
    Options
    Offline / Send Message
    Swordslayer interpolator
    Hi, interesting concept. First of all, referencing controllers like this will only get you so far, quite often when working with rigs (and constrained stuff) you will stumble upon List controllers, TCB controllers, thins like Bezier Position etc. Second, a nitpick, you can replace meshes != undefined and meshes != $selection with selection.count == 1. Btw. did you notice the close event handler is actually outside the rollout scope? Guess it's just a result of a hasty cleanup :) Anyway, here's how I would tackle it (incomplete, just a proof of concept):
    rollout Tformspinners "TformSpinners" width:280
    (
        label Movelabel "Move" pos:[0,0] width:32
        spinner MoveX "X" range: [-1e6,1e6,0] pos:[40,0] width:70
        spinner MoveY "Y" range: [-1e6,1e6,0] pos:[120,0] width:70
        spinner MoveZ "Z" range: [-1e6,1e6,0] pos:[200,0] width:70
    
        fn redefineTransformHandlers sel =
        (
            deleteAllChangeHandlers id:#typeInTransform
            if sel.count == 1 do
            (
                when transform $ changes id:#typeInTransform handleAt:#redrawViews do
                (
                    MoveX.value = $.pos.x
                    MoveY.value = $.pos.y
                    MoveZ.value = $.pos.z
                  )
            )
        )
    
        on Tformspinners open do
        (
            callbacks.removescripts id:#typeInTransform
            callbacks.addScript #selectionSetChanged  "Tformspinners.redefineTransformHandlers selection" id:#typeInTransform 
        )
        
        on MoveX changed val do
            if selection.count == 1 do selection[1].pos.x = val
    
        on MoveY changed val do
            if selection.count == 1 do selection[1].pos.y = val
    
        on MoveZ changed val do
            if selection.count == 1 do selection[1].pos.z = val
        
        on Tformspinners close do
            callbacks.removescripts id:#typeInTransform
    )
    createDialog Tformspinners
    
  • Narlyteeth
    Options
    Offline / Send Message
    Narlyteeth polycounter lvl 5
    Thank you very much for the tips. I didn't know it was better to have the called function inside the rollout's scope. "selection.count == 1" is more comprehensive than what I had. and I'll make sure not to only define controllers.

    :thumbup:
  • Swordslayer
    Options
    Offline / Send Message
    Swordslayer interpolator
    Nothing much to thank for, really. Sometimes it's better, sometimes not, here it's more for simplicity's sake. As for manipulating pivots, I would probably just make a checkbutton for that - I think there's some global or function returning if you are currently in Affect Pivot Only mode, but a simple checkButton should be enough (if checked, $.pos.x will instead be $.pivot.x and so on). Same for world/local coordinates and coordsys pivot vs world, for example. To extend it for multiple nodes, look at about context and coordsys context, too, if you haven't already.
  • Pedro Amorim
    Options
    Offline / Send Message
    How are you attaching the rollout to the interface?
Sign In or Register to comment.