Feature Request: Additional programmatic Grasshopper plugin loading options

Hi there @stevebaer, @scottd, and @kike!! It has been a few moments since we covered this topic at the last TT AEC, but I finally got around to trying to automate silent loading of a GH script with a HumanUI using the methods we talked about. Will document my attempts here and I’m hoping we can get something to work so people can build slick apps on top of Rhino/GH with killer UX.

So… I’ve been playing around with the Rhinoscript interface for Grasshopper and it looks like so far my hopes have been dashed on what I’d like to accomplish. To recap, here is the goal:

  • Create a Rhino Plugin that contains 1 command, which can be run via command line or via a button in an RUI toolbar
  • The command launches Grasshopper (with absolutely no visible evidence of Grasshopper) and opens a Grasshopper script with a HumanUI interface (again, without triggering any visible instance of Grasshopper)
  • The script nonetheless executes when operating the HumanUI (this is the hard part, as we will see), despite there being no GH window

I’ve been using the API doc methods here:
https://developer.rhino3d.com/api/grasshopper/html/M_Grasshopper_Plugin_GH_RhinoScriptInterface_HideEditor.htm

I’ve noticed several problems with the methods in the API, with respect to what I’d like to accomplish:

  • DisableBanner(): This is great and a welcome method – however, I would like to also be able to enable silent loading (no echo in the Rhino Command Line). Even better (amazing, actually) would be providing an overload that would allow me to define my own custom splash screen (Waaaaaaat!)
  • LoadEditor(): Again, love that the Load function is separate from the Show function, and simple tests show that it is possible o “Load” grasshopper without the window appearing. However, the behavior of other methods crushes the hopes and dreams that I had when looking at the documentation
  • OpenDocument(): And here’s where the tears start to flow. From the API docs: “Open a Grasshopper document. The editor will be loaded if necessary, but it will not be automatically shown.” Well in my case, using this method on a script that I have built with full HumanUI (no GH interaction necessary), regardless of whether I call LoadEditor() first, it does indeed automatically show the editor.
  • HideEditor(): There’s hope still! Perhaps if I hide the editor first, before opening the document! Nope, disappointment ensues. Okay, so maybe I’m disappointed that the Editor does in fact show during the load process, but I do have a script within my GH definition that automatically minimizes the editor so it’s not blocking my UI. At least I can use HideEditor() to get rid of that pesky GH window minimized at the bottom of the Rhino UI, right? A flicker of joy, as I successfully hide the GH window entirely – “this is it!!!” I think, and then deep sadness sets in as I push a button and nothing happens, as it appears that when the GH editor is hidden, it no longer functions (at least with my intensely insane script)
  • EnableSolver(): Perhaps I can enable the solver on a hidden GH instance! Nope.

:slight_smile: :slight_smile: :slight_smile:

Anyway, just thought I would do a dramatic retelling of my last 20 minutes for fun. H’s a sample of the code I’m using so you can point out any stupid mistakes I’m making:

        dynamic gh = RhinoApp.GetPlugInObject("Grasshopper");
        gh.DisableBanner();
        gh.LoadEditor();
        gh.HideEditor();
        gh.OpenDocument(appGhFilePath);
        //gh.HideEditor();

Tried various combinations and orderings here. Main fixes would seem to include:

  • HideEditor(): Not disabling the GH execution context in this state (easier said than done?)
  • OpenDocument(): overload with a flag to prevent editor from showing automatically, or fixing the bug that does force it to show, or document in which cases it will automatically show, etc – also good compromise would be the ability to load in minimized state (never seeing the full GH window), a function not currently provided by the API (and would get me almost all the way to my goal)
  • DisableBanner(): overload that allows silent load (no Rhino command line echo)

Cheers,
Marc

In personal projects, I use Harmony as a workaround to hook window-related functions (System.Windows.Forms and now Eto) to prevent Grasshopper from being shown. Generally, it’s a complicated procedure.

HideEditor doesn’t hide the editor alone, it also closes the window, that’s what may prevent the execution context. Maybe try Visible = false?

As for Human UI, I forget whether Human UI uses GH or Rhino as its parent window. If its parent is GH, you would need more adjustments.

Interesting, I’d love to see a project where you’ve accomplished that, if you don’t mind sharing.

Yes, indeed “Hide” appears to simply close the window. Regarding Visible = false – the RS interface doesn’t implement Property accessors directly, AFAICT, only methods, and I am inferring that “Visible” in this context refers to whether the window is Hidden or not.

HumanUI can be set to Always on Top, or to use GH or Rhino as a parent (I usually tend to use the latter, so WPF parent relationships shouldn’t be an issue if I muck with GH)…

All that said, I would hope that a few strategic tweaks to the provided Interface could solve these challenges without having to dig in at Harmony’s level…

Cheers,
Marc

You can show any window you like for whatever period you like if your command is triggered.

1 Like

I’ll run your example code to see what function is trying to be too clever for its own good.

1 Like

I suppose that’s true – of course, would be nice to have a convenience method, but there are more important things for you all to worry about. :slight_smile:

Any thoughts on this? Still looking to clean up the GH launch routine for my applications.

Thanks!

Marc