We’ll start off where we left the last tutorial, A quick tour of the Python Node. This was where we finished by opening the Python Nodes Popup window by double clicking on the main body of the Node. Having done that, you will be presented by this…
Now, you may or may not know what it is doing, either way I’ll go though it Line-By-Line so there is no confusion. Note: you don’t actually need any of this code if you want to do simple operations, if you delete all this, you can still write code but you will be limited to strictly basic Python.
Let’s start line one (obviously!)…
Let’s CLR this up…
What does this mean?
CLR stands for Common Language Runtime. Yeah, very informative eh? This probably doesn’t help much in understanding why we need it.
Here is an excerpt from another blog by Haibo Luo which explains it pretty well…
“clr is an IronPython built-in module, which provides some functionalities in order to interop with .NET. When writing “import clr” in a python module, it means you intend to leverage the .NET libraries. … In IronPython, python type str is implemented by the .NET type System.String”
To summarise, if you want to import or use .NET libraries, you will need this short bit of code…and we will be importing .dll’s quite a bit so there’s no harm in keeping this is in, although, if you are not importing any .NET libraries you could remove it.
This brings us to line two, here we are adding a Reference to a .NET library which is the ProtoGeometry.dll that ships with every Dynamo install and is crucial to creating Dynamo Geometry.
This is why we imported the CLR, without the CLR we would not be able to bring this into Python as it is a .NET assembly. We MUST add a reference to a .dll if we want to use the functions that it contains, consider it like a link to the file you want to access, but having a link doesn’t give you the contents, merely a portal to access the contents later.
If we want to bring in its contents we must go to line three…
What this line of code is doing is saying is, well, we added a reference to “ProtoGeometry.dll”, and from this we want to import everything from the Namespace “Autodesk.DesignScript.Geometry”.
What is a Namespace? I won’t get into specifics as you can google this and find much and more about this, but let’s say you have a cook book, if we were to breakdown that book into a list of its parts starting with the book itself, we would get the following:-
- Chapters by Topic, Region or Main Ingredient
- Cooking Methods
Well, Object Oriented Programming (OOP) is similar to this (in my mind anyway – but I haven’t had breakfast yet and food is weighing heavily in my thoughts! Haha!). When you are writing code you are essentially creating a recipe of instructions to send to your computer for execution, but you still need to organise this in a logical way if you have a lot of recipes. Let’s swap out the Cookery terms and put some Programming terms in there…
Can you see how this works? It’s not a perfect analogy, I’m sure someone may disagree with some aspects of it, but for me it’s close enough.
Like I said, I won’t get into specifics as the purpose of this tutorial is about Python/Dynamo/Revit API, but I thought I would at least mention this as an understanding of how OOP is structured is fundamental to working with the RevitAPI, .NET or any other OOP based language.
Awesome, almost there! Now, onto the fourth/fifth line…
The Ins and OUTs…
Now, this is a bit of an odd one as we don’t actually need it. I’m not entirely sure what the purpose of this line is other than to tell you that all your inputs coming into the node will be stored in an Array called IN.
The IN Variable is a Built-In variable to store all the inputs coming through the Input Ports on your Python Node. It is essentially and Array of Arrays. To get an item from the IN array, we need to use the “IN[n]” syntax commonly used to get an item from any array in Python (where n is the index number of the item).
You can see this even labelled for you on the IN Ports on the Python Node itself…
So, if we want to work with the data coming into the Python Node we can simply just refer to that port as it is written any time we need to use it. This generally is not good practice though, a better way to use this Input Data is to create a new Variable that is called something related to what it is and store the IN[n] data in that. This gives the Data context when you are using it throughout your script.
See this example for what I mean about creating new variables with context…
We are doing a simple operation here that concatenates some strings with a “_” separator.
Here is the code in its simplest form. Note how I have removed the CLR, References and Imports? We are using Built-In functionality and don’t need to use any other Libraries.
Now look at the following…
This is more human readable and easier to understand (and easier for someone else to follow), although a little bit more work. When you start working with more complex scripts you will see that naming your variables to something obvious will lead to less errors putting in the wrong Index number and much easier to debug.
And, finally the last lines. The OUT variable…
The OUT variable is another Built-In variable, You can only have one OUT variable, but you can output anything you need, this includes any object, array or array of arrays, therefore you can output more than one output by grouping all your outputs in an Array of outputs… I hope that makes sense! Haha! Here is an example to make it clearer…
You can see that you can output whatever you need in this one OUT variable, but it is up to you how you structure the out data to how it will be used downstream. We’ll cover this later on when we need to output multiple data and how we deal with that data out of the node to create a usable custom node with multiple OUT ports.
Well, this pretty much sums up in detail what this node contains and a little more.
Hope you found this useful, in the next tutorial, References, References, References… we will have a deeper look at Referencing and what you will need to Reference and for what purpose.