AlHanson Posted January 26, 2020 Share Posted January 26, 2020 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? 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. Quote Link to comment
Vectorworks, Inc Employee SBarrettWalker Posted January 27, 2020 Vectorworks, Inc Employee Share Posted January 27, 2020 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. 1 Quote Link to comment
Antonio Landsberger Posted January 27, 2020 Share Posted January 27, 2020 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. Quote Link to comment
MRoth Posted January 29, 2020 Share Posted January 29, 2020 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.) Quote Link to comment
AlHanson Posted February 24, 2020 Author Share Posted February 24, 2020 Thanks for the all the help everybody. Just understanding what to expect makes a big difference in planning and troubleshooting! Quote Link to comment
Recommended Posts
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.