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
Creates perfect box at origin with no segments.
Creates an 8 sided cylinder at origin with no segments.
Creates a perfect plane at origin with no segments.
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. This one turns the turbosmooth modifier 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. So I wasn't able to make it back to the script for a whole week.
This will toggle the turbosmooths in a selection on or off 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.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.
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.
Nice to know that when you use "selection" it will run the script anyways. Thanks for that!
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.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!
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:
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:
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:
Happy scripting!
So over the weekend I poured over more tutorials and a lot of what everyone is saying makes sense. So in due time...
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.
Just an OT comment: Use PJanssen's Outliner script. You won't want to miss it ever again.
You could also split up your if statement so you can have more specific error messages (eg. "Nothing Selected", "Selected object has no material").
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.
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...
Name: Bigley_Smart_Material
What it does:
-- When run it creates 3 materials in the Material Editor that I use on a regular basis
Name: Bigley_TransformLock_Toggle
What it does: Toggles the transform locks on or off.
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(
______________)
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
Haven't had much time but I got to play around with this.
What it does:
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.
(hah, in the time I typed this, I could have just tested it)
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~
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.
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.
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.
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?
Any help would be very much appreciated.
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
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.
Edit: Noticed an error bug today at work so quick single line fix.