Home 3D Art Showcase & Critiques

Jeremiah Bigley - Maxscript Adventures

polycounter lvl 12
Offline / Send Message
jeremiah_bigley polycounter lvl 12
I finally decided to take the jump into maxscript like I have said I wanted to for the past 4 years. I have been at it for about a week now and I am loving it. I figured I would post a progress thread of a little bit different flavor and share my "sketches" and WIPs that I come up with.

Maybe it will keep me from creating bad coding habbits/help be more efficient.
Feel free to take/expand/suggest anything I post here.

I am a modeler so my focus will be toward making my workflows for modeling faster, easier and more efficient.


This is one of my first little things playing around with. Playing with one of my first variables and for loops.
Didn't realize how easy it was to create a variable. And crazy how powerful it can be. Being able to take your current selection and make it a variable.

This code will take your current selection and move each object randomly on each axis between -100 and 100 relative units.
macroScript Bigley_MoveThisRandomly
category:"Bigley"

(
    this = $
    for i in this do (
    move i [random -100 100, random -100 100, random -100 100])
)

Replies

  • A-N-P
    Options
    Offline / Send Message
    A-N-P polycounter lvl 6
    I'll be following this closely as I've also recently jumped into a bit of maxscript (particularly at work). All I can say right now is nice start. Looking forward to seeing more :D
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    These are a bit old but they are very beginner level so I figured I would post them now. I get tired of creating certain primitives and zeroing out all the height segments and making them square... I bind these to Alt+number.

    Creates perfect box at origin with no segments.
    macroScript QuickBox
        category:"Bigley"
    (
        Box lengthsegs:1 widthsegs:1 heightsegs:1 length:50 width:50 height:50 mapcoords:on pos:[0,0,0] isSelected:on
    )
    

    Creates an 8 sided cylinder at origin with no segments.
    macroScript QuickCylinder
        category:"Bigley"
    (
        Cylinder smooth:on heightsegs:1 capsegs:1 sides:8 height:100 radius:25 mapcoords:on isSelected:on
    )
    
    

    Creates a perfect plane at origin with no segments.
    macroScript QuickPlane
        category:"Bigley"
    
    (
        Plane length:125 width:125 lengthsegs:1 widthsegs:1 pos:[0,0,0] isSelected:on
    )
    
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Thanks A-N-P! :D

    So I sorta took upon myself to make a script to speed my friend up. It was originally going to be a turbosmooth toggle but it expanded from there. Here was what my early tests were just to figure out some of the properties and functions.

    This one turns the turbosmooth modifier off.
    macroScript Bigley_Turbosmooth_OFF
    category:"Bigley"
    
    (    
        these = $
        for i in these do(
            i.modifiers[#turbosmooth].enabled = off
        )
    )
    
    This one turns the turbosmooth modifier on.
    macroScript Bigley_Turbosmooth_ON
    category:"Bigley"
    
    (
        these = $
        for i in these do(
            i.modifiers[#turbosmooth].enabled = on
        )
    )
    
    I hadn't figured out how to test and see if the objects had the modifier on it yet... I made a facebook status asking a couple of questions and Juan Martinez (monsterblues) came to the recue and helped me with the isProperty function. Which checks to see if a certain property is on an object and will return a true or false.

    Then... I had to crunch a bit at work. D: So I wasn't able to make it back to the script for a whole week.
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    I was able to get back to it last night... and I made the toggle.

    This will toggle the turbosmooths in a selection on or off
    for i in $ do
                if isproperty i #turbosmooth == true do
                    if i.modifiers[#turbosmooth].enabled == on
                    then
                        i.modifiers[#turbosmooth].enabled = off
                    else
                        i.modifiers[#turbosmooth].enabled = on
    
    The script evolved though... because there was an inherent problem with this script. If you grab 2 objects, both with a turbosmooth, but one is off and the other is on... it would just flip flop the modifiers. How lame.
    So... I came up with this.



    WIP Name: Bigley Uber Turbo Toggle
    What it does:

    • Nothing Pressed - Toggles turbosmooths on all geometry in the scene.
    • CTRL - Turns all turbosmooths on.
    • ALT - Turns all turbosmooths off.
    • SHIFT - Adds a turbosmooth modifier to objects that don't have one.
    If you run each of these on a selection it will apply to the selection. If you run it on no selection it will apply to all geometry in the scene.
    wincon = dotnetclass "system.windows.forms.control"
    obj = $
    
    if wincon.modifierKeys == wincon.modifierkeys.none do
        if $ == undefined 
        then
            for i in geometry do
                if isproperty i #turbosmooth == true do
                    if i.modifiers[#turbosmooth].enabled == off
                    then
                        i.modifiers[#turbosmooth].enabled = on
                    else
                        i.modifiers[#turbosmooth].enabled = off
    
        else
            for i in obj do
                if isproperty i #turbosmooth ==true do
                    if i.modifiers[#turbosmooth].enabled == off
                    then
                        i.modifiers[#turbosmooth].enabled = on
                    else
                        i.modifiers[#turbosmooth].enabled = off
    
    ---------------------------------------------------------------------------------
    
    if wincon.modifierKeys == wincon.modifierkeys.control do -- if holding CTRL
        if $ == undefined
        then
            for i in geometry do
                if isproperty i #turbosmooth == true do
                    i.modifiers[#turbosmooth].enabled = on
        else
            for i in obj do
                if isproperty i #turbosmooth == true do
                    i.modifiers[#turbosmooth].enabled = on
    
    ---------------------------------------------------------------------------------
    
    if wincon.modifierkeys == wincon.modifierkeys.alt do -- if holding ALT
        if $ == undefined
        then
            for i in geometry do
                if isproperty i #turbosmooth == true do
                    i.modifiers[#turbosmooth].enabled = off 
        else
            for i in obj do
                if isproperty i #turbosmooth == true do
                    i.modifiers[#turbosmooth].enabled = off 
    
    ---------------------------------------------------------------------------------
                
    if wincon.modifierkeys == wincon.modifierkeys.shift do -- if holding SHIFT
        if $ == undefined
        then
            for i in geometry do
                if isproperty i #turbosmooth == false do
                    addmodifier i (turbosmooth())    
        else
            for i in obj do
                if isproperty i #turbosmooth == false do
                    addmodifier i (turbosmooth())
    
    ---------------------------------------------------------------------------------
    
    completeredraw()
    
    
    I am not happy with it yet... I still want to add a delete function and probably some up and down iterations. And ideally it would apply to meshsmooth and turbosmooth. But... one step at a time.

    For this I had looked around on the internet for how to do something based on a pressed key and it led me to some dotnet framework code. I am at a little bit of a roadblock as of now because I don't know how to check and see if multiple modifier keys are pressed. I have a thread here asking.
  • The Flying Monk
    Options
    Offline / Send Message
    The Flying Monk polycounter lvl 18
    these = $
    for i in these do(

    This will cause an error if you only have one object selected and posibly if you have nothing selected when you run the script.

    With only one object selected $ returns a single object. But with multiple objects selected it returns an array.

    In these cases its better to use 'selection'
    This always returns an array, even with no objects selected.

    It would be better to have:

    if selection.count != 0 then
    (
    ...

    But since your script starts with a for loop you don't realy need that. But its always a good idea to think about how other artists are goin to use your script. And all the things they could posibly do to break it.
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Using $ does return undefined if you have nothing selected. However as long as there is at least 1 object in your selection when you use $ it doesn't give you an error as you still have something to apply the functions to.

    Nice to know that when you use "selection" it will run the script anyways. Thanks for that! :D


    Working one weekend at a time here... Was able to get a bit of time in on this script and finish it. Took out all of the .net framework because Perna and Bryan Cavett pointed out that I could use the keyboard. class in max. Let me know what you guys think or if you modelers out there find it useful. And let me know if I need to make a macro out of it for anyone... my intention was for it to be run from a button. I am just too tired to do it right now. :P

    Name:
    Bigley_Smart_TurboToggle
    What it does:

    • Nothing Pressed - Adds a turbosmooth modifier only to the objects that don't have one in your selection.
    • CTRL - Turns all turbosmooths on.
    • ALT - Turns all turbosmooths off.
    • SHIFT - Toggles turbosmooths on all geometry in the scene
    • CTRL + SHIFT - Goes up 1 iteration to a maximum of 3
    • CTL + ALT - Goes down 1 iteration to a minimum of 0
    • ALT + SHIFT - Turns isoline display to false and collapses model to EditablePoly
    • CTRL + ALT + SHIFT - Deletes the turbosmooths off the objects from anywhere in the stack.
    If you run each of these on a selection it will apply to the selection. If you run it on no selection it will apply to all geometry in the scene.
    macroScript Bigley_Smart_TurboToggle
        category:"Bigley"
        toolTip:"Bigley_Smart_TurboToggle"
        
    (
        fn bigley_modKey =
        (
            case of
            (
                (keyboard.controlPressed and not keyboard.shiftPressed and not keyboard.altPressed):
                        return #ctrl
                
                (keyboard.altPressed and not keyboard.controlPressed and not keyboard.shiftPressed):
                        return #alt
                
                (keyboard.shiftPressed and not keyboard.controlPressed and not keyboard.altPressed):
                        return #shift
                
                (keyboard.altPressed and keyboard.controlPressed and not keyboard.shiftPressed):
                        return #ctrl_alt
                
                (keyboard.shiftPressed and keyboard.controlPressed and not keyboard.altPressed):
                        return #ctrl_shift
    
                (keyboard.shiftPressed and keyboard.altPressed and not keyboard.controlPressed):
                        return #alt_shift
    
                (keyboard.shiftPressed and keyboard.altPressed and keyboard.controlPressed):
                        return #ctrl_shift_alt
                
                default: return #none
            )
        )
    
        fn selection_check =
        (
            case of
            (
                ($ == undefined):
                    return #nothing_selected
                
                ($ != undefined):
                    return #something_selected
            )
        )
    
        -- Start of Main Code ------------------------------------------------
    
        case selection_check() of
        (
            #nothing_selected:
                
                case bigley_modkey() of
                (
                    #none: messagebox "To add a turbosmooth modifier you need a selection."
                    #ctrl: for i in geometry do
                                if isproperty i #turbosmooth == true do
                                    i.modifiers[#turbosmooth].enabled = on
                    #alt: for i in geometry do
                                if isproperty i #turbosmooth == true do
                                    i.modifiers[#turbosmooth].enabled = off
                    #shift: for i in geometry do
                                if isproperty i #turbosmooth == true do
                                    if i.modifiers[#turbosmooth].enabled == off
                                    then
                                        i.modifiers[#turbosmooth].enabled = on
                                    else
                                        i.modifiers[#turbosmooth].enabled = off
                    #ctrl_shift: for i in geometry do
                                        if isproperty i #turbosmooth == true do
                                            if i.modifiers[#turbosmooth].iterations >= 3
                                            then i.modifiers[#turbosmooth].iterations += 0
                                            else i.modifiers[#turbosmooth].iterations += 1
                    #ctrl_alt: for i in geometry do
                                    if isproperty i #turbosmooth == true do
                                        if i.modifiers[#turbosmooth].iterations > 0
                                        do i.modifiers[#turbosmooth].iterations -= 1
                    #ctrl_shift_alt: for i in geometry do
                                            if isproperty i #turbosmooth do
                                                deletemodifier i i.modifiers[#turbosmooth]
                    #alt_shift: for i in geometry do
                                        if isproperty i #turbosmooth == true do(
                                            i.modifiers[#turbosmooth].isolinedisplay = false
                                            convertTo i PolyMeshObject
                                        )
                )        
    
            
            #something_selected:
            
                case bigley_modkey() of
                (
                    #none: for i in selection do
                                if isproperty i #turbosmooth == false do
                                    addmodifier i (turbosmooth isolinedisplay: true)
                    #ctrl: for i in selection do
                                if isproperty i #turbosmooth == true do
                                    i.modifiers[#turbosmooth].enabled = on
                    #alt: for i in selection do
                                if isproperty i #turbosmooth == true do
                                    i.modifiers[#turbosmooth].enabled = off
                    #shift: for i in selection do
                        if isproperty i #turbosmooth == true do
                            if i.modifiers[#turbosmooth].enabled == off
                            then
                                i.modifiers[#turbosmooth].enabled = on
                            else 
                                i.modifiers[#turbosmooth].enabled = off
                    #ctrl_shift: for i in selection do
                            if isproperty i #turbosmooth == true do
                                if i.modifiers[#turbosmooth].iterations >= 3
                                then i.modifiers[#turbosmooth].iterations += 0
                                else i.modifiers[#turbosmooth].iterations += 1
                    #ctrl_alt: for i in selection do
                                    if isproperty i #turbosmooth == true do
                                        if i.modifiers[#turbosmooth].iterations > 0 do
                                            i.modifiers[#turbosmooth].iterations -= 1
                    #ctrl_shift_alt: for i in selection do
                                            if isproperty i #turbosmooth do
                                                deletemodifier i i.modifiers[#turbosmooth]
                    #alt_shift: for i in selection do
                                        if isproperty i #turbosmooth == true do(
                                            i.modifiers[#turbosmooth].isolinedisplay = false
                                            convertTo i PolyMeshObject
                                        )
                )
        )
    
        completeredraw()
    )
    
    
  • aajohnny
    Options
    Offline / Send Message
    aajohnny polycounter lvl 13
    Awesome stuff man! I can't wait to use these. Keep it up.
  • FistOfVegetables
    Cool beans man, I could definitely see how that would be useful. Keep up the good work!
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    Another fun thing with FOR loops is the WHERE keyword:
    #alt_shift:
      for i in geometry WHERE isproperty i #turbosmooth == true do (
        i.modifiers[#turbosmooth].isolinedisplay = false
        convertTo i PolyMeshObject
      )
    
  • Novian
    Options
    Offline / Send Message
    Novian polycounter lvl 5
    How did I miss this thread!?

    Jeremiah,

    Awesome stuff man. I'm going to "borrow" some of those to increase my workflow speed. ;)

    Now I have to dust off the maxscript stuff I was doing and get back into it as well.

    I'll sub now and let you know if I find out anything neat to share.

    Cheers~

    Well done sir!
  • Swordslayer
    Options
    Offline / Send Message
    Swordslayer interpolator
    Nice to see another maxscript user :) Just a few notes if you don't mind:

    1. You can drop the == true test everywhere, (true == true returns true anyway so there's no point in doing that; you've already done that in one case, see #ctrl_shift_alt: section) and as LoTekK already mentioned, for loops with single if branch can be replaced with for .. where expression:
    #shift: for i in selection
        where isproperty i #turbosmooth do
            i.modifiers[#turbosmooth].enabled = NOT i.modifiers[#turbosmooth].enabled
    
    #ctrl_shift: for i in selection
        where isproperty i #turbosmooth AND i.modifiers[#turbosmooth].iterations < 3 do
            i.modifiers[#turbosmooth].iterations += 1
    

    2. To further simplify it, try not to repeat yourself - both those code blocks (nothing selected vs. something selected) are basically the same, the only difference being selection vs. geometry - you can make a function of it and pass one variable containing the appropriate collection:
    fn doAllTheStuff objs =
    ...
    #nothing_selected: doAllTheStuff geometry
    

    3. In the macroscript body, bigley_modKey, selection_check (and something along the lines of doAllTheStuff) functions need to be evaluated only once, so it's better if you provide on execute context - without it, everything gets evaluated every time. Basically, the main code belongs there.

    4. As for the very first post, notice that you can pass point3 values to random:
    move i random [-100,-100,-100] [100,100,100]
    

    Happy scripting! :)
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Thanks for all of the feedback guys! I will be revising that turbosmooth script within the next couple of weeks sometime. When everyone started giving me feedback and critiques... I borderline had no clue what people were talking about. lol...

    So over the weekend I poured over more tutorials and a lot of what everyone is saying makes sense. So in due time... :D

    Until then... I made a simple script that I have been needing for a while while I work. I don't use layers (yes I know... shame.) It just seems slow and clunky to me. So my workflow has adopted color coding my highpolys by one material and my lowpolys by another material (obviously I don't work with super large scenes very often). Frequently I need to pull a selection by the material and it is annoying having to go into the material editor to hit the button select by material AND THEN have to hit okay. What I wanted was a script that would read the material on the current object and select all the other objects with the same material.

    So here it is.

    Name: Bigley_ObjectbyMaterial
    What it does: Reads the current object's material and selects all other objects with the same material.
    Notes: Not error proof. Errors when object has no material. Might need to add wirecolor functionality.
    macroScript Bigley_ObjectbyMaterial
        category:"Bigley"
        toolTip:"Bigley_ObjectbyMaterial"
    (
        if $ != undefined then(
        MaterialTest = $.material.name
        ObjectbyMaterial = for i in objects where i.material.name == MaterialTest collect i
        select ObjectbyMaterial)
        else(print "Nothing Selected.")
    )
    
    
  • cptSwing
    Options
    Offline / Send Message
    cptSwing polycounter lvl 11
    I don't use layers (yes I know... shame.) It just seems slow and clunky to me.

    Just an OT comment: Use PJanssen's Outliner script. You won't want to miss it ever again.
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    Notes: Not error proof. Errors when object has no material. Might need to add wirecolor functionality.
    if $ != undefined then(
    
    try
    if $ != undefined AND $.material != undefined then(
    

    You could also split up your if statement so you can have more specific error messages (eg. "Nothing Selected", "Selected object has no material").
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    cptSwing wrote: »
    Just an OT comment: Use PJanssen's Outliner script. You won't want to miss it ever again.

    Yeah I have used it before... It never stuck. It is nice for large scenes...

    LoTekK - I tried the and where like you suggested but it created some other problems... The MaterialTest variable stays undefined because it is in the THEN statement. I can declare it ahead of everything and give it any value and the script works... but this seems kinda a lame work around.
        MaterialTest = "Temp_Assignment"
    
            case bigley_modKey() of
        (
            #none:   if $ != undefined and MaterialTest != undefined  then(
                        local MaterialTest = $.material.name
                        ObjectbyMaterial = for i in objects where i.material.name == MaterialTest collect i
                        select ObjectbyMaterial)
                        else(print "Nothing Selected.")
       )
    
    Any help would greatly be appreciated. :)


    Oh and has anyone ever had issues with Max not running lines of code when you hit the numpad enter? It was also treating my lines of code like they were the last code I typed. For example I was showing a friend an if statement that would create a plane. And the code wasn't executing... so I changed it from creating a plane to moving the current selection... and when I got it to execute it created the plane! Even though my code said move selection. It just seemed like it was being buggy.

    Edit: I think I figured it out...
            case bigley_modKey() of
        (
            #none:   if $ != undefined then(
                            MaterialTest = $.material.name
                            ObjectbyMaterial = for i in objects where i.material.name == MaterialTest collect i
                            select ObjectbyMaterial)
                            else(print "Nothing Selected.")
    
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    I can declare it ahead of everything and give it any value and the script works... but this seems kinda a lame work around.
    Actually there's no shame in predeclaring a variable. In fact in stricter languages, this might be what you'd be required to do anyway. Mind, predeclaring doesn't require you to assign a value to the variable.
    local someVariable  --this just initialises the variable for use
    if someCondition then
    (
      someVariable = someValue
    )
    else
    (
      someVariable = anotherValue
    )
    print someVariable
    
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Thank you LoteKk! I think I finally managed to get this thing error proof so I am posting the full script.



    Name: Bigley_Smart_Material
    What it does:

    -- When run it creates 3 materials in the Material Editor that I use on a regular basis
    • Nothing Pressed - Reads material from current selection and selects all other unhidded objects that share that material.
    • CTRL - Applies Material Editor Slot 1
    • ALT - Applies Material Editor Slot 3
    • SHIFT - Applies Material Editor Slot 2
    macroScript Bigley_Smart_Material
        category:"Bigley"
        toolTip:"Bigley_Smart_Material"
    ( 
        -- Define Functions
        fn bigley_modKey =
        (
            case of
            (
                (keyboard.controlPressed and not keyboard.shiftPressed and not keyboard.altPressed):
                        return #ctrl
                (keyboard.altPressed and not keyboard.controlPressed and not keyboard.shiftPressed):
                        return #alt
                (keyboard.shiftPressed and not keyboard.controlPressed and not keyboard.altPressed):
                        return #shift
                (keyboard.altPressed and keyboard.controlPressed and not keyboard.shiftPressed):
                        return #ctrl_alt
                (keyboard.shiftPressed and keyboard.controlPressed and not keyboard.altPressed):
                        return #ctrl_shift
                (keyboard.shiftPressed and keyboard.altPressed and not keyboard.controlPressed):
                        return #alt_shift
                (keyboard.shiftPressed and keyboard.altPressed and keyboard.controlPressed):
                        return #ctrl_shift_alt
                default: return #none
            )
        )
        
        -- Material Slot 1 Creation
        meditMaterials[1].Name = "Highpoly_Clay"
        meditMaterials[1].Diffuse = color 128 128 128
        meditMaterials[1].Specular = color 251 245 236
        meditMaterials[1].SpecularLevel = 55
        meditMaterials[1].Glossiness = 20
        
        -- Material Slot 2 Creation
        meditMaterials[2].Name = "Lowpoly_Clay"
        meditMaterials[2].Diffuse = color 0 140 255
        meditMaterials[2].Specular = color 255 255 255
        meditMaterials[2].SpecularLevel = 20
        meditMaterials[2].Glossiness = 10
        meditMaterials[2].selfIllumAmount = 20
        
        -- Material Slot 3 Creation
        meditMaterials[3].Name = "Cage_Clay"
        meditMaterials[3].Diffuse = color 0 212 0
        meditMaterials[3].specularLevel = 20
        meditMaterials[3].glossiness = 10
        meditMaterials[3].opacity = 100
        meditMaterials[2].selfIllumAmount = 20
        
            case bigley_modKey() of
        (
            #none:   if $ != undefined and $.material != undefined then (
                            MaterialTest = selection[1].material.name
                            select (for i in objects where i.ishidden != true and
                                i.material != undefined and i.material.name == MaterialTest collect i))
                        else(print "Nothing selected/No material.")
            #ctrl:        if $ != undefined then ($.material = meditMaterials[1]
                            $.wirecolor = color 0 0 0)
                        else (select objects
                            $.material = meditMaterials[1]
                            $.wirecolor = color 0 0 0
                            deselect objects)
            #shift:    if $ != undefined then ($.material = meditMaterials[2]
                            $.wirecolor = color 0 0 0)
                        else (select objects
                            $.material = meditMaterials[2]
                            $.wirecolor = color 0 0 0
                            deselect objects)
            #alt:  if $ != undefined then ($.material = meditMaterials[3]
                        $.wirecolor = color 0 0 0)
                    else (select objects
                        $.material = meditMaterials[3]
                        $.wirecolor = color 0 0 0
                        deselect objects)
        )
    
        completeredraw()
        
    )
    
    
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    something else I did today... This was to condense a couple of buttons I made a while back. Originally I had a button to lock all transforms and a button to unlock all transforms.


    Name: Bigley_TransformLock_Toggle
    What it does:
    Toggles the transform locks on or off.
    macroScript Bigley_TransformLock_Toggle
        category:"Bigley"
        toolTip:"Bigley_TransformLock_Toggle"
        
    -- To Do:  Add "All on" Switch
    --            Add " All off" Switch
    
    (
        for o in selection do(
            TransformLockCheck = getTransformLockFlags o
            for i in 1 to 9 do (
                TransformLockCheck[i] = not TransformLockCheck[i])
            setTransformLockFlags o TransformLockCheck
    )
    )
    
    
    
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Got a question for you guys watching.

    Is it possible to make a script that executes when I CTRL+SHIFT+Mouse Click in editable poly?

    Something like this:
    If in editable poly and CTRL SHIFT Click do (
    _______________)

    or like this:
    while in editable poly if CTRL+SHIFT+CLICK do(
    ______________)
  • SimonT
    Options
    Offline / Send Message
    SimonT interpolator
    I guess you have to checkout call backs. Search for "General Event Callback Mechanism" in the help. It works like that: you write a function and register it to a callback. Max knows different callbacks like: #selectionSetChanged.

    The function you wrote is called every time you change the selection. In this function you could try to check which keys are hold currently, but i have no idea how this could work :D
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    thanks for the info SimonT! I went a little MIA there... got busy with work.

    Haven't had much time but I got to play around with this.

    What it does:
    It will jump to the current subobject level of the object you pick when you run it.
    Notes:
    Haven't had time to test it out really. Definitely not for production yet. :P Still some functionality I want to add like checking for Edit Poly Modifiers...
    lastSOL = subobjectlevel
    jump = pickobject()
    
    if classof jump.baseobject == Editable_Poly then(
    max create mode
    select jump
    max modify mode
    modPanel.setCurrentObject $.baseObject
    subobjectlevel = lastSOL)
    else print "Not an Editable Poly."
    

    Any feedback would be greatly appreciated. It is a little slow at the moment... I had hoped it would be just a bit faster. It is that dang modifier panel refreshing everytime you do something. I can only switch out for one of the refreshes because I need to be in the modifier panel to register the jump to baseObject and the change in Subobject Level.
  • cptSwing
    Options
    Offline / Send Message
    cptSwing polycounter lvl 11
    So basically you have object A selected, and say vertices. Now you select object B and it automatically goes to vertex subobjectmode, from what I can read?

    (hah, in the time I typed this, I could have just tested it)
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Wanted to give this a little update... Share my WIP. No code just a screenshot. I am making a sort of streamlined/master control for baking. When I am done I will put it up somewhere for download and hopefully people can get some use out of it.

    Bigley_Cast_Tools_01_zps113d7afb.jpg
  • Novian
    Options
    Offline / Send Message
    Novian polycounter lvl 5
    Jeremiah,

    You beat me to it! I've been working on a mass baker script for inside Max. Calling it the Bakery. Will auto align and back named pairs of models. Just working out how to check for a completed bake in order to trigger the next.

    Well done. Looking forward to it.

    Cheers~
  • ahosking
    Options
    Offline / Send Message
    Novian wrote: »
    Jeremiah,

    You beat me to it! I've been working on a mass baker script for inside Max. Calling it the Bakery. Will auto align and back named pairs of models. Just working out how to check for a completed bake in order to trigger the next.

    Well done. Looking forward to it.

    Cheers~
    I've done similar at work.
    Though these days the scripts send bakes to the farm, you can do a lot of things to trigger the next render.
    My go-to is to put a custom attribute on all models to be baked. When one is done, I change the attribute and re-scan until all models are done.
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Both you guys make mine sound pretty weak... it would currently only render one at a time. Haven't really thought about rendering more than one. I tend to switch renderers to render my AO so I kinda have to render them separately. Maybe... I haven't gotten there. lol :poly136:

    The main purpose of this was the Material ID buttons at the top. I don't like to explode... even with the most efficient ways I still hate it. I have always liked using the hit only matching material IDs option. However even that method is still slow.

    So these two buttons help me Setup Material IDs in almost 1.5 minutes flat. :D
    The rest of it was just extra to condense the baking task. Starting to wonder what I got myself into. RTT is so complicated.

    I will be sure to demo how it works when I get the script done. ;)

    Edit: Novian that really sounds cool. I would be interested in hearing how you are able to check for a completed bake when you get it down.
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Hey guys! I am pretty stuck. I am 95% there on this script and the padding is giving me an issue. Was hoping someone could help tell me why I am having this problem.

    Problem:
    After my first render, if I change the padding, it doesn't render out the new padding amount. I am not really sure why. It seemed to update in the render after I updated at least the save location and padding... sometimes.

    I am not clearing the bake elements because I would like to keep it there. Idea is to setup using predefined preset in the script, render, tweak some settings in it, and then render again.


    EDIT: So apparently the padding isn't the issue. It is actually just displaying the previous render. When I move my objects and rebake... nothing updates. I guess that means be.bitmap is not closing out?
    Why?

    global bp = $.INodeBakeProperties
    global prjp = $.INodeBakeProjProperties
    
    
    fn RTTBigleyCastTools Xsize Ysize channel padding fullfilename =
    (
        bp.bakeEnabled = true
        bp.bakeChannel = channel
        bp.ndilations = padding
    
        fPath = getFilenamePath fullfilename
        fName = getFilenameFile fullfilename
        fType = getFilenameType fullfilename
    
        be.outputSzX = Xsize
        be.outputSzY = Ysize
        be.filenameUnique = true
        be.filename = fName
        be.fileType = fType
    
        render rendertype:#bakeSelected outputwidth: Xsize outputheight: Ysize outputfile:(fPath+fName+fType)  vfb: false
    )
    
    
    -- Sets up a Test Normal Map RTT Element
    bp.removeAllBakeElements()
    bp.bakeEnabled = true
    bp.bakeChannel = 1
    bp.nDilations = 4
    
    prjp = $.INodeBakeProjProperties
    prjp.hitMatchMtlID = true
    prjp.enabled = true
    prjp.warnRayMiss = true
    
    nmtest = Normalsmap()
    nmtest.enabled = true
    nmtest.outputSzX = nmtest.outputSzY = 512
    nmtest.filenameUnique = true
    nmtest.elementname = "Normal Map Test"
    nmtest.filename = (maxfilepath + $.name + "_nmtest.tga")
    bp.addBakeElement nmtest
    
    
    -- Renders and Saves bitmap 
    be = bp.getBakeElement 1 -- Assigns the obj bake element to the variable be
    
    RTTBigleyCastTools be.outputSzX be.outputSzY bp.bakeChannel bp.ndilations be.filename
    
    if be.bitmap != undefined do
    (
        newbitmap =  bitmap be.outputSzX be.outputSzY
    
        copy be.bitmap newbitmap 
        newbitmap.filename = edtFilePath.text
        display be.bitmap
        save newbitmap 
    
        close newbitmap
        close be.bitmap
    )
    
    Any help would be very much appreciated.
  • raul
    Options
    Offline / Send Message
    raul polycounter lvl 11
    Nice scripts man! :)
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    lol thanks man! I have been trying. As you can see I am having issues.
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    Note: BBT are broken and I don't know when I will get around to fixing it. I don't bake in max anymore for work so no motivation really to pour tons more hours into fixing this. I would like to but currently this script was out of my league and I need to learn A LOT more before going back to it.

    Finished the Bigley Bake Tools.
    Here is the thread in the Tech Talk for it. You can download it there.
    http://www.polycount.com/forum/showthread.php?t=117018
  • R00
    Options
    Offline / Send Message
    R00 polycounter lvl 12
    JB where are my scripts yo! ;)
  • jeremiah_bigley
    Options
    Offline / Send Message
    jeremiah_bigley polycounter lvl 12
    The Bigley Bake Tools is going on a hiatus. Honestly it was way more than I could handle. It is really hard to get somewhere without someone to sit down and ask questions. I find myself pouring over google searches way late into the night just to realize I suck at understanding basic scripting concepts.

    I think quite honestly the BBT broke me when it came to scripting... then I went off and got married, new job, and now am literally a week away from being a dad.

    Life kind of ate me and I just haven't been scripting. I was recently just starting to come back around to it but with a baby right around the corner we will have to see how much time I can devote...


    In the mean time... I was fixing this up. #TerribleScripterAlert
    This is something I use all the time. If you find it useful, find bugs, have ideas to improve, or improve it yourself... please pass it along to me. :)

    Name: Bigley_Subobject_Jump
    What it does:
    Execute and pick an object. It will jump you to the last subobject level available in Editable Poly base object. If an Edit Poly modifier is present it will put you in that instead. In other words, if you are in vert and you pick another editable poly object, it will put you in vert in that object.
    macroScript Bigley_Subobject_Jump
        category:"Bigley"
        toolTip:""
    (
        lastSOL = (if selection[1] == undefined then 1 else subobjectlevel)  -- Store Last SO
        global jump = pickObject forceListenerFocus:false rubberBand:(if selection[1] != undefined then $.pos else [0,0,0])
        
        if isproperty jump #edit_poly then
        ( -- if EditPoly
            if selection[1] != jump do select jump; max modify mode
            currentmod = modpanel.getcurrentobject()
            if currentmod as string != "Edit_Poly:Edit Poly" do (modPanel.setCurrentObject $.editpoly node: jump)
            if lastSOL != undefined do subobjectlevel = lastSOL
        )
        else
        (  -- if NOT EditPoly
            if selection[1] != undefined then
            ( -- if Selected then
                if jump != undefined and classof jump.baseobject == Editable_Poly then
                ( -- if JumpObj is EditablePoly then
                    if selection[1] != jump do select jump; max modify mode  -- Select Jump if not already
                    currentmod = modpanel.getcurrentobject()
                    if currentmod as string != "Editable Poly" do (modPanel.setCurrentObject $.baseObject node: jump)  -- CurrentMod != EditablePoly, Go to BaseObject
                    if lastSOL != undefined do subobjectlevel = lastSOL -- Select Last SO
                )
                else
                (  -- if nothing selected
                    subobjectlevel = 0
                    deselect $
                    print "Not an Editable Poly."
                )
            )
            else
            ( -- if NOT Selected
                if jump != undefined and classof jump.baseobject == Editable_Poly then
                ( -- if JumpObj is EditablePoly then
                    if selection[1] != jump do select jump; max modify mode -- Select Jump if not already
                    currentmod = modpanel.getcurrentobject()
                    if currentmod as string != "Editable Poly" do (modPanel.setCurrentObject $.baseObject node: jump)  -- CurrentMod != EditablePoly, Go to BaseObject
                    if lastSOL != undefined do subobjectlevel = lastSOL  -- Select Last SO
                )
                else
                (  -- if nothing selected
                    subobjectlevel = 0
                    if selection[1] != undefined do deselect $
                    print "Not an Editable Poly."
                )
            )
        )
    )
    

    Edit: Noticed an error bug today at work so quick single line fix.
Sign In or Register to comment.