Take a grasshopper script and turn it entirely into c# code?

Hi,

is there a simple way to convert all grasshopper code into C#?

So for example I have a .Gh file and want it to all be c# code

Short answer is no. Like a very big no.

Would running a gh script from c# (e.g. without having to open it on the canvas) be an alternative. That is pretty much how a cluster works.

Sorry I can’t be of more help, think this one has been asked before I’ll have a look

Here’s a similar old post. No from DR himself I’m afraid

I am seeing by copy-pasting independent nodes in c script does give me some form of code? - see the following - Is this sufficient for the operation of the code from a “source” perspective versus an object perspective?

<?xml version = "1.0" encoding = "utf-8" standalone = "yes" ?>
  <Archive name = "Root">
  <!--Grasshopper archive-->
  <!--Grasshopper and GH_IO.dll are copyrighted by Robert McNeel &Associates-->
  <!--Archive generated by GH_IO.dll file utility library {0.2.0002}-->
  < items count = "1">
  <item name = "ArchiveVersion" type_name = "gh_version" type_code = "80">
  <Major > 0</Major>
  <Minor > 2</Minor>
  <Revision > 2</Revision >
  </item >
  </items>
  <chunks count  =  "1">
  <chunk name  =  "Clipboard">
  <items count="1">
  <item name="plugin_version" type_name="gh_version" type_code="80">
  <Major > 1</Major>
  <Minor > 0</Minor>
  <Revision > 7</Revision >
  </item >
  </items>
  <chunks count  =  "4">
  <chunk name="DocumentHeader">
  <items count  =  "5">
  <item name = "DocumentID" type_name = "gh_guid" type_code = "9" > c6ea35ab - c724 - 4dba - 8656 - 3f2a12b2d7c5</item>
  <item name = "Preview" type_name = "gh_string" type_code = "10" > Shaded</item>
  <item name = "PreviewMeshType" type_name = "gh_int32" type_code = "3" > 1</item>
  <item name = "PreviewNormal" type_name = "gh_drawing_color" type_code = "36">
  <ARGB > 100;150;0;0</ARGB >
  </item>
  <item name = "PreviewSelected" type_name = "gh_drawing_color" type_code = "36">
  <ARGB > 100;0;150;0</ARGB >
  </item >
  </items >
  </chunk>
  <chunk name  =  "DefinitionProperties">
  <items count  =  "3">
  <item name = "Date" type_name = "gh_date" type_code = "8" > 636070817273558846</item>
  <item name = "Description" type_name = "gh_string" type_code = "10" > /item>
  <item name = "Name" type_name = "gh_string" type_code = "10" > Formative_V9.gh</item >
  </items>
  <chunks count  =  "3">
  <chunk name  =  "Revisions">
  <items count="1">
  <item name="RevisionCount" type_name="gh_int32" type_code="3">0</item>
  </items >
  </chunk>
  <chunk name  =  "Projection">
  <items count="2">
  <item name = "Target" type_name = "gh_drawing_point" type_code = "30">
  <X > 359</X>
  <Y > -50</Y >
  </item>
  <item name = "Zoom" type_name = "gh_single" type_code = "5" > 1.17647052</item >
  </items >
  </chunk>
  <chunk name  =  "Views">
  <items count  =  "1">
  <item name = "ViewCount" type_name = "gh_int32" type_code = "3" > 0</item >
  </items >
  </chunk >
  </chunks >
  </chunk>
  <chunk name  =  "RcpLayout">
  <items count  =  "1">
  <item name = "GroupCount" type_name = "gh_int32" type_code = "3" > 0</item >
  </items >
  </chunk>
  <chunk name  =  "DefinitionObjects">
  <items count="1">
  <item name="ObjectCount" type_name="gh_int32" type_code="3">1</item>
  </items>
  <chunks count  =  "1">
  <chunk name="Object" index="0">
  <items count  =  "2">
  <item name = "GUID" type_name = "gh_guid" type_code = "9" > deaf8653 - 5528 - 4286 - 807c - 3de8b8dad781</item>
  <item name = "Name" type_name = "gh_string" type_code = "10" > Surface</item >
  </items>
  <chunks count  =  "1">
  <chunk name="Container">
  <items count="7">
  <item name = "Description" type_name = "gh_string" type_code = "10" > Contains a collection of generic surfaces</item>
  <item name = "Hidden" type_name = "gh_bool" type_code = "1" > true</item>
  <item name = "InstanceGuid" type_name = "gh_guid" type_code = "9" > 2491c0aa - 03ad - 4a63 - b17d - 200392d8c3f4</item>
  <item name = "Name" type_name = "gh_string" type_code = "10" > Surface</item>
  <item name = "NickName" type_name = "gh_string" type_code = "10" > Srf</item>
  <item name = "Optional" type_name = "gh_bool" type_code = "1" > false</item>
  <item name = "SourceCount" type_name = "gh_int32" type_code = "3" > 0</item >
  </items>
  <chunks count  =  "2">
  <chunk name="Attributes">
  <items count="3">
  <item name = "Bounds" type_name = "gh_drawing_rectanglef" type_code = "35">
  <X > 83</X>
  <Y > 108</Y>
  <W > 50</W>
  <H > 20</H >
  </item>
  <item name = "Pivot" type_name = "gh_drawing_pointf" type_code = "31">
  <X > 108.1283</X>
  <Y > 118.343</Y >
  </item>
  <item name = "Selected" type_name = "gh_bool" type_code = "1" > true</item >
  </items >
  </chunk>
  <chunk name  =  "PersistentData">
  <items count="1">
  <item name="Count" type_name="gh_int32" type_code="3">1</item>
  </items>
  <chunks count  =  "1">
  <chunk name="Branch" index="0">
  <items count  =  "2">
  <item name="Count" type_name="gh_int32" type_code="3">1</item>
  <item name = "Path" type_name = "gh_string" type_code = "10" > {0}</item >
  </items>
  <chunks count  =  "1">
  <chunk name="Item" index="0">
  <items count  =  "1">
  <item name="RefID" type_name="gh_guid" type_code="9">317b3e4d-d018-4b81-9488-cdd0cac1b6aa</item>
  </items >
  </chunk >
  </chunks >
  </chunk >
  </chunks >
  </chunk >
  </chunks >
  </chunk >
  </chunks >
  </chunk >
  </chunks >
  </chunk >
  </chunks >
  </chunk >
  </chunks >
  </Archive>

Depending on your use case/end goal this thread might be useful:

1 Like

Thank you @kiteboardshaper alas it is not exactly what I am looking for… However, I did read your thread which was a pretty interesting way to protect things, kind of. I can export the independent nodules, but am looking for someone with the coding skill to look at my GH, convert to C# and write it totally in C#, I feel like there should be a service out there for something like this. Just like a way to reverse the GH into a source. @mcneelsoftware is there anything like this in the works or anyone who provides it as a service? I could do it myself but I need to learn more coding.

Well … that’s a bit CATCH22 (notorious cyclic logic etc etc). I mean IF you know C# then you never do a solution with components (there’s exceptions of course that confirm the rule) … but if you are a beginner what could be the benefit of dealing with a black box (i.e. your stuff “converted” into C#) - you could not further (as is the norm in 99.99999 % of real-life cases) develop/debug/whatever … and that brings us back into that rabbit hole.

Out of curiosity (that killed the cat) post some stuff of yours that you would like to “convert”.

Thats the whole point, I cant share it for that reason, new developments, new code. There are other ways of protecting, it just optimizes calculations, and runtimes for GHpython → VB–> C#

You are Indeed in the rabbit hole (many entries, no exit > kinda Alice in the Wonderland). Other than that any pro (at least in theory) bakes his beans with one way (BTW: who does things with VB these days?).

BTW: If something becomes slow … in 99% of cases blame you (unless you are after computing the mass of some black hole in a galaxy far far away etc etc).

So your saying dont worry about it and keep rolling?

I’m saying that everything in life is a race against time: learn C# as soon as possible and reach a level that could allow you to evaluate things in a totally different perspective (including the why to do things).

Keep in mind that knowing how to do things is a small thing … all what really metters is the conrol of things (for instance if you are in the AEC business … all what matters is what happens on site).

From what I understand right now it is, in theory, completely possible to match the function of any GH definition in C#/Rhinocommon code.

GH is for want of a better description just a visual representation of data being passed around between blocks of C# (plus GH PYTHON, F#, VB, C++ or a range of other languages)

Control of some plugins (like Kangaroo) are a little less easy to implement via C# but are possible.

Cheers

DK

Hi Mikael -

FWIW, @mcneelsoftware apparently is a user studying or working at the Emily Carr University of Art + Design who spent less than 10 minutes reading 2 threads here on Discourse.

At any rate, you didn’t really explain the purpose of converting graphs into “code” - have you looked into using the Script Compiler in Rhino 7 that lets you save Grasshopper files as rhp plug-ins? You’ll have to adapt your graphs so that they can be run from the GrasshopperPlayer command…
-wim

Technically it’s possible. You can decompile and disassemble code. Copy and paste it. That however violates license agreements and is not helpful at all. Grasshopper makes things easier for non-programmers and produces a lot of overhead because of that. A software developer usually goes the direct way. Sure, you can hire someone, but seriously, what’s your part other than being a client? Do you think that connecting pre-fabricated components, basically running a code generator, is really such a great achievement? Sure, you can debate about that, but I rather tend to say no.

It depends on why you want to create C# code. Usually you get better performance with writing C# code because you reduce the algorithmic complexity by combining several operations (=components) into one step. That’s something you can’t do by just converting.
Is it for deployment and protection purposes? That’s such a complex topic, that it will likely take more effort than everything else. Non-programmers tend to underestimate that part totally.

A GH user who is not able to code (at least inside GH/RH) is a weak user. At any point where GH does not cover the use-case, this user will fail or will need to rely on third-party help. It’s in your own interest to learn to convert your definitions into C#, just as Peter says.

By the way it doesn’t necessarily make sense to convert a single script into a C# script, but into modular parts. Reducing a 1000 component definition into 25 script components is usually better, than having 1 big bulk of code.

why are 25 components of code better than one component of code replacing 1000 nodes? (I really ask out of curiosity)

Because you might need to reuse components. It also prevents you from dealing with a too large code-base. Instead, you break the logic down to single-responsible parts. Of course, the number of 25 is quite random. E.g. for a pattern this means that you create a component to create a grid of points, another is connecting the grid with lines, another component creates the surfaces based on the curves and so on. If you want to change how the grid is generated, you simply replace that part without touching the rest.

1000 components are as complicated to handle than just 1 script component. At least for a script-component with one code file.(If you create a library, you can split the code by creating more than 1 code files). I found the best maintainability of a definition is if you deal with around 5 to 100 components for a medium-sized project. This same holds true for the amount of parameters. You can clearly over-parameterize a definition.

true dat! I spend so much time for my c# components figuring out which parameters I can automate/decide for the user without having too many parameters and therefor loss of overview in the end.

Thank you for your precisions!

Hey everyone, I may have found a way to do this. I will be following up with some details soon, so now everyone who doesn’t know C# can have a pipeline to convert their special sauce. I need to verify this, but once its done, it will be a really fast way for us lazy architects/designers to convert. Don’t get me wrong I am teaching myself C# and other code everyday, and in doing so found some interesting holes… if this doesn’t work I am going to be trying to building a team to provide an automated way of doing this regardless… If anyone is interested in being part of this endeavor message me privately. I mean how many API’s are intertwined with Rhino and Grasshopper , really? (That is sarcasm, I know its literally growing almost everyday) May not work for all types of plugins and addons, but It will begin a much needed aspect of intermediate to advanced GH user pipelines.

I still have difficulties to understanding the use-case. I’m sort of lazy as well. Why would auto-converting my definitions into C# help me in doing so, and why would that pipeline be a more advanced one? (I also really ask out of curiosity). Once I’m done with a definition, what would converting that definition into a c# script give me? Why should I take that extra step?

I also ask this because in GHPython, McNeel added a functionality to write a script by using GH components. In a way that you can write definitions like if you would place components. I have hardly anybody seen using this possibility.