Notifications
Clear all

[Closed] Custom attribute help in maxscript

Here is the script refactored to use a struct, if you really wanted to:

(
	local a, b, c

	struct nodeStruct
	(
		sceneNode,
		nodeArray,
		
		fn CustAttribute_Node item nodesArray =
		(
			str = "attributes objectData
			(
				rollout paramsRollout \"Parameters\"
				(
					dropdownlist nodesDd items:%
				)
			)
			"
			ss = stringstream ""
			format str (with printallelements on nodesArray as string) to:ss
			objectData = execute (ss as string)
			free ss

			custAttributes.add item objectData baseobject:on
			select item
			max modify mode
		),
			
		fn CustAttribute_IKFK item =
		(
			IKFK_Switch = item
			
			IKFK_SwitchCA = attributes IKFK_SwitchData
			(
				rollout rollout_IK_FK "es"
				(
					group "Blend"
					(
						button matchIKtoFK "C --> B" across:2
						button matchFKtoIK "C --> A"
						
						on matchIKtoFK pressed do
						(
							arr = $.objectData.paramsRollout.nodesDd.items --collect the custom attributes array
							--get nodes by their name
							local aa = getnodebyname (arr[1] as string) exact:true
							local bb = getnodebyname (arr[2] as string) exact:true
							local cc = getnodebyname (arr[3] as string) exact:true
							--set c's transform to b's transform
							local tm = bb.transform
							local pos = bb.pos
							local new_TM = matrix3 tm.row1 tm.row2 tm.row3 pos
							cc.transform = new_TM
						)
						on matchFKtoIK pressed do
						(
							arr = $.objectData.paramsRollout.nodesDd.items --collect the custom attributes array
							--get nodes by their name
							local aa = getnodebyname (arr[1] as string) exact:true
							local bb = getnodebyname (arr[2] as string) exact:true
							local cc = getnodebyname (arr[3] as string) exact:true
							--set c's transform to b's transform
							local tm = aa.transform
							local pos = aa.pos
							local new_TM = matrix3 tm.row1 tm.row2 tm.row3 pos
							cc.transform = new_TM
						)
					)
				)
				
			)
			custAttributes.add item IKFK_SwitchCA
		)
	
	)--end struct def
	
	
	global riggingT
	try destroyDialog riggingT catch()
	rollout riggingT "Rigging Tools UI" width:250 height:600
	(
		fn test = 
		(
			a = box()
			b = box()
			c = box()
			
			a.height = 10
			a.width = 10
			a.length = 10 
			a.pos = [50,0,0]
			
			b.height = 10
			b.width = 10
			b.length = 10
			b.pos = [-50,0,0]
			
			cStruct = nodeStruct sceneNode:c nodeArray:#(a.name,b.name,c.name)
			cStruct.CustAttribute_node c cStruct.nodeArray
			cStruct.CustAttribute_IKFK c
		)
		
		group "Create"
		(
			button createIKFK "Create"
			on createIKFK pressed do test()
		)
	)
	createDialog riggingT 250 150	
)

As a script grows larger, or if there are many people working on the same script, structs can help add clarity and re-useability to the code. But they are not a magic bullet.

Just to pick you up on a small thing: I think that the way the initial code used a struct was almost right. The instance was unnecessary, but using a struct in a static way is not that bad. Since there’s no other ‘grouping’ alternatives like classes, namespaces, packages or modules, using a struct statically would be fine imo.
And since max2010 it provides a way to hide data/implementation using the private/public keywords, which is excellent programming practice.

#3. (A) I’m 99% sure you can’t directly store a reference to a scene node on a custom attribute (like you were doing with: “NodeStore” and “a type:Node” ).
What about the MaxObject parameter type?

(B) I’m 100% sure you can’t store an array data type on a custom attribute.

The xTab parameter types are statically typed arrays.

Not to derail this thread from it’s intended purpose, but I stand by my statement that you cannot add an array data type to a custom attribute. My experience with this particular problem is documented in this thread.

What about the MaxObject parameter type?

I found that you cannot store a reference to a scene node as a custom attribute on an empty modifier, in the way that EvilFish3 was originally doing. That was the reason why I couldn’t print the nodeStore. Perhaps I am wrong? I would be happy if you could provide a code snippet.

And since max2010 it provides a way to hide data/implementation using the private/public keywords, which is excellent programming practice.

I guess I’m just too accustomed to weakly typed languages. While it is good practice, I usually just leave the methods public unless security is a concern (and that’s only for an encrypted scrip).

Since there’s no other ‘grouping’ alternatives like classes, namespaces, packages or modules, using a struct statically would be fine imo.

You can declare a namespace with a set of brackets ( ). And define data structures local to that namespace. In addition, you can import .ms files using maxscript, which allows you to break scripts up into smaller chunks, which one might colloquially refer to as a ‘package’ or ‘module’.

I am not debating the use of structs, just stating that his code did not warrant the use of a struct, and that it may of been only confusing things more. Now that the codebase is working, it could be expanded to warrant the use of structs. Obviously, if you are a higher level maxscripter, you might prototype with structs and use them all the time, or you may be developing with a team using GRASP principles, which hinge on the proper use of classes and structs. For solving the problem at hand, I think it was correct to remove the struct, get it working, and then add the struct back in.

Thanks TheGrak thats exactly what i wanted. Its great, now i just need to spend a long time trying to undterstand it fully.

Also thanks Pjanssen and denisT for the help and advice.

Page 2 / 2