Python and Csharp scripting used as an OOP environment

python
csharp
scripting
code
oop

#1

I have earlier today released my version 2018.301.0 version of the DanEDU Dynamo package. Thanks to @awilliams, @JacobSmall, and @Kulkul for testing it before I posted this topic. However, it is not the update as such, why I am making this topic. The essential of this package is, on the other hand, a breakthrough.

All the releases since 2017.x.x versions have been developed as an OOP package thanks to ideas I developed from @Konrad_K_Sobon and @Mostapha. But in this one, I have extended it with Csharp scripting thanks to @Dimitar_Venkov “C sharp interpreter”.

Please take a look under the hood in the package and the nodes to see how they are built.

The way I have implemented the Csharp code is taking @Dimitar_Venkov previously presentations and turning them into “production” mode. The code outside “#region Script section for using CSharpScript.FromString” can be transferred directly to production in a ZeroTouch environment!

In other words, am I trying to prove how everyone can gain what the .net platform gives without turning it into a coding project that needs to be compiled. It has the lightweight and easy approach as python scripting without the limits from IronPython 2.7.3. The side effect is that the code rather easily can be turned into a ZeroTouch package if wanted and we can start implement things from @Jeremy_Tammik site one-to-one :slight_smile:

Inside the individual nodes have I made a “Reader” (one for Python and one for Csharp). The reader does three things. One, it knows where the (my) package is installed, which is needed since I will never know the path where users are installing the package. Two, it comes with a"refresh" option, which is needed when testing. otherwise I would need to close/open the graph everytime I changed something in the script. Three, it comes with an option for feeding an individual path. Therefore can the reader be used by others in developing/using Python/Csharp scripting.

Keeping the code outside in external files gives the benefit of using IDE’s there can assist with intillisence and error correction. Thanks to @Gui_Talarico for making stubs available for the Python language.

The testbed is made on the flipped nodes, both in the Boolean and the Element version. By doing this I give examples of returning a single list and returning a dictionary converted to a list with sublists, as it is being done with the python custom nodes. The way the methods are coded is according to how they must be coded to apply the “ZeroTouch” requirements.

Flipped (6 nodes).dyn (32.6 KB)

Unfordnetly I cant upload a test project due to the limitations on file upload. I don’t know why there has been set a limitation on 3.2 Mb for files. Almost no rvt project files can be so small… but if you are very interested, then contact me with a private message and I will try to arrange a test file.

Likewise, do I hope that it will be doable to upload cs files in the community as it is with py files (@Racel_Williams, @Zach_Kron)


Arguments invalid in index of
Python Nodes Basics
How to import an external python file
Robot SA: Uniform Load on Contour, from Dynamo
#2

I’m excited about this! :slight_smile: I’ve learned a lot from examining your Python scripts, so I’m looking forward to being able to do the same with C#. Awesome work per usual :+1:


#3

I have learned a lot of examining scripts of the both of you :grinning:


#4

it is opened a new Chapter of the book for study…
this material is not to explore in one day of course but it’s very interesting

@erfajo :clap: :fire:


#5

@erfajo very cool! I was hoping someone would investigate this possibility, now you just need a double click on node -> opens visual studio extension with debug.


#6

@Michael_Kirschner2,
Is that a feature of dynamo 2.0? – That sound really good :slight_smile:
Could I suggest you ask @Dimitar_Venkov if his “C sharp interpreter” could go into the core nodes of Dynamo. I think this would be most wanted by more developers than me :slight_smile:

Next, as a suggestion for both the “Python Script Reader” and the “C sharp interpreter” please add a “refresh” option. Scripts updated in external files will not be seen as updated if you don’t add some kind of “reread” or “refresh” option.

Finally, make a node that can find the path to the package storage “root”, with an input for the individual packages.

By developing this, we all can be developers more easily than today. Please feel free to take any of the ideas from my package :slight_smile:


#7

Here’s an example on how to load and use custom assemblies. The below code is executing a python statement in C#:

@Michael_Kirschner2 The code used in the script is structured differently than what you’d typically have in Visual Studio. There’s a meta class that encompasses the script code, so you’d have to somehow open VS with an appropriate template and then paste the node’s code in the right place…


#8

Thanks for sharing how to load assemblies from outside what is preloaded with Dynamo.

This “trick” @Dimitar_Venkov show is a much larger gamechanger than it looks. By showing this, it literally means, that any .dll based software or COM-object driven software can be used in combination with Dynamo. e.g. Microsoft Office package, like Excel and Project if anyone could be interested :slight_smile:

Below here is an example of csharp code as I have made it… please notice the “#region”, that is the important part which makes it possible to run the code using the “C sharp interpreter” node.

The two internal static methods are made that way since I in my ZeroTouch package use those two methods over and over again, so they are stored in my utilities.cs file used throughout the package. That part could be included in the “main” method (the Flipped method).

The Boolean Flipped method has an IList return, like other nodes in the Dynamo concept has it, which is returned to the user via the tFlipped method, invoked in the end by the command tFlipped() without a semicolon ( ; ) that is important!

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Revit.Elements;
using RevitServices.Persistence;
using Autodesk.Revit.DB;

internal static Document Doc
{
    get { return DocumentManager.Instance.CurrentDBDocument; }
}

internal static Autodesk.Revit.DB.Element Elem(Revit.Elements.Element elem)
{
    return Doc.GetElement(elem.UniqueId.ToString());
}

public static IList Flipped(IList element)
{
    List<object> flipped = new List<object>();

    foreach (Revit.Elements.Element elem in element)
    {
        Autodesk.Revit.DB.Wall item = Elem(elem) as Autodesk.Revit.DB.Wall;
        if (item.Flipped)
        {
            flipped.Add(true);
        }
        else
        {
            flipped.Add(false);
        }
    }
    return flipped;
}

#region Script section for using CSharpScript.FromString

public IList tFlipped()
{
    // argument assigned the IN port
    var element = (IList)IN[0];

    // return assigned the OUT port
    return Flipped(element);
}

// Invoke the script (method)
tFlipped()

#endregion

For the sake of completeness, the below is snipped from the comparative Element Flipped method, which has a IDictionary return since it has a “MultiReturn”. But it can rather easily be converted in the return method to the user by the tFlipped() method. It returns the IDictionary as an IList so the output can fetch it as OUT[0] and OUT[1] etc. It is invoked in the end like the former code by the tFlipped() without the semicolon ( ; )

public static IDictionary Flipped(IList element)
{
    do something... 
    
    return new Dictionary<string, object>
            {
                {"True", flippedTrue},
                {"False", flippedFalse}
            };
}

#region Script section for using CSharpScript.FromString

public IList tFlipped()
{
    // argument assigned the IN port
    var element = (IList)IN[0];

    // cast IDictionary to IList
    var idict = Flipped(element);
    var dict = (Dictionary<string, object>)idict;
    var ilist = new List<object>(dict.Values.ToList());

    // return assigned the OUT port
    return ilist;
}

// Invoke the script (method)
tFlipped()

#endregion

#9

The dawn of the singularity driven by Dynamo draws ever nearer! :scream:

I wonder if it would be willing to keep me around to respond to forum posts for them… :thinking: