algorithmic modeling for Rhino

Suggestion: input for "code" in .NET script components

Hello everybody,


I am thinking that it would be great to have an input for the code in VB and C# script components as we have in the python script GH component for Rhino 5. That way, we could write functions and classes only once and use it in other script components by storing them in string parameters and concatenate them with other code.


Let´s say we could, in a way, fake global classes and functions for a whole GH definition.


I don´t know wether it is easy, difficult, or even possible, to do as Grasshopper is now but maybe it could be a quick solution for the issue of accessing classes and functions from different components.



Views: 1112

Replies to This Discussion

some stolen code......



private void RunScript(string code_in, object y, ref object A)
    String InputCode = String.Empty;
    InputCode = code_in;
    System.Reflection.Assembly Assembly = CompileCode(InputCode);
    if (Assembly == null) return;
    object Temp = Assembly.CreateInstance("RunTimeCompiler.Test");
    if (Temp == null) return;
    Type RefType = Temp.GetType();
    System.Reflection.MethodInfo MethodInfo = RefType.GetMethod("Ergebnis");
    A = MethodInfo.Invoke(Temp, new object[] { });


//<Custom additional code>
  public static System.Reflection.Assembly CompileCode(string InputCode)
    System.CodeDom.Compiler.CodeDomProvider CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp");
    //Parameter für die Compilierung, wie die einzubindenen Bibliotheken usw.
    System.CodeDom.Compiler.CompilerParameters CompilerParameters = new System.CodeDom.Compiler.CompilerParameters();
    CompilerParameters.CompilerOptions = "/t:library";
    CompilerParameters.GenerateInMemory = true;

    //Über den StringBuilder wird der Code zusammengesetzt
    string Temp;// = new StringBuilder();

    Temp = @"using System;";
    Temp = Temp + @"using System.Windows.Forms;";
    Temp = Temp + @"namespace RunTimeCompiler{";
    Temp = Temp + @"public class Test{";
    Temp = Temp + @"public object Ergebnis(){";
    Temp = Temp + InputCode;
    Temp = Temp + @"}}}";

    System.CodeDom.Compiler.CompilerResults CompilerResults = CodeDomProvider.CompileAssemblyFromSource(CompilerParameters, Temp);
    //Auf CompilerFehler prüfen
    if (CompilerResults.Errors.Count > 0)
      MessageBox.Show(CompilerResults.Errors[0].ErrorText, "Fehler bei Laufzeitkompilierung", MessageBoxButtons.OK, MessageBoxIcon.Error);
      return null;
    //Rückgabe der compilierten Assembly
    return CompilerResults.CompiledAssembly;
  //</Custom additional code>





Hi Michael,


you do not really want to do this because loaded assemblies are not candidates of garbage collection and will cause a small but noticeable amount of memory to be used and never released at each definition update (memory leak). This might be fine for a short-medium test, but if you play some time with the definition it will slowly use up all computer memory, up till making Rhino crash when no more is available.

You might have some luck - but I have not tried this and I speak mostly by heart - if you create a new AppDomain at each operation and then unload it. Frankly I would not spend too much time with this: it is then impossible to exchange any type and instance that is defined in your new assembly (class, struct, enum, delegate ... or instances thereof), as that implies having the code loaded in memory. Also, everything will marshal (be copied or serialized+deserialized) across AppDomain boundaries. See here and here.


Python is interpreted and can therefore execute code at runtime. It's simple and the DLR makes a lot of this extra work for you.


- Giulio
McNeel Europe

maybe a dispose at the end could help. I personally like microsoft visual express as editor... or maybe monodevelop. Do you have any suggestions on this field to get this done?

I would agree with Giulio that python is going to be much easier to work with as far as passing functions around that can be called in other components.  If you want to do this in C# or VB.NET, you are most likely going to need to use reflection.  Here's a trivial sample in C#








  • Add Photos
  • View All


  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service