Notifications
Clear all

[Closed] creating a global track curve

Hello,

i’m trying to create a script , and I want to implement a feature where user can input a number that determine the times of a curve to be added to the global tracks in the curve editor.

I’m facing a problem though, because every time I execute the code inside the rollout, max script throws an error, and i can’t create it before the rollout since i need the user input.

here’s what i have so far


  	global Curve
  	
  	--rootScene[#Global_Tracks].Float.controller = float_script ()
  	--rootScene[#Global_Tracks].Float.controller = float_list ()
  	rootScene[#Global_Tracks].Float.controller.Available.controller = bezier_float ()
  	Curve = rootScene[#Global_Tracks].Float.controller[2]
  	
  	rollout testrollout "test" (
  		
  		spinner val "value"
  
  		addNewKey Curve 0
  		addNewKey Curve val.value
  		addNewKey Curve -val.value
  		curve.keys[1].value = 100
  		curve.keys[2].value = 0
  		curve.keys[3].value = 100
  		
  	)
createDialog testrollout
  

one more thing, the commented lines are for resetting the graph, it’s my solution to that every time this script is executed, it adds a new track to the available tracks, I’d like to reset the list to only one curve, I wonder if someone could help with that as well.

thank you

6 Replies

Try something along these lines:

(

	try destroydialog ::RO_TEST catch()
	
	rollout RO_TEST "" width:140 height:172
	(
		button bt_addBezier "Add Bezier" pos:[8,8] width:124 height:32
		button bt_resetBezier "Reset Bezier" pos:[8,40] width:124 height:32
		spinner spn1 "Time:" pos:[36,84] width:96 height:16 type:#integer scale:1 range:[0,100000,0]
		spinner spn2 "Value:" pos:[36,108] width:96 height:16 scale:0.01 range:[-1E9,1E9,0]
		button bt_addKey "Add Key" pos:[8,132] width:124 height:32
		
		local controller
		
		fn HasBezierController ctrl =
		(
			for j = 1 to ctrl.numsubs where iskindof ctrl[j] Bezier_Float do return true
			return false
		)
		
		fn AddBezierController =
		(
			floatTrack = globalTracks.Float
			if HasBezierController floatTrack then
			(
				controller = floatTrack.Bezier_Float.Controller
			)else(
				controller = floatTrack.Available.Controller = Bezier_Float()
			)
		)
		
		fn ResetBezierController =
		(
			if HasBezierController globalTracks.Float then
			(
				deleteKeys controller #allKeys
			)else(
				messagebox "No Bezier Controller found."
			)
		)
		
		on RO_TEST open do AddBezierController()
	
		on bt_addBezier pressed do AddBezierController()
		
		on bt_resetBezier pressed do ResetBezierController()
		
		on bt_addKey pressed do
		(
			key = addNewKey controller spn1.value
			key.value = spn2.value
		)
	)

	createdialog RO_TEST

)

it would be better to name your ‘global track controller’, and work with it by name (find, change, rename, delete, etc.)

thank you very much, that code worked perfectly.well, your version of the code worked perfectly, however when I applied it failed.
there are some values that are going to be hardcoded so i don’t want to bother the user with inputing them, like he value of the keys, i just want him to input the time, I also want the curve to be added or reset automatically when the rollout is called, so I made the following modifications


try destroyDialog ::test catch()

rollout test "pick" width:200
(
	
	--create the global curve
	spinner spnlimit "limit value" 
	button btnlimit "Set Limits"
	
	local controller
	--function to test if global track has bezier curve
	fn HasBezierController ctrl = 
	(
		for i = 1 to ctrl.numsubs where iskindof ctrl[i] Bezier_float do return true
		return false
	)
	--function to add bezier curve
	fn AddBezierController = 
	(
		floatTrack = globaltracks.float
		if HasBezierController floatTrack then
		(
			controller = floatTrack.Controller
		)else(
			controller = floatTrack.Available.Controller = Bezier_float()
		)
	)
	
	fn ResetBezierController = 
	(
		if HasBezierController globalTracks.Float then
		(
			deleteKeys controller #allkeys
		)else(
			messagebox "No curves found"
		)
	)
	
	
	on facialRig open do ResetBezierController()
	on facialRig open do AddBezierController()
	
	on btnlimit pressed do (
		
		key = addNewKey controller -(spnlimit.value)
		key.value = 100
		key2 = addNewKey controller
		key3= addNewKey controller spnlimit.value
		key.value = 100
	)
	
)
createDialog test

but it throws an error that controller is undefined.

I also have another question about the two :: in the first line of code, what are their purpose as I ran the code fine without them? thank you.

@denisT isn’t that what I did, by assigning it to the Curve variable

Curve = rootScene[#Global_Tracks].Float.controller[2]

I’m using the macroRecorder to get the name of things so my code won’t probably be all that clean.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

why do you think that second controller in globaltracks.float is yours? maybe it’s one of set (added, created) by anyone else?
i suggest to name your controller with some not common name and search and access it by name.

but if you want to be safe it’s better to add your own trackview node and your own controller (for example):

(
	own_tracks = newTrackViewNode "FullMoonStudios"
	own_ctrl = bezier_float()
	addTrackViewController own_tracks own_ctrl "Weight"
)
print trackViewNodes.FullMoonStudios.Weight

The errors are caused by the several lines of code you have modified.

Double colon are used to tell MXS to look for that variable in the global scope.

Try this:

(
  
  	try destroydialog ::RO_TEST catch()
  	
  	rollout RO_TEST "" width:140 height:152
  	(
  		button bt_addBezier "Add Bezier" pos:[8,8] width:124 height:32
  		button bt_resetBezier "Reset Bezier" pos:[8,40] width:124 height:32
  		spinner spn1 "Time:" pos:[36,84] width:96 height:16 type:#integer scale:1 range:[0,100000,0]
  		button bt_addKeys "Add Keys" pos:[8,112] width:124 height:32
  		
  		local controller
  		
  		fn HasBezierController ctrl =
  		(
  			for j = 1 to ctrl.numsubs where iskindof ctrl[j] Bezier_Float do return true
  			return false
  		)
  		
  		fn AddBezierController =
  		(
  			floatTrack = globalTracks.Float
  			if HasBezierController floatTrack then
  			(
  				controller = floatTrack.Bezier_Float.Controller
  			)else(
  				controller = floatTrack.Available.Controller = Bezier_Float()
  			)
  		)
  		
  		fn ResetBezierController =
  		(
  			if HasBezierController globalTracks.Float then
  			(
  				deleteKeys controller #allKeys
  			)else(
  				messagebox "No Bezier Controller found."
  			)
  		)
  		
  		on RO_TEST open do
  		(
  			AddBezierController()
  			ResetBezierController()
  		)
  	
  		on bt_addBezier pressed do AddBezierController()
  		
  		on bt_resetBezier pressed do ResetBezierController()
  		
  		on bt_addKeys pressed do
  		(
  			-- Add 3 keys to the Bezier controller
  			key1 = addNewKey controller -spn1.value
  			key2 = addNewKey controller 0
  			key3 = addNewKey controller spn1.value
  			
  			-- Set the keys values
  			key1.value = 100
  			key2.value = 0
  			key3.value = 100
  		)
  	)
  
  	createdialog RO_TEST
  
  )

thank you both very much for your help.

@PolyTools3D of course my modifications are the ones responsible for screwing things up :), thanks for your modifications though, they helped me achieve what i wanted.

@denisT. I see what you mean, i didn’t know I can do that actually, that could be very helpful.