Jump to content
Developer Wiki and Function Reference Links ×

If Node List Handling Confusion


AlHanson

Recommended Posts

I've been encountering this with the If node on many of my marionette projects and I'm struggling to understand if this is normal behavior and the list handling just doesn't work the way I'm expecting it to and I should be approaching my scripts differently or if this is a bug. Any help explaining this to me would be appreciated!

 

I've attached a screenshot with a very simple example to explain. I've been trying to set up simple toggles using the If node and a Boolean or Popup node to control the output. I have 2 different lists of different lengths, one with 10 items and one with 15 items for example. Regardless of the Boolean status the resulting list is always as long as the list with the larger number of items and the last value just gets continued to fill out the maximum list length. Why does the result not just return a list of the 10 items in the True result? Is this a bug or am I just not approaching python script handling correctly?

 

 MarionetteList.thumb.jpg.1111257a9c1b61ae9596dfbb9c72e8ee.jpg

 

For this simple example I understand that I could just put the if nodes on the  input values to the Series node to avoid this, but I there's not always a clear work around on some of the more complex scripts I've been playing with.

 

MarionetteList2.thumb.jpg.0913f2ff891c1a75bd2051c7edca72f5.jpg

Link to comment
  • Vectorworks, Inc Employee

This is how default list handling happens in Marionette nodes. When a node receives input lists of multiple lengths, it repeats the last value of the shorter list until it has run through all the values of the longest list. You see this in nodes that are built to "expect" lists that are the same length, such as geometry creation nodes, like the Circle or Rectangle node. There are certain nodes that have special list handling, but it is usually mentioned in the description. In this instance of using the If node with multiple list lengths, you can use a Mix2 node before the If node, and you can decide with that node how you want the lists to be handled.

  • Like 1
Link to comment

Hi @AlHanson,

the If node should work fine. Could you please the check the checkbox in the object info palette of the Bool nodes?

If the checkbox is ticked, the Bool node returns "True" as is indicated by the text "True" right after the checkbox.

 

If the strange behavior of the network(s) persists, please upload the vwx-file with the information which Vectorworks version you are using.

Link to comment

Hi @AlHanson

I changed the if node a little bit, so that it can fix your problem now. With the third mode you have to be a bit careful because it reacts to the number of inputs on the test port. Otherwise everything should work fine.

 

Unfortunately I can't send you a document with a finished node, because I use a student version and you wouldn't be able to open it.

To implement, simply replace the code in the if node with the code below.

 

 

Another way to solve your problem is to convert the list to a tuple, which you leave through the if node. Then you convert the tuple back to a list. I think you can find the corresponding nodes in DomC's node gallery. If you can't find them, just tell me and I can send you my version.

#MRoth 200129

@Marionette.NodeDefinition
class Params(metaclass = Marionette.OrderedClass):
#APPEARANCE
	#Name
	this = Marionette.Node( 'If enhanced' )
	this.SetDescription( 'If test is true, pass the inputs from true otherwise pass the inputs from false' )	

	#Input Ports
	true = Marionette.PortIn( None, 'itemTrue' )
	true.SetDescription( "An item" )
	false = Marionette.PortIn( None, 'itemFalse' )
	false.SetDescription( "An item" )
	test = Marionette.PortIn( True, 'bTest' )
	test.SetDescription( "A boolean value" )

	#OIP Controls
	opt = Marionette.OIPControl( 'Options', Marionette.WidgetType.RadioButton, 3, ['Value', 'List', 'Automatic'])
	opt.SetDescription('Select how the node should work. ' + vs.Chr(10) +
	'"Values"=Works like the standard node; ' + vs.Chr(10) +
	'"List"=Returns the list in its original length; ' + vs.Chr(10) +
	'"Automatic"=If only one value is entered for Test, the node acts according to the List mode, and if several values are entered, the node acts according to the Value mode.') 

	#Output Ports
	out = Marionette.PortOut('item')   
	out.SetDescription( "The result item" )

#BEHAVIOR
	this.SetListAbsorb()
	
def RunNode(self):
	#libraries
	import itertools

	#inputs
	test = self.Params.test.value
	true = self.Params.true.value
	false = self.Params.false.value
	opt = self.Params.opt.value
	
	#script
	b = False
	if opt == 2 and len(test) == 1: b = True
	
	if opt == 0 or not(b):
		maxi = max(len(test),len(true),len(false))
		
		test = test + list(itertools.repeat(test[len(test)-1], maxi - len(test)))
		true = true + list(itertools.repeat(true[len(true)-1], maxi - len(true)))
		false = false + list(itertools.repeat(false[len(false)-1], maxi - len(false)))
		
		out = []
		for t in range(len(test)):
			if test[t]:
				out.append(true[t])
			else:
				out.append(false[t])
			#END if
		#END for
	else:
		if test[0]:
			out = true
		else:
			out = false
		#END if
	#END if
	
	#outputs
	self.Params.out.value = out

(Sorry for my scripting style. I don't know Python that well yet and have helped me with what I already know. Surely there are nicer ways to solve the problem.)

Link to comment
  • 4 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...