Is it possible to get data from custom input parameters?

Hey guys,

I’m writing a custom loft component and wondering if its possible to reuse the original “Loft Options” component? I’m assuming there is no access to the source code, so it seems there’s no way to get values out of the data. Don’t have too much hope for this one, but maybe there is way. :slight_smile:

What does the component do? those options might not work for what you are trying to make as an output. What is a split loft?

That class is probably defined in the surface.gha file. So yes, reusing it will be tricky. You may have to resort to some serious reflection, or maybe serialise the data.

@Michael_Pryor Just a regular loft, but splitting the curves beforehand at the tangents, as you have with the Rhino loft command.

@DavidRutten Ok thats what I thought. It would be easy enough to make my own loft options component, but would be nice to avoid that, seeing that my search bar is starting to get cluttered up with duplicate components from different plugins. Do you have any resources on how to serialize for this particular purpose? Not familiar at all with how it works.Thx!

This should work, Note that if your GHA assembly is loaded before the Surface.gha assembly, you will not yet be able to emit a loft options parameter.

    protected override void RegisterInputParams(GH_InputParamManager pManager)
    {
      pManager.AddCurveParameter("Sections", "S", "Section curves", GH_ParamAccess.list);

      var optionsId = new Guid("{A8DA9901-F5FB-49ec-9CD1-DFA7B788263E}");
      var options = Grasshopper.Instances.ComponentServer.EmitObject(optionsId) as IGH_Param;
      if (options is null)
        return;

      options.Access = GH_ParamAccess.item;
      pManager.AddParameter(options);
    }

and inside SolveInstance():

    protected override void SolveInstance(IGH_DataAccess access)
    {
      var sections = new List<Curve>();
      if (!access.GetDataList(0, sections)) return;

      object options = null;
      if (!access.GetData(1, ref options)) return;
      if (options is null) return;

      var adjustSeams = (bool)Grasshopper.Utility.InvokeGetter(options, "AdjustSeams");
      var closedLoft = (bool)Grasshopper.Utility.InvokeGetter(options, "ClosedLoft");
      var rebuildCount = (int)Grasshopper.Utility.InvokeGetter(options, "RebuildCount");
      var refitTolerance = (double)Grasshopper.Utility.InvokeGetter(options, "RefitTolerance");
      var loftType = (int)Grasshopper.Utility.InvokeGetter(options, "LoftType");
      var loftFit = (int)Grasshopper.Utility.InvokeGetter(options, "LoftFit");

      // loftType: Rhino.Geometry.LoftType
      // loftFit: 0=none, 1=rebuild, 2=refit

      access.SetData(0, $"AdjustSeams={adjustSeams}, ClosedLoft={closedLoft}, RebuildCount={rebuildCount}, RefitTolerance={refitTolerance}, Type={loftType}, Fit={loftFit}");
    }
3 Likes

Amazing! Thank you so much!

So to clarify, the GUID and the property names used in the InvokeGetter() method are not retrievable unless you have the source code, is that correct? Just wondering if the same principle can be applied to other components in the future.

You can reflect them. Inspect these values inside the debugger too.