Resthopper: Client-side .ghx composition POC

Question at the top: is there a way to parse Grasshopper.dll (or some other source) for information about all components? Specifically the gh_guid, input count, and output count.

I’ve been studying the .ghx structure since the hackathon. Just finished a quick POC for the client-side “dynamically composed definitions” thing I was preaching about. It can take this syntax:

syntax

And, with a simple little Request.send(uri, definition) helper, can return:

It abstracts away the schema and all the grouping stuff so you can work with components and parameters directly. Which is nice. The prospect of attaching grasshopper logic to any web frontend gets me all excited. But if you check out the code, you’ll see that it only works with the multiplication component and the number parameter. To get this to work I had to manually map component names to their grasshopper metadata.

I really don’t mind chiseling away at the list and adjusting the syntax for strange cases. But it feels like it’d make more sense to do some code generation based on the grasshopper source, kind of like what rhino3dm does now.

1 Like

Already talked w/ you about this on twitter, linking the thread here for completeness: https://twitter.com/andrewheumann/status/1191000427694874624?s=20

tl;dr there’s a script for that: ClassDocumentator_2.5.gh (22.6 KB)

2 Likes

Edit for batsignal: @DavidRutten

Got the following (limited?) result when parsing Grasshopper.dll in \Rhino 6\Plug-ins\Grasshopper\. Do you know if the standard grasshopper component library is stored somewhere else?

GH_Cluster
GH_ValueTimeline
GH_Cluster_OBSOLETE
GH_Legend
GH_GradientControl
GH_TaskCapableComponent`1
GH_DocExampleComponent
GH_MetaBallComponent
GH_MetaBallComponentThreshold
GH_MetaBallComponentThresholdEx
GH_CleanTreeComponent_OBSOLETE
GH_CleanTreeComponent_OSBOLETE_AS_WELL
GH_CleanTreeComponent
GH_IsNullDataComponent_OBSOLETE
GH_PruneTreeComponent
GH_GraftTreeComponent_OBSOLETE
GH_GraftTreeComponent
GH_SimplifyTreeComponent_OBSOLETE
GH_SimplifyTreeComponent
GH_FlattenTreeComponent_OBSOLETE
GH_FlattenTreeComponent
GH_UnflattenTreeComponent
GH_TrimTreeComponent
GH_MatchTreeComponent
GH_ReplacePathComponent
GH_ExplodeTreeComponent_OBSOLETE
GH_ExplodeTreeComponent
GH_FlipDataMatrixComponent
GH_ShiftDataPathComponent
GH_GroupGeometryComponent
GH_UngroupGeometryComponent
GH_MergeGroupComponent
GH_SplitGroupComponent
GH_DataDamComponent
GH_SmoothNumbersComponent
GH_ReadFileComponent
GH_PathCompareComponent
GH_TreeSplitComponent
GH_StreamFilterComponent_OBSOLETE
GH_StreamFilterComponent
GH_StreamGateComponent_OBSOLETE
GH_StreamGateComponent
GH_CustomPreviewComponent
GH_CurvatureGraphComponent
GH_PointListComponent
GH_TextTag3DComponent_OBSOLETE
GH_TextTag3DComponent_OBSOLETE_AS_WELL
GH_TextTag3DComponent
GH_TextTagComponent_OBSOLETE
GH_TextTagComponent

Was having issues with Grasshopper.dll trying to load a bunch of external dependencies like System.Windows.Forms. Code used:

var path = new FileInfo(@".\dll\Grasshopper.dll");
var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path.FullName);

try {
    Console.WriteLine(assembly.GetTypes());
}
catch (ReflectionTypeLoadException e) {
    e.Types
    .Where(t => t != null)
    .Where(t => t.IsSubclassOf(typeof(GH_Component)))
    .ToList()
    .ForEach(t => Console.WriteLine(t.Name));
}

Edit:

I opened my eyes and found the Grasshopper\Components\ folder. But their results are still a bit confusing. Here’s ALL types from MathComponents.dll for example:

MyProject
Resources
MySettingsProperty
AbstractGenericOperator
SubtractionUpdater
MultiplicationUpdater
NumberComparison
InfinityComparer
OperandPair
OperatorDelegate
Operation
Addition
Subtraction
Multiplication
Upgrader_ListItem
OffsetMethod
Upgrade_NullInvalidComponent
Upgrade_WeaveComponent
Upgrade_PickNChooseComponent
Component_MatchListAbstract
Component_SortListAttributes_OBSOLETE
Upgrade_SortList
Upgrade_SortList2
AndGateUpgrader1
AndGateUpgrader2
OrGateUpgrader1
OrGateUpgrader2
ColourUtil
Component_ColourAddition_OBSOLETE
Component_SubtractColours_OBSOLETE
Component_MultiplyColours_OBSOLETE
VariantType
Component_Evaluate_Attributes
RemapNumberUpgrader
AbstractFunctionComponentAttributes
ExpressionComponentAttributes_OBSOLETE
IGH_QuickCastTable
<PrivateImplementationDetails>
MyWebServices
ThreadSafeObjectProvider`1
RangeType
SequenceSolver
Sequence
NumberType
ItemOptimization
WrapOptimization
TrimMode
PaddingMode
CrossMode
Interpolation
Calendar
ClockHand
DragMode
__StaticArrayInitTypeSize=40

And the ones that pass assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(GH_Component)));

AbstractGenericOperator
Component_MatchListAbstract
Component_ColourAddition_OBSOLETE
Component_SubtractColours_OBSOLETE
Component_MultiplyColours_OBSOLETE

Yes, most components are part of several gha files shipped with grasshopper. If you have access to GH at runtime, you can use the Grasshopper.Instances.ComponentServer to find all loaded components and parameters (and other objects such as groups, scribbles, jumps etc.)

1 Like

Perfect, will give that a try now. Thanks for the quick assist.

Snippet that works in the grasshopper C# component, for posterity. I struggled a bit before realizing what ObjectProxies were. You could not have made it any easier for me. Massive thanks.

    var gha = Grasshopper.Instances.ComponentServer.Libraries;
    
    var names = new List<string>();
    var ids = new List<string>();
    
    var proxies = Grasshopper.Instances.ComponentServer.ObjectProxies;
    
    for (int i = 0; i < proxies.Count; i++) {
      ids.Add(proxies[i].Guid.ToString());
      names.Add(proxies[i].Desc.Name);
    }
    
    var z = ids.IndexOf(ids.Find(w => w.IndexOf("ce46b74e-00c9-43c4-805a-193b69ea4a11") >= 0));

    A = names[z];
    B = ids[z];

The last part was me confirming with a guid I already knew. Will attempt the codegen with a compute server tomorrow evening. I have work in a few hours :upside_down_face:

1 Like

The previous post opened up a lot of possibilities. Resthopper can now compose definitions “implicitly” (similar to SetData / GetData in C#):

The indexes there are just referencing a pile of classes for each component. So, resthopper can also compose “explicitly,” with all the autocomplete and security that comes with it:


Time to generate “everything” and see what happens. The library is also limited to one input per parameter right now. Still trying to better understand how more complex data trees translate to .ghx and, then, how to represent that in javascript.

End goal is not to just be able type out grasshopper definitions, even though that’s kind of funny. Going to tie this up to a little UI and see where we can go.

3 Likes