Convert Python to c# in Grasshopper-help

Hello everyone, I need help to convert THIS python Script to c# in Grasshopper(this script shows all the plugins and cluster and component used in the algorithm in the panel) i try it but get this error for panel…
@Mahdiyar


ot_get Component__.gh (18.3 KB)
C#=

// Grasshopper Script Instance
#region Usings
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using Grasshopper.Kernel.Special;
#endregion

public class Script_Instance : GH_ScriptInstance
{
    #region Notes
    /* 
      Members:
        RhinoDoc RhinoDocument
        GH_Document GrasshopperDocument
        IGH_Component Component
        int Iteration

      Methods (Virtual & overridable):
        Print(string text)
        Print(string format, params object[] args)
        Reflect(object obj)
        Reflect(object obj, string method_name)
    */
    #endregion
   
    private void CheckCanvas()
    {
        bool note = false;
        var ghdoc = Instances.ActiveCanvas.Document;

        foreach (var obj in ghdoc.Objects)
        {
            if (obj is GH_Panel panel && panel.NickName == "All Components Used")
            {
                panel.UserText = AnalyzeActiveGhDoc();
                panel.ExpireSolution(true);
                note = true;
                break;
            }
        }

        if (!note)
        {
            MakeCompsPanel();
        }
    }

    private void CheckCanvas2()
    {
        bool note2 = false;
        var ghdoc = Instances.ActiveCanvas.Document;

        foreach (var obj in ghdoc.Objects)
        {
            if (obj is GH_Panel panel && panel.NickName == "PlugIns Used")
            {
                panel.UserText = formatted;
                panel.ExpireSolution(true);
                note2 = true;
                break;
            }
        }

        if (!note2)
        {
            MakePlugInsPanel();
        }
    }

    private void MakeCompsPanel()
    {
        var panel = new GH_Panel();
        panel.Name = "All Components Used";
        panel.UserText = AnalyzeActiveGhDoc();
        panel.FillColor = Color.LightSkyBlue;
        panel.Font = new Font("Trebuchet MS", 10);
        panel.Multiline = false;
        panel.Attributes.Pivot = new PointF(-345, 0);
        panel.Attributes.Bounds = new RectangleF(-330, 0, 330, 450);
        Instances.ActiveCanvas.Document.AddObject(panel, false);
    }

    private void MakePlugInsPanel()
    {
        var panel = new GH_Panel();
        panel.Name = "PlugIns Used";
        panel.UserText = formatted;
        panel.FillColor = Color.LightSkyBlue;
        panel.Font = new Font("Trebuchet MS", 10);
        panel.Multiline = false;
        panel.Attributes.Pivot = new PointF(-690, 0);
        panel.Attributes.Bounds = new RectangleF(-330, 0, 330, 150);
        Instances.ActiveCanvas.Document.AddObject(panel, false);
    }

    private Tuple<Dictionary<Guid, GH_AssemblyInfo>, Dictionary<Guid, GH_AssemblyInfo>> Libraries()
    {
        var coreLibraries = new Dictionary<Guid, GH_AssemblyInfo>();
        var addonLibraries = new Dictionary<Guid, GH_AssemblyInfo>();
        var server = Instances.ComponentServer;

        foreach (var obj in Instances.ActiveCanvas.Document.Objects)
        {
            var objId = obj.ComponentGuid;
            if (obj is IGH_Component)
            {
                if (objId != Guid.Empty && !coreLibraries.ContainsKey(objId) && !addonLibraries.ContainsKey(objId))
                {
                    var lib = server.FindAssemblyByObject(obj);
                    if (lib != null)
                    {
                        if (lib.IsCoreLibrary)
                            coreLibraries.Add(lib.Id, lib);
                        else
                            addonLibraries.Add(lib.Id, lib);
                    }
                }
            }
        }

        return Tuple.Create(coreLibraries, addonLibraries);
    }

    private string AnalyzeActiveGhDoc()
    {
        int compCount = 0;
        var dictComponents = new Dictionary<string, Dictionary<string, Dictionary<string, int>>>();

        foreach (var obj in Instances.ActiveCanvas.Document.Objects)
        {
            if (obj is IGH_Component)
            {
                var component = obj as IGH_Component;
                var category = component.Category;
                var subCategory = component.SubCategory;
                var name = component.Name;

                if (!dictComponents.ContainsKey(category))
                    dictComponents[category] = new Dictionary<string, Dictionary<string, int>>();

                if (!dictComponents[category].ContainsKey(subCategory))
                    dictComponents[category][subCategory] = new Dictionary<string, int>();

                if (!dictComponents[category][subCategory].ContainsKey(name))
                    dictComponents[category][subCategory][name] = 0;

                dictComponents[category][subCategory][name]++;
                compCount++;
            }
        }

        string username = Environment.UserName;
        string panelText = $"{DateTime.Now.ToString("DATE- yyyy.MM.dd TIME- HH:mmh")}\n";
        panelText += $"Last saved by - {username}\n";
        panelText += $"Total Components - {compCount}\n";

        foreach (var category in dictComponents)
        {
            foreach (var subCategory in category.Value)
            {
                foreach (var comp in subCategory.Value)
                {
                    panelText += $"{category.Key}.{subCategory.Key}.{comp.Key} - {comp.Value}\n";
                }
            }
        }

        return panelText;
    }
    private void RunScript(bool x, ref object a)
    {
        

        if (x)
        {
            var coreLibraries = Libraries().Item1;
            var addonLibraries = Libraries().Item2;

            List<string> adds = new List<string>();
            foreach (var lib in addonLibraries.Values)
            {
                if (!string.IsNullOrEmpty(lib.Name))
                    adds.Add($"{lib.Name} {lib.Version}");
            }

            formatted = string.Join("\n", adds);

            CheckCanvas();
            CheckCanvas2();
        }
    }
      
    
}

Python=

ghenv.Component.Name = "OTools_GetComponents2" 
ghenv.Component.NickName = 'O_GetComps2' 
ghenv.Component.Category = "OTools"
ghenv.Component.SubCategory = "3 | Debugging"
try: ghenv.Component.AdditionalHelpFromDocStrings = "1"
except: pass

import Grasshopper as gh
import System.Drawing as sd
import time
from collections import defaultdict
import sys
import os

comp = ghenv.Component
ghdoc = comp.OnPingDocument()

def get_time():
    # Function to format time
    _t = time.localtime()
    _format = "DATE- %Y.%m.%d TIME- %H:%Mh\n"
    return time.strftime(_format, _t)

def format_dict_info(dictionary, info, level = 0):
    for key, value in dictionary.iteritems():
        _indent = '.'*3*level
        if isinstance(value, dict):
            text_fmt = "%s%s:" %(_indent,key)
            info.append(text_fmt)
            #recursive call here
            format_dict_info(value, info, level + 1)
        else:
            text_fmt = "%s%s - %s" %(_indent,key,value)
            info.append(text_fmt)

def analyze_active_ghdoc():
    try:
        compcount = 0
        #getgrasshopper document
        ghdoc = ghenv.Component.OnPingDocument()
        # create nested dictionary to store component info
        dict_components =  defaultdict(lambda: defaultdict(lambda:defaultdict(int)))
        for obj in ghdoc.Objects:
            if type(obj) is not gh.Kernel.Special.GH_Group: #Fixed this to filter out groups in count
                dict_components[obj.Category][obj.SubCategory][obj.Name] += 1
                compcount = compcount+1

        # Format output text
        username = os.environ['USERNAME']
        panel_text = "%s"%(get_time())
        panel_text += "Last saved by - %s\n" %username
        #panel_text  += "Total Components - %s\n" %(ghdoc.ObjectCount)
        panel_text  += "Total Components - %s\n" %compcount 
        mytext =[]

        format_dict_info(dict_components, mytext)
        for t in mytext:
            panel_text += "%s\n"%t
        return panel_text
        
    except:
        print "Unexpected error:", sys.exc_info()[0]

def CheckCanvas():
    note = False
    for obj in ghenv.Component.OnPingDocument().Objects: # check the components in the definition
        if type(obj) is gh.Kernel.Special.GH_Panel: # check to see if its a panel
            if obj.NickName == "All Components Used": # check the panel name
                print "Found "+obj.NickName+" Panel"
                obj.UserText = analyze_active_ghdoc()
                obj.ExpireSolution(True) # http://www.grasshopper3d.com/forum/topics/triggering-solution-refresh
                note = True
    if note == False:
        print "I didn't find it, I'm just going to make it for you. Soon as you let go of the button, I'll go ahead and add some info....so let go already."
        MakeCompsPanel()
    
def CheckCanvas2():
    note2 = False
    for obj in ghenv.Component.OnPingDocument().Objects: # check the components in the definition
        if type(obj) is gh.Kernel.Special.GH_Panel: # check to see if its a panel
            if obj.NickName == "PlugIns Used": # check the panel name
                print "Found "+obj.NickName+" Panel"
                obj.UserText = formatted
                obj.ExpireSolution(True) # http://www.grasshopper3d.com/forum/topics/triggering-solution-refresh
                note2 = True
    if note2 == False:
        print "I didn't find it, I'm just going to make it for you"
        MakePlugInsPanel()

def MakeCompsPanel():
    #create the panel
    Panel = gh.Kernel.Special.GH_Panel()
    
    #set the panel attributes
    Panel.NickName ="All Components Used"
    Panel.UserText = analyze_active_ghdoc()
    Panel.Properties.Colour = sd.Color.LightSkyBlue
    Panel.Properties.Font = sd.Font("Trebuchet MS", 10)
    Panel.Properties.Multiline = False
    
    #add the panel
    ghdoc.AddObject(Panel,False,ghdoc.ObjectCount+1)
    
    #set the location and size of the panel
    Panel.Attributes.Pivot = sd.PointF(-345,0)
    Panel.Attributes.Bounds = sd.RectangleF(-330,0,330,450)
    
def MakePlugInsPanel():
    #create the panel
    Panel = gh.Kernel.Special.GH_Panel()
    
    #set the panel attributes
    Panel.NickName ="PlugIns Used"
    Panel.UserText = formatted
    Panel.Properties.Colour = sd.Color.LightSkyBlue
    Panel.Properties.Font = sd.Font("Trebuchet MS", 10)
    Panel.Properties.Multiline = False
    
    #add the panel
    ghdoc.AddObject(Panel,False,ghdoc.ObjectCount+1)
    
    #set the location and size of the panel
    Panel.Attributes.Pivot = sd.PointF(-690,0)
    Panel.Attributes.Bounds = sd.RectangleF(-330,0,330,150)
    
def libraries():
    coreLibraries = {}
    addonLibraries = {}
    objids = {}
    
    server = gh.Instances.ComponentServer
    for obj in ghenv.Component.OnPingDocument().Objects:
        
        objId = obj.ComponentGuid
        if objids.has_key(objId): continue
        objids[objId] = ""
        
        lib = server.FindAssemblyByObject(obj)
        if lib == None: continue
        if coreLibraries.has_key(lib.Id) or addonLibraries.has_key(lib.Id): continue
        
        if lib.IsCoreLibrary:
            coreLibraries[lib.Id] = lib
        else:
            addonLibraries[lib.Id] = lib
    return coreLibraries, addonLibraries
    
if x == True:
    coreLibraries, addonLibraries = libraries()
    
    adds = []
    for id, lib in addonLibraries.iteritems():
        if lib.Name != "":
            adds.append("{0} {1}".format(lib.Name, lib.Version))
    formatted = '\n'.join(map(str, adds)) # serialize input _Text list to a formatted string
    print formatted
    
    CheckCanvas()
    CheckCanvas2()

Hi,
I didn’t test but got it to compile by doing the following:

add

private string formatted;

instead of

panel.Font

use

panel.Properties.Font

Same with Colour, and Pivot.
Rename FillColor to Colour

1 Like

Thanks @Alain
In the new script editor, how to display the list of errors in the Out output (params)? Same as old C# Components in Rhino7( grasshopper )(to convert all errors to text

All, the errors were finally solved in this conversion to c# with the help of @Alain - only one error that I don’t know what it is - this error = when X=1 becomes true. Error running script: Exception has been thrown by the target of an invocation.


ot_get Component_edit_.gh (17.6 KB)

@Rh-3d-p

Here is a working example. I will imrove the error reporting:

test_gh_createPanels.ghx (34.6 KB)

1 Like

For reference: RH-80755 ScriptInstance does not throw ExecuteException

1 Like

Thanks @eirannejad i change this function to this and error is fixed: seems tuple data structure is problem Tuple<Dictionary<Guid, GH_AssemblyInfo>,
Component List.gh (15.2 KB)

 /* private Tuple<Dictionary<Guid, GH_AssemblyInfo>, Dictionary<Guid, GH_AssemblyInfo>> Libraries()
    {
        var coreLibraries = new Dictionary<Guid, GH_AssemblyInfo>();
        var addonLibraries = new Dictionary<Guid, GH_AssemblyInfo>();
        var server = Instances.ComponentServer;

        foreach (var obj in Instances.ActiveCanvas.Document.Objects)
        {
            if (obj is IGH_Component)
            {
                var component = obj as IGH_Component;
                var objId = obj.ComponentGuid;

                if (objId != Guid.Empty && !coreLibraries.ContainsKey(objId) && !addonLibraries.ContainsKey(objId))
                {
                    var lib = server.FindAssemblyByObject(obj);
                    if (lib != null)
                    {
                        if (lib.IsCoreLibrary)
                            coreLibraries.Add(lib.Id, lib);
                        else
                            addonLibraries.Add(lib.Id, lib);
                    }
                }
            }
        }

        return Tuple.Create(coreLibraries, addonLibraries);
    }*/

**Change to this :**
     public (Dictionary<Guid, GH_AssemblyInfo>, Dictionary<Guid, GH_AssemblyInfo>) Libraries()
    {
        Dictionary<Guid, GH_AssemblyInfo> coreLibraries = new Dictionary<Guid, GH_AssemblyInfo>();
        Dictionary<Guid, GH_AssemblyInfo> addonLibraries = new Dictionary<Guid, GH_AssemblyInfo>();
        Dictionary<Guid, string> objids = new Dictionary<Guid, string>();

        var server = Grasshopper.Instances.ComponentServer;
        foreach (var obj in GrasshopperDocument.Objects)
        {
            var objId = obj.ComponentGuid;
            if (objids.ContainsKey(objId)) continue;
            objids[objId] = "";

            var lib = server.FindAssemblyByObject(obj);
            if (lib == null) continue;
            if (coreLibraries.ContainsKey(lib.Id) || addonLibraries.ContainsKey(lib.Id)) continue;

            if (lib.IsCoreLibrary)
            {
                coreLibraries[lib.Id] = lib;
            }
            else
            {
                addonLibraries[lib.Id] = lib;
            }
        }
        return (coreLibraries, addonLibraries);
    }

Hi! While a,b=(a,b) is simpler and would be preferred in many cases, I can spot where the original code failed.

var coreLibraries = Libraries().Item1;
var addonLibraries = Libraries().Item2;

The Libraries() is called twice. It should be corrected to

var returnedTuple = Libraries();
var coreLibraries=returnedTuple.Item1;
var addonLibraries = returnedTuple.Item2;
1 Like