Notifications
Clear all

[Closed] CgTalk Maxscript Challenge 020: "Build a Better Tool"

CgTalk Maxscript Challenge 020: “Build a Better Tool”

DESCRIPTION: A simple task, but with complicated implications. Pick a tool in max (any tool; extrude, array, rename, save etc.) and make it better. This could be as simple as adding a new feature, or go as far as replacing the entire system behind the tool with something more optimised.
Keep in mind that there are a lot of tools out there that are built for this very purpose, so try to be original or expand on already existing concepts.

DEADLINE: 01/07/2008

RULES:
[ul]
[li]Do NOT post your code until the deadline![/li][li]Code from scratch. Try not to use pre-exisitng functions or plugins.[/li][li]Show your script references, if any (eg. Looking at another script to assist you).[/li][li]You are encouraged to ask for help where needed, but try to do it on your own. The maxscript reference is an invaluable resource.[/li][li]Post your final script inside [/li]“`
tags (located on your posting toolbar).
[li]Post all code into THIS thread.[/li][li]Post the max version you coded in, plus any maxscript extensions you used. (Thanks galagast!)[/li][li]Try to finish the challenge in the proscribed time. There is no definite time limit.[/li][/ul]NOTES: Enjoy! This should be diverse!

17 Replies

I’ve decided to shorten the deadline. I think I give you guys way too much time to work on these. The challenges should be short and sharp.

G-DAY mate…

Here in the USA we see your date as January 1st 2008
I presume that you mean to us up here, the deadline is 07-01-08 /
July 1st 2008

Good on Ya

MB

Well, I see the middle endian system of date as ambiguous, especially for programmers. Date progression should logically be by little endian form; day->month->year (Actually, if we were to really split hairs, big endian form is the most logical system).

If it confuses you, I can always make the date alphanumerically instead, but since the rest of the world predominantly uses the little endian method, i’m sure you can adapt.

oh no!! i missed the deadline!

Yeah, internally I always use YYYYMMDDHHMMSS (or seconds since 1 jan 1970)

MMDDYYYY is not only confusing it’s not very useful

Well, I might as well be the first:

It’s not all that robust, but I decided to try and expand the clone tool. This script creates an option to clone evenly along a picked spline, or clone randomly outward from the selection based on a maximum unit distance. I was going to add the normal cloner, but ran out of time:

[Max 2009 SP1]


 
 (
 
 -------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------
 	fn cloneRandom obj method num maxD = 
 	(
 		for i = 1 to num do
 		(
 			offst = random (obj.pos-[maxD,maxD,MaxD]) (obj.pos+[maxD,maxD,MaxD])
 			maxOps.CloneNodes obj offset:offst cloneType:method
 		)
 	)
 -------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------
 	fn cloneToSpline splineObj obj method num = 
 	(
 		newArray = #()
 		spacing = 1.00/num as float
 		for i = 1 to num do
 		(
 			interpValue = spacing*i
 			offst = pathInterp splineObj interpValue
 			maxOps.CloneNodes obj  cloneType:method actualNodeList:obj newNodes:&newArray
 			obj =  newArray
 			obj.pos = offst
 		)
 	)
 -------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------
 	rollout cloneToSplineRollout "Clone to Spline" width:160 height:200
 	(
 		local pickedSpline = "" ---local picked object
 		pickbutton pickSpline "Pick Spline" pos:[19,14] width:120 height:30
 		spinner numClones "Number of Copies" pos:[15,129] width:132 height:16 range:[1,10000,1] type:#integer scale:1
 		radiobuttons cloneType "" pos:[41,68] width:73 height:48 labels:#("Copy", "Instance", "Reference")
 		
 		groupBox Object "Object" pos:[31,51] width:93 height:71
 		button okButton_spline "OK" pos:[37,162] width:81 height:23
 		
 		on pickSpline picked obj do
 		(
 			pickedSpline = obj
 			pickSpline.text = pickedSpline.name
 		)
 		
 		on okButton_spline pressed  do
 		(
 			if pickedSpline != "" then
 			(
 				cloneMethod = case cloneType.state of
 				(
 					1:#copy
 					2:#instance
 					3:#reference
 				)
 				try
 					cloneToSpline pickedSpline $ cloneMethod numClones.value
 				catch
 					messageBox "No object to clone"
 			)
 			else
 			(
 				messageBox "You must pick a spline path to clone to"
 			)
 		)
 	)
 -------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------	
 	rollout cloneRandomRollout "Clone Randomly" width:160 height:200
 	(
 		spinner numClones "Number of Copies" pos:[15,129] width:132 height:16 range:[1,10000,1] type:#integer scale:1
 		radiobuttons cloneType "" pos:[41,27] width:73 height:48 labels:#("Copy", "Instance", "Reference")
 		GroupBox object "Object" pos:[31,13] width:93 height:71
 		button okButton_spline "OK" pos:[37,162] width:81 height:23
 		spinner maxDist "Max Dist from Obj" pos:[15,105] width:132 height:16 range:[1,10000,1] type:#integer scale:1
 		on okButton_spline pressed do
 		(
 			cloneMethod = case cloneType.state of
 			(
 				1:#copy
 				2:#instance
 				3:#reference
 			)
 			try
 				cloneRandom  $ cloneMethod numClones.value maxDist.value
 			catch
 				messageBox "No object to clone"
 		)
 	)
 -------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------
 	cloneDialog = newRolloutFloater "Attack of the Cloned" 160 450
 	addRollout cloneToSplineRollout cloneDialog
 	addRollout cloneRandomRollout cloneDialog
 	
 -------------------------------------------------------------------------------------------------------------------------------------
 -------------------------------------------------------------------------------------------------------------------------------------
 	-----TestCode-----
 	--cloneToSpline $Line01 $ #copy 50
 	--cloneRandom $  #copy 50 50
 
 )
 

(Just for fun, you get some quite cool patterns if you clone the spline you picked to clone to as well).

Well, that was a short deadline…I just saw the challenge today, so here a little try with random selection, it take a selection and split it into layer that you can select to assign material or whatever


(
Global SDx
Try Destroydialog SDx catch()
Local Do_Randomize,Do_Reset,Do_Select,Do_Rename
Local TsArray = #()
Local Pfix = "SD"

fn Do_Randomize =
	(
	if selection.count != 0 then
		(
		Do_Reset()
		TsArray=selection as array
		---------------------------------------------------
		Local Tnumb = TsArray.count 
		Local kk = (Tnumb/(SDx.spn_lv1.value as float))
		Local SubArray = #{1..(Tnumb)}	
		Local NbArray = #()
		---------------------------------------------------
		for f in 1 to SDx.spn_lv1.value do
			(
			layermanager.newLayerFromName (Pfix+"_Level"+(f as string))
			append NbArray 0
			)
		---------------------------------------------------
		While SubArray.isEmpty == false do 
			( 
			Tx = Random 1 SubArray.count
			Vx = (ceil ((TsArray.count-Tnumb)/kk))as integer
			if Vx == 0 then Vx = 1
			if SubArray[Tx] == true then 
				(
				Sx = LayerManager.getLayerFromName (Pfix+"_Level"+(Vx as string))
				Sx.addNode TsArray[Tx]
				deleteItem SubArray Tx
				NbArray[Vx] += 1
				Tnumb -= 1
				)
			) 
		---------------------------------------------------
		for f in 1 to SDx.spn_lv1.value do 
			(
			execute ("SDx.bt_S"+(f as string)+".enabled = true")
			execute ("SDx.bt_S"+(f as string)+".text = "+"\""+(NbArray[f] as string)+"\"")
			)
		---------------------------------------------------
		SDx.btn2.enabled = true
		)
	)

fn Do_Reset =
	(
	lDefault = layermanager.getlayer 0
	for f in 1 to TsArray.count do
		(
		lDefault.addNode TsArray[f]
		)
	for f in 1 to 20 do 
		(
		LayerManager.deleteLayerByName (Pfix+"_Level"+(f as string))
		execute ("SDx.bt_S"+(f as string)+".enabled = false")
		execute ("SDx.bt_S"+(f as string)+".text = \"\"")
		)
	)

fn Do_Select x =
	(
	if x!="x" then
		(
		clearselection()
		Sx = LayerManager.getLayerFromName (SDx.Eprx.text+"_Level"+x)
		Sx.select true
		)
	else
		(
		clearselection()
		Sx = (for f in TsArray where (isvalidnode f) collect f)
		Select Sx
		)
	)

fn Do_Rename x =
	(
	for f in 1 to 20 do 
		(
		Sx = LayerManager.getLayerFromName (Pfix+"_Level"+(f as string))
		try (Sx.setName (x+"_Level"+(f as string))) catch (exit loop)
		)
	Pfix=x
	)

(
rollout SDx "Random Selection" width:287 height:265
	(
	GroupBox grp1 "" pos:[74,0] width:112 height:59
	editText Eprx "Prefix: " text:"SD" pos:[83,15] width:91 height:17
	-----------------------------------------------------------
	button btn1 "Randomize" pos:[6,6] width:62 height:24
	button btn2 "Total" pos:[6,35] width:62 height:24 enabled:false
	spinner spn_lv1 "Level  " pos:[94,35] width:81 height:16 range:[2,20,5] type:#integer
	-----------------------------------------------------------
	button bt_S1 "" pos:[6,67] width:84 height:18 enabled:false
	button bt_S2 "" pos:[6,85] width:84 height:18 enabled:false
	button bt_S3 "" pos:[6,103] width:84 height:18 enabled:false
	button bt_S4 "" pos:[6,121] width:84 height:18 enabled:false
	button bt_S5 "" pos:[6,139] width:84 height:18 enabled:false
	button bt_S6 "" pos:[6,157] width:84 height:18 enabled:false
	button bt_S7 "" pos:[6,175] width:84 height:18 enabled:false
	button bt_S8 "" pos:[6,193] width:84 height:18 enabled:false
	button bt_S9 "" pos:[6,211] width:84 height:18 enabled:false
	button bt_S10 "" pos:[6,229] width:84 height:18 enabled:false
	button bt_S11 "" pos:[102,67] width:84 height:18 enabled:false
	button bt_S12 "" pos:[102,85] width:84 height:18 enabled:false
	button bt_S13 "" pos:[102,103] width:84 height:18 enabled:false
	button bt_S14 "" pos:[102,121] width:84 height:18 enabled:false
	button bt_S15 "" pos:[102,139] width:84 height:18 enabled:false
	button bt_S16 "" pos:[102,157] width:84 height:18 enabled:false
	button bt_S17 "" pos:[102,175] width:84 height:18 enabled:false
	button bt_S18 "" pos:[102,193] width:84 height:18 enabled:false
	button bt_S19 "" pos:[102,211] width:84 height:18 enabled:false
	button bt_S20 "" pos:[102,229] width:84 height:18 enabled:false
	-----------------------------------------------------------
	on btn1 pressed do Do_Randomize()
	on btn2 pressed do (Do_Select "x")
	on Eprx entered s do (Do_Rename s)
	-----------------------------------------------------------
	on bt_S1 pressed do (Do_Select "1")
	on bt_S2 pressed do (Do_Select "2")
	on bt_S3 pressed do (Do_Select "3")
	on bt_S4 pressed do (Do_Select "4")
	on bt_S5 pressed do (Do_Select "5")
	on bt_S6 pressed do (Do_Select "6")
	on bt_S7 pressed do (Do_Select "7")
	on bt_S8 pressed do (Do_Select "8")
	on bt_S9 pressed do (Do_Select "9")
	on bt_S10 pressed do (Do_Select "10")
	on bt_S11 pressed do (Do_Select "11")
	on bt_S12 pressed do (Do_Select "12")
	on bt_S13 pressed do (Do_Select "13")
	on bt_S14 pressed do (Do_Select "14")
	on bt_S15 pressed do (Do_Select "15")
	on bt_S16 pressed do (Do_Select "16")
	on bt_S17 pressed do (Do_Select "17")
	on bt_S18 pressed do (Do_Select "18")
	on bt_S19 pressed do (Do_Select "19")
	on bt_S20 pressed do (Do_Select "20")
	)
)
on execute do (createDialog SDx 192 254 100 100)
)

It doesn’t seam to be that much post for this one…what about 1 more week ?

Martin Dufour

martroyx – that’s a cool little toy. I think you should use a list box or a drop down list
instead of all this buttons, that way you will have theoretically infinit number of groups.

erilaz – I tried your tool (in max 2008) and it looks like you have a problem with the
offset definition on your cloneRandom function. If you use the offset property, it is already
being cloned on the position of the original object and then being offset from there.
So your offst variable should look like that:


   offst = random [-maxD,-maxD,-MaxD] [maxD,maxD,MaxD]
   

Good job guys:beer:

martroyx – that’s a cool little toy. I think you should use a list box or a drop down list
instead of all this buttons, that way you will have theoretically infinit number of groups.

That’s a good idea I added some seed to, thank!


(
Global SDx
Try Destroydialog SDx catch()
Local Do_Randomize,Do_Reset,Do_Select,Do_Rename
Local TsArray = #()
Local Pfix = "SD"

fn Do_Randomize =
	(
	if (selection.count >= SDx.spn_lv1.value) then
		(
		Do_Reset()
		TsArray=selection as array
		---------------------------------------------------
		Local Tnumb = TsArray.count 
		Local kk = (Tnumb/(SDx.spn_lv1.value as float))
		Local SubArray = #{1..(Tnumb)}	
		Local NbArray = #()
		Local DropArray = #()
		Local NbSeed = 0
		---------------------------------------------------
		for f in 1 to SDx.spn_lv1.value do
			(
			layermanager.newLayerFromName (Pfix+"_Level"+(f as string))
			append DropArray (Pfix+"_Level"+(f as string))
			append NbArray 0
			)
		---------------------------------------------------
		While SubArray.isEmpty == false do 
			( 
			Tx = (
					seed (SDx.spn_seed.value+NbSeed)
					Random 1 SubArray.count
					)
			Vx = (ceil ((TsArray.count-Tnumb)/kk))as integer
			if Vx == 0 then Vx = 1
			if SubArray[Tx] == true then 
				(
				Sx = LayerManager.getLayerFromName (Pfix+"_Level"+(Vx as string))
				Sx.addNode TsArray[Tx]
				deleteItem SubArray Tx
				NbArray[Vx] += 1
				Tnumb -= 1
				) else (NbSeed += (random 1 100))
			) 
		---------------------------------------------------
		SDx.ddl1.items = DropArray
		SDx.btn2.enabled = true
		SDx.ddl1.enabled = true
		Do_Select "1"
		)
	else (messagebox "Select more object or try to lower level" beep:false)
	)

fn Do_Reset =
	(
	lDefault = layermanager.getlayer 0
	for f in 1 to TsArray.count do
		(
		lDefault.addNode TsArray[f]
		)
	for f in 1 to 20 do 
		(
		LayerManager.deleteLayerByName (Pfix+"_Level"+(f as string))
		)
	)

fn Do_Select x =
	(
	if x!="x" then
		(
		clearselection()
		Sx = LayerManager.getLayerFromName (SDx.Eprx.text+"_Level"+x)
		Sx.select true
		SDx.ddl1.text = ("Selected Obj -"+(selection.count as string)+" -")
		)
	else
		(
		clearselection()
		Sx = (for f in TsArray where (isvalidnode f) collect f)
		Select Sx
		SDx.ddl1.text = ("Selected Obj -"+(selection.count as string)+" -")
		)
	)

fn Do_Rename x =
	(
	Local DropArray = #()
	for f in 1 to 20 do 
		(
		Sx = LayerManager.getLayerFromName (Pfix+"_Level"+(f as string))
		try(
			Sx.setName (x+"_Level"+(f as string))
			append DropArray (x+"_Level"+(f as string))
			) catch (exit loop)
		)
	SDx.ddl1.items = DropArray
	Pfix=x
	)

(
rollout SDx "Random Selection" width:287 height:265
	(
	GroupBox grp1 "" pos:[6,0] width:181 height:115
	edittext Eprx "prefix  " text:"SD" pos:[89,51] width:91 height:17
	button btn1 "Randomize" pos:[12,12] width:62 height:24
	button btn2 "Total" pos:[12,38] width:62 height:24 enabled:false
	spinner spn_lv1 "level   " pos:[99,13] width:81 height:16 range:[2,400,5] type:#integer
	spinner spn_seed "seed   " pos:[99,32] width:81 height:16 range:[1,99999,1] type:#integer
	dropDownList ddl1 "Selected Obj -0-						   " pos:[11,69] width:171 height:40 enabled:false
	-----------------------------------------------------------
	on btn1 pressed do Do_Randomize()
	on btn2 pressed do (Do_Select "x")
	on Eprx entered s do (Do_Rename s)
	on ddl1 selected s do (Do_Select (s as string))
	)
)
on execute do (createDialog SDx 192 120 100 100)
)

Page 1 / 2