Notifications
Clear all

[Closed] recursive function needed

I wrote a test function designed to loop through all the material nodes of an object in the curve editor and locate the position of any float wire controller.
It sort of works but I know I need a nifty recursive function to do the job properly and I tried concatenating arguments in a for loop but I got strangled by string literals not serving the function…Can anyone help? My version is below, I’m embarrassed to show it, but it’s a start…


 
fn FloatWireNode  = 
(
 local result = undefined ;
 local found = false;
 local nodestr = undefined;
 for i = 1 to 100 while not found do (
  for j = 1 to 60 do (
  for k = 1 to 100 do (
  for L = 1 to 4 do (
 for m = 1 to 10 do (
  if  $.material[2][i] != undefined do (
  if $.material[2][i][j] != undefined do (
	if classof $.material[2][i][j].controller != undefined do (
  if classof $.material[2][i][j].controller ==float_wire then (found = true;
 
   nodestr = "$.material[2]["+i as string+"]["+j as string+"]";
 
 
   )
	 if $.material[2][i][j][k] != undefined do (
  if classof $.material[2][i][j][k].controller != undefined do (
  if classof $.material[2][i][j][k].controller ==float_wire then (found = true;
 
   nodestr = "$.material[2]["+i as string+"]["+j as string+"]["+k as string+"]";
 
 
   )
 
	if $.material[2][i][j][k][L] != undefined do (
  if classof $.material[2][i][j][k][L].controller != undefined do (
  if classof $.material[2][i][j][k][L].controller ==float_wire then (found = true;
 
   nodestr = "$.material[2]["+i as string+"]["+j as string+"]["+k as string+"]["+L as string+"]";
 
 
   )
 
 
   if $.material[2][i][j][k][L][m] != undefined do (
  if classof $.material[2][i][j][k][L][m].controller != undefined do (
  if classof $.material[2][i][j][k][L][m].controller ==float_wire then (found = true;
 
   nodestr = "$.material[2]["+i as string+"]["+j as string+"]["+k as string+"]["+L as string+"]["+m as string+"]";
 
 
   )
 
 
  )
 )
  )
 )
 
  )
 )
 
 
 
  )
 
 )
  )
 )
)
 )
  )
  result = #(i,j, nodestr)
  )
 
  result 
 )
12 Replies
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

there is a much easier way to do this thing. i want just know why you need the location of the controller. how do you want to use it?

 MZ1
fn FindMaterialSubAnimByClass Obj ControllerClass = 
(
	if Obj!=undefined and classof Obj.material == Standardmaterial do
	(
		Finded = #()
		for i=2 to Obj.material.numSubs do
		(
			Sub = Obj.material[i]
			for j=1 to Sub.numSubs where (classof Sub[j].controller) == ControllerClass do 
			(
				append Finded (".material["+(i as string)+"]"+"["+(j as string)+"]") 
			)		
		)
		Finded
	)
)

FindMaterialSubAnimByClass Selection[1] float_script 

I cleaned your code a little but we can improve it more.

Thanks MZ, I will check out your code. It already looks a lot better than mine.

Oh a much easier way is good Denis! I am writing code for a spline controller that is connected to the output of a material node, such as alpha or mix amount etc…via a CA, …almost finished but I need to be able to allow the user to delete the CA later in another session of max. Deleting the CA is of course easy but I also want to delete the associated float wire controller. It turns out that due to the complexity of the material node code, it’s not a trivial task to get all that specific info from the CA itself.
I decided it was easier to loop thru the material editor and check if a float wire control was the one associated with the CA on the spline control .
All I need to do in this edit mode is locate the relevant float wire controller position so the user can delete it if they want. That’s all. I hope that makes sense…Thanks for your time.

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

is it one-way or two-way connection?

one way connection denis

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

here is a sample how to do these things:


wireAttr = attributes "wireAttr"
(
	parameters main rollout:main
	(
		weight type:#float ui:ui_weight
	)
	rollout main "Wired Parameters"
	(
		spinner ui_weight "Weight: " range:[0,1,0] type:#float scale:0.01 fieldwidth:60
	)
)
fn findSlaveFloatWires target: dependson: = 
(
	-- find all float_wires
	wires = if target == unsupplied then (getclassinstances float_wire) else (getclassinstances float_wire target:target) 

	-- filter only slaves and once connected
	wires = for wire in wires where wire.isSlave and wire.numWires == 1 collect wire 

	-- filter only dependents of a specific node
	if dependson != unsupplied then 
	(
		for wire in wires where refs.DependencyLoopTest dependson (wire.getWireParent 1) collect wire
	)
	else wires 
)

set redraw off
delete objects

b = sphere name:#testWireAttrNode isselected:on
custattributes.add b wireAttr

check = Checker name:"WireAttr Checker"
mat = Standard name:"WireAttr Material" diffusemap:check specular_level:60 showinviewport:on
setMeditMaterial 1 mat
setMeditMaterial 2 check

b.mat = mat
paramWire.connect b.baseobject.wireAttr[#weight] check[#soften] "weight"
paramWire.connect b.baseobject[#radius] mat[#Shader_Basic_Parameters][#Glossiness] "radius"


set redraw on
	
/* how to find:
-- all
findSlaveFloatWires()
-- from material
findSlaveFloatWires target:b.material
-- from material and depends on box
findSlaveFloatWires target:b.material dependson:b
-- from material and depends on wireattr
findSlaveFloatWires target:b.material dependson:b.wireattr
*/

Thanks for that denis, but I’m not sure how it helps me delete the wire controllers, as your function simply creates a collection in an array of elements each called ‘floatwire controllers’…what am I missing?

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

simply replace these instances with any convenient float controller, or as PEN suggests disconnect them.


...
cc = findSlaveFloatWires target:<target> dependson:<maxobject>
-- #1
for c in cc do replaceinstances c (bezier_float())
-- #2
for c in cc do paramWire.disconnect c

the difference between #1 and #2 is the method #1 wipes the animation, #2 to transfer the animation from the master controller.

 PEN

Loop through the collection and disconnect them.

Right, got hat thnx denis and pen. There remains for me the problem of determining if a specific float wire is the one associated with a specific Ca…as I have a modifier with several stacked CAs, each refering to a different material node…I need to check that a float wire belongs to a CA with a specific name…

that’s what my function has an extra argument “dependson” for…

I understand Denis, but I may not know the precise material node “address’ controlled by the CA without actually drilling down into the curve editor and checking…which is fine…I can use the function above for that…it’s just that it would be great if it was simpler…thnx for your time.