Inputs in definitions - is this possible?

designscript

#1

Hi all,

I have a script that requires the Select Model Element node to be used several times with the same element selected. I would like to clean it up a bit, remove the crossing wires etc. by using code block definitions.

I’m new to code block defs so sorry if this is very simple!

Is there a way to to have an input in a definition like in the top row of nodes?
If not is there a way to make the element ID a variable in the bottom row of code blocks? The element id won’t always be the same when running in different scripts you’re aware.

Any suggestions?

Cheers!

TJ


#2

Hi @Tom_James

Why not just use “List.Cycle” or “List.OffRepeatedItems” node. You can have as many times you want :slight_smile:


#3

Hi @Kulkul,

I get what you mean, there isn’t really an issue. I was just wondering if there was a way to reduce the amount of ‘crossing wires’ in my script, by having the definition shoved in the corner, so all I have to do is use the Modeltest() node as shown above, cleaning up the script.

Do you know if it’s possible to have an input into a definition?

Thanks,


#4

@Kulkul @Tom_James This question has been asked multiple times on the forum, and the answer has always been no. It is a reasonable and logical request. Essentially it is like in Python (or any other number of languages I assume) when declaring a variable. The scope of that variable definition varies based on the rules of the language. In Python, if the variable is declared in the body of a module (say x=1), the value of that variable is constant when called in the body (unless it is overwritten by a subsequent assignment to the same variable name (x=2). If the variable is declared within the definition of a function, the variable’s value applies only to the code within the function definition.

A coder would claim your request is obvious. A narrow-minded scripter would tell you to declare the value as an input to the definition-- essentially using a custom input value on a per instance basis.

The reality is that (it seems) as most coding languages grow, and even some from conception, dive Deep into variable scope in the context of very large workflows or programs. A Python main console could reference any number of module files which could contain fixed variable values or functions that process values. I don’t know C# yet but I know a good deal of the verbiage in the code is concerned with public and private scope.

Point is, Dynamo already allows .dyn files to access .dyf files (definitions), custom nodes, or definitions declared within said .dyn file. Dynamo will (hopefully) evolve into a program that allows .dyn files to access other .dyn files as well as any variables or functions declared within those outside .dyn files (or declared “outputs” to use scripter speak). But Dynamo does not currently allow a .dyn-wide function definition to live-access variable data.

I think the missing link here is true Variable Definition within Dynamo. At present variables can be declared within a code block and behave much the same way as variables in code languages, but the scope of those variables ends once outside of the code block. As you have seen, one can embed a constant value by defining it within a custom function and returning it by calling the function, but this doesn’t allow the value to vary throughout the course of the .dyn script the way a variable could be overwritten in, say, Python code.

The real issue is that separate nodes within a .dyn script can and are run in parallel. When there is parallel computation, various nodes that access a [wireless] Variable value wouldn’t know which version or state of it to use.

At the end of the day, in order for Dynamo to be capable of truly defining variables at a .dyn-wide scope (which is what you are proposing), Dynamo needs to do 1 or more of the following:

  1. Allow more explicit user control over the compute order of .dyn content. For traditional code languages code is “Read” or processed by the computer from top to bottom, and loops and nested functions are handled through indentation and/or brackets.

Dynamo could process variables geographically (left-to-right) allowing the user to manage variable state by node location. This seems difficult to integrate with loops [which again are confined to OOTB nodes, custom nodes (.dyf files), or code blocks] but the geographic approach could be used as a default interpretation by Dynamo until an exception is encountered.

When an exception IS encountered, the User could assign the Variable state by selection from a visual Hierarchy Graph of the .dyn script. This seems a little separate and redundant to managing hierarchy on the fly. So maybe node dependency could be color-coded (or hatch-coded for the color-blind).

There is potential in the Stop Process and Start Process nodes, but that alone won’t enable global use of Variables in a .dyn file.

It’s almost as if a hierarchical shorthand (textual or visual or both) needs to automatically be generated as the script develops. A good Textual example is Dynamo’s own “At Level” processing of list depth (@1, @2,@@2 etc.) and the data itself as seen in each node dropdown. A good Visual example is Autodesk’s Fusion360-- at the bottom of the screen, as a Part is modelled, the parametric and hence Operation Dependence History is displayed on a timeline through Icons of operations. The user could select from this shorthand interface to select the correct variable state to reference. (In fact, Fusion could improve EPICALLY if it allowed easier Reuse or Reference to various parts of the developed history by other parts or even outside files. Perhaps the history icons could be click-expanded to expose various dependencies visually through wires. And maybe icons could be named (hence creating a VARIABLE) and tagged for outside file public access.)

I guess the last potential approach would be to find a way to automatically manage variable state under the hood (which could in some cases lead to some vagueness in how results were obtained). Automatic processing is best left to simpler processes.

Cheers


#5

As noted in the many other requests for this, there are several other methods to achieve this. My favorites are:
Clipboard send to/Clipboard get from; write to and read CSV or text file.

Most often when I see a mess of wires as described above I find that utilizing data and list management, and some design script to reduce he number of nodes not only fixes the mess of wires issue, but also allows for faster graph runtimes and optimizes the graph for incorporation with Dynamo player (which means no one really sees the mess of wires even if they exist).

Those two points mean I’m fine with never seeing a function allow for inputs, as long as I keep getting other sweet goodies like player input formatting, or more robust send to web access (maybe enable from within the Revit add in instead of just studio, with a link for use with a BIM360 shared models and data sources).


#6

HI Nick,

Is this still the case even with the latest releases of Dynamo? I am finding myself always getting to the point where my wires are becoming excessively crossed…


#7

That is still the case, and my prior post still holds. List levels, lacing and code blocks are usually the best way forward. I have created definitions to move a value to a dictionary stored as a .txt file can be easily recalled which works for simple data types, but there is no way to remove complex data like geometries and elements.

It may be possible to do something like this with a view extension, but I’m not sure and I haven’t seen others ‘go there’ just yet.


#8

Creating custom nodes to compact many nodes is also an option. If a section of nodes have a lot of crossing wires within but are relatively self-contained, putting it all into a custom node can save space.