Notifications
Clear all

[Closed] Bobo's "fast tool development" video

SO Bobo apparently gave a nice master class on mxs tool development at 2008 Siggraph.
A video of it was free to 3dS Max subscribers, but I Just started using Max and can’t find any such thing on the Autodesk site.

I have found evidence of it’s existence inthis thread , among others.

Google truns up many dead links.

Does any body know where i can find this video?

25 Replies

2008? hmm… tool creation technique changed a lot since that time. at least my technique.

for example… look at the question in the thread… how to store a rollout values with max file? all suggestions from this thread are looking a little outdated today.

I’m really just looking for some solid guidelines / best practices for savvy tool scripting.
something beyond what the help files contain.

Things like how to go about using struct /roll-out pairs
(a wiki article now lost to the tech-art.org )

I suppose I’ll just keep doing it wrong and learn from my errors

2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

that’s what you will not see in techniques of 2008. it’s better to check most recent samples from this forum. in 2008 all scripters (including me) used structures a different way than today.
there is an old tool style (pseudo code):


 <global params>
 <global functions>
 <structs>
 <rollouts>
 

the modern one is:


 <
 struct
 (
    <params>
    <structs>
    <rollouts> or <forms>
    <functions>
    <event handles>
 )
 >
 

so the modern paradigm for a tool is “one tool – one global”

(@wallworm)
Joined: 11 months ago

Posts: 0

Be glad you found Denis and this advice… because I started blindly learning MXS using the old ways and didn’t learn about a lot of the current trends until I’d already created a large collection of tools… as the docs and samples easiest to find all use the older methods.

The next thing some genius here needs to invent is Matrix-style info downloading straight to the brain.

100% matches my experience.

Dennis your struct summary above is pure gold, thank you.

One question:
if the “modern” roll-out definitions are now functions within a struct, how is the UI commonly launched?
is there also createdialog / newrollout floater code within the struct, allowing commands like


myStruct.displayRollout()

or is it better practice to keep the ui launching seperate


struct mystruct(...)

global thefloater=newRolloutFloater  "" 200 100
addRollout mystruct.myrollout theFloater
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

 myStruct.displayRollout()
 

is what i do. your structure is a tool. and the tool has metdods: show dialog, hide dialog, initialize, destroy, etc. the best solution when you also able to call base tool’s functions without opening the tool dialog. tomorrow i will try to find a time to illustrate my tool concept with a snippet.

here is it:


 global GeneralSceneOps 
 (
 	struct GeneralSceneStruct
 	(
 		fn destroy = try(closeRolloutFloater GeneralSceneOps.dialog) catch(),
 		
 		title = "General Scene Helpers",
 		dialogWidth = 250,
 		dialogHeight = 400,
 		dialog,
 		
 		MatStruct =
 		(
 			struct MatStruct (material, slot)
 		),
 		ObjectRollout = rollout ObjectRollout "Objects"
 		(
 			local owner = if owner != undefined do owner
 			button deleteall_bt "Delete All Objects" align:#left width:(owner.dialogWidth - 30) offset:[-5,0] 
 			on deleteall_bt pressed do undo "Delete All" on
 			(
 				format ">>> %
" owner
 				delete objects
 			)
 		),
 		materials = #(),
 		MaterialRollout = rollout MaterialRollout "Materials"
 		(
 			local owner = if owner != undefined do owner
 			button collectmats_bt "Collect Editor Materials" align:#left width:(owner.dialogWidth - 30) offset:[-5,0]
 			on collectmats_bt pressed do 
 			(
 				owner.materials = for k=1 to 24 collect (owner.MatStruct (medit.GetTopMtlSlot k) k)
 				format "mats: %
" owner.materials
 			)
 		),
 		rollouts = #(ObjectRollout, MaterialRollout),
 		fn show = 
 		(
 			destroy()
 			dialog = newRolloutFloater title dialogWidth dialogHeight
			for r in rollouts do addRollout r dialog
		),
 		on create do
 		(
 			destroy()
 			rollouts.owner = this
 		)
 	)
 	GeneralSceneOps = GeneralSceneStruct()
 	ok
 )
 GeneralSceneOps.show()
 

this snippet mostly shows my style of tool design. don’t try to find a sense in the button functions

Nice summary, Denis !

What exactly is point of encapsuling the whole thing in a global scope ?
Isn’t that enough ?

global GeneralSceneOps;
 
struct GeneralSceneStruct
 (
 	...
	same things as you
	...
 )

 GeneralSceneOps = GeneralSceneStruct()
 GeneralSceneOps.show()

Is there any differences between the both ways?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

yes, there is. in your case we have two globals. GeneralSceneOps and GeneralSceneStruct. but there is no any reason to have GeneralSceneStruct definition public.

thank you a million times, Dennis.

The fact that the use of a mxs struct has evolved makes for outdated search results for those of us just starting.

It leads me to wonder about another aspect of max tool development which may have evolved : distribution and installation of tools to the team. I think I’ll start a fresh thread about that…

quick question
what’s the purpose behind the OK statement that follows the struct instancing?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

remove OK, run the script, and look at the listener… and return OK back.

got it

max help didn’t clearly indicate that effect.

what about



[...]

                 local owner = if owner != undefined do owner

[...]
 		on create do
 		(
 			destroy()
 			rollouts.owner = this
 		)


the latter part seems to set a .owner property to the struct
but what’s the first part do? seems odd to “do” a property…

3 Replies
(@denist)
Joined: 11 months ago

Posts: 0

that’s also the trick that belongs to me… this little hack prevents the property from overwriting at the time of a rollout creating.

(@huamulan)
Joined: 11 months ago

Posts: 0

I can’t clearly understand it. Any example?

usually, I tend to construct a definite file structure to manage my tool files.
Like
init.ms at the top of my file structure maybe with only two lines in it.

global myTool_path = getFilenamePath(getSourceFileName());
fileIn "FileStructrue/tool.ms"

under FileStructrue folder there is tool.ms with many include like


include "FileStructrue/lib/UIlib.ms"
include "FileStructrue/lib/Functionlib.ms"
.....

I like the idear “one tool – one global”. But I also want to keep my fileStucture to keep things clear. Is there a general pratical way to do this? note that the variable “myTool_path” in the init.ms is important for most of my tool is drop-in tool.

(@denist)
Joined: 11 months ago

Posts: 0

my snippet is a sample. try to remove the owner definition and check the difference

usually, I tend to construct a definite file structure to manage my tool files.
Like
init.ms at the top of my file structure maybe with only two lines in it.

global myTool_path = getFilenamePath(getSourceFileName());
 fileIn "FileStructrue/tool.ms"
 

under FileStructrue folder there is tool.ms with many include like

include “FileStructrue/lib/UIlib.ms”
include “FileStructrue/lib/Functionlib.ms”

 
 

i never use include in my max scripting. i use filein only in macroscripts to call main code.

Page 1 / 2