-- I don't think this will destroy anyone's computer or planet but let's just give a disclaimer anyhow; -- Use at your own risk! (..risk is a risk to risk and that is risky!!) -- This file has been commented to help new Scripters. -- I added a little bit of variety to the file to demonstrate the flexibility of Maxscript. Enjoy! -- ///////////////////////////////////////////////////////////////////////////////////////// -- SOP : Spit Out Props+! -- version:"written too fast for Version #'s. All stealth like an sh!t." :P -- eb: eb7898@hotmail.com -- written in Max2011 & should work with 2008 and newer. -- ///////////////////////////////////////////////////////////////////////////////////////// -- LICENSE: -- Whoa, easy there whiskey! You can't steal this work and call it your own!! -- ..Because I claim it's awesome coolness level of '3 points above lame', for myself! -- Learn and then write your own useless rollouts! ..and remember to make a few that are useful too! -- ......Email me if you use this on something cool or morph it into something useful. :P /* START */ ---------------------------------------------------------------------------------------------- -- It's a rollout! Rollout SOP "SOP+" width:162 height:87 ( checkbox chk1 "S.pit O.ut P.rops+ ?" pos:[8,6] width:146 height:16 button btn1 "RandomColor" pos:[8,25] width:70 height:15 button btn2 "RandomPos" pos:[82,25] width:70 height:15 spinner spn1 "" pos:[105,64] width:45 height:16 range:[-99999,99999,10] spinner spn2 "" pos:[105,44] width:45 height:16 range:[-99999,99999,0] label lbl1 "1. turn on\n2. select 1 object\nby : eb\n" pos:[8,45] width:90 height:52 -- it's a button! -> let's set some wirecolors eh ? on btn1 pressed do(for i in selection do ( i.wirecolor = [(random 0 255),(random 0 255),(random 0 255)])) -- it's an odd button! -> let's set some random positions just to be a bit lame!! on btn2 pressed do(for i in selection do ( i.pos = [(random spn1.value spn2.value),(random spn1.value spn2.value),(random spn1.value spn2.value)])) fn propsForTehWurld = ( -- set a chocolate matrix with caramel topping, vanilla is so boring these days. gw.setTransform(Matrix3 1) -- check the selection count, because we shouldn't tickle more than 1 thing at a time! if selection.count == 1 then ( --starting Y point in screenEstate local ycount = 156 --starting X point in screenEstate local xcount = 10 -- Accumulate to track available space for rows and tally 'em up guvna! local rowcount = 1 -- hold the viewport's YScreenEstate in high regard local ymax = (gw.getWinSizeY()) -- for each in selection, grab and tickle with the following textings for o in selection do ( --the line belwo is commented out, it was to force this function to a filtered class... --if superclassof o == geometryclass then( -- set starttext location, name, & color gw.wText ([10,130,0]) (" Selection Info:") color:white -- Let's spit out the selection's name in white and then preset the location for the next text to spit into the y screenEstate ( gw.wText ([xcount,ycount,0]) (o.name) color:White;ycount+=14;) -- Let's check for a parent, if there is a parent, let's draw a line from the selection's transform to the parent's transform. Set the Parent's name into that "spit place" we set above and -- preset the position for the next spit into the y ScreenEstate. if o.parent != undefined then(gw.setColor #line white ;gw.polyline #(o.pos,o.parent.pos) false;( gw.wText ([xcount,ycount,0]) ("Parent: "+ o.parent.name) color:white; ycount+=14)) -- if no parent then let's inform the user! ..spit out some text to the y ScreenEstate position and prepare the position for the next spit. else ( gw.wText ([xcount,ycount,0]) ("Parent: : ~null~") color:o.wirecolor;ycount+=14; ) -- Whoa, there can be too many children to keep sanity as a dear friend, let's think this through; -- if 0(Zero) children in the hierarchy then let's inform the user with the color of the selection so that it doesn't appear in standout form...and preset the next spit place if o.children.count == 0 then ( gw.wText ([xcount,ycount,0]) ("Children: ~null~") color:o.wirecolor;ycount+=14;) -- if there is 1 hierarchical child, then let's do some things; inform the user of the child's name, again in non-standout form by using the color of the selection. -- prep the y screenEstate position for the next spit! if o.children.count == 1 then (gw.setColor #line o.wirecolor ; gw.polyline #(o.pos,o.children[1].pos) false;( gw.wText ([xcount,ycount,0]) ("Children: "+ o.children[1].name) color:o.wirecolor;ycount+=14;)) -- if there is >1 hierarchical children, then let's do some things; inform the user of the children names, and use the child's wirecolor to denote them personally by wire connection and text.. -- (no one like to be a number.. not even cyber-mathmatical-3space-coordinate-generated-CCW&CWpolygonally-created-objects!) -- Here we'll stack the children names and once there are too many in 1 stack for Tom or Nancy's viewport screenEstate, -- we'll simply make another stack into the X ScreenEstate to keep this clean and semi-dynamic! -- (Hooray! we can let max adjust these placements in close to real-time!) -- Then we'll prep the y and the x screenEstate positions for the next spit..which is the next child! until they are all counted!! if o.children.count > 1 then ( for i = 1 to o.children.count do (gw.setColor #line o.children[i].wirecolor ; gw.polyline #(o.pos,o.children[i].pos) false; );--print o.children[i].name; for i = 1 to o.children.count do (gw.wText ([xcount,ycount,0]) ("Children: "+ o.children[i].name) color:o.children[i].wirecolor;ycount+=14; if ymax < (ycount+20) then (xcount = 200;ycount = 130;rowcount+=1) if rowcount == 1 then xcount =10 if rowcount == 2 then xcount = 195 if rowcount == 3 then xcount = 380 if rowcount == 4 then xcount = 565 if rowcount == 5 then xcount = 750 if rowcount == 6 then xcount = 935 if rowcount == 7 then xcount = 1120 if rowcount == 8 then xcount = 1305 if rowcount == 9 then xcount = 1490 if rowcount == 10 then xcount = 1675 ) ) -- If there is any screenEstate left after checking for the kiddies(children), we're now going to grab the selection's props -- and display the settings of each property ..it's easier than sorting through particulars for every class and then safety netting Max's Barking system(alerts). -- for each property of the selection, let's do the following.. for p in getPropNames o do ( -- set pushout to hold a string to spit out, PROPERTY NAME - PROPERTY VALUE pushout = ((p as string) + " @ " +((getProperty o p)as string)); -- Spit out the pushout string holder using the object's wirecolor for the text ( gw.wText ([xcount,ycount,0]) (pushout as string) color:o.wirecolor; -- set the next position for more spits..we may have many properties to dsiplay. Editable Polys are ridiculously stacked with manipulatables! :P -- if too much x and y is used, we adjust accordingly to make everything display as clean as possible. (unless there are 100+ children and the seelction is an Epoly for a user that has a very low res viewport) ycount+=14; if ymax < (ycount+20) then (xcount = 200;ycount = 130;rowcount+=1) if rowcount == 1 then xcount =10 if rowcount == 2 then xcount = 195 if rowcount == 3 then xcount = 380 if rowcount == 4 then xcount = 565 if rowcount == 5 then xcount = 750 if rowcount == 6 then xcount = 935 if rowcount == 7 then xcount = 1120 if rowcount == 8 then xcount = 1305 if rowcount == 9 then xcount = 1490 if rowcount == 10 then xcount = 1675 ) ) --this nest line doesn't matter..it's a remnant of when I allowed multiple selections to have their information stacked. This gave the stacked info a bit of the old "separation". ycount+=15 -- this is the superclass filter end bracket, commented out (see line 61/62) --) ) ) -- update the area for the text gw.enlargeUpdateRect #whole gw.updateScreen() -- make a more complete 'update the area for the text' -- this may cause severe slowdowns, comment it out of needed completeredraw() ) -- this is our check box to call this entire SOP thing into use or to tell it to stop itself on chk1 changed state do ( if chk1.checked == true then ( propsForTehWurld();registerRedrawViewsCallback propsForTehWurld; completeredraw()) if chk1.checked == false then ( unregisterRedrawViewsCallback propsForTehWurld; completeredraw() ) ) -- this is to ensure this entire SOP thing doesn't hurt anyone's mojo. -- Basically, when we open and close the rollout, the callbacks are removed to make sure they are removed. Better safe than sorry. ;) on SOP open do (unregisterRedrawViewsCallback propsForTehWurld; completeredraw()) on SOP close do (unregisterRedrawViewsCallback propsForTehWurld; completeredraw()) ) -- create the rollout as a dialog createdialog SOP /* The End */ -- Thanks for playing. Remember to tip your waitress on the way out. ;)