I'd like to bundle parameters into a single wire without (too much) boilerplate

Too much boilerplate is a relative term but I don’t want to have to deal with geometric goo or anything that involves: writing classes, deriving from classes, overriding X virtual methods, etc. YUK! I’m far too lazy for that - it was fun in the 80s (no it wasn’t: it was never fun)

I’ve tried the merge component, and trees but I’m writing custom components in C# so, for me, the least effort path seems to be, Get McNeel to:

  1. invent an IGH_DataAccess parameter for custom components
  2. write a Grasshopper component that looks like the merge component only its output is a IGH_DataAccess.
  3. add AddDataAccessParameter to the GH_InputParamManager, and GH_OutputParamManager classes

I can then do something like this:

Without bundling I might write something like this in every class that uses those parameters

    protected override void RegisterInputParams(GH_InputParamManager pManager)
    {
        pManager.AddBrepParameter("LowestDeck", "LowestDeck", "LowestDeck", GH_ParamAccess.item);
        pManager.AddVectorParameter("DeckVector", "DeckVector", "DeckVector", GH_ParamAccess.item);
        pManager.AddNumberParameter("OuterRadius", "OuterRadius", "OuterRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("InnerRadius", "InnerRadius", "InnerRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("PipeRadius", "PipeRadius", "PipeRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("ArcCornerRadius", "ArcCornerRadius", "ArcCornerRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("TriangleBaseRadius", "TriangleBaseRadius", "TriangleBaseRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("PadOuterRadius", "PadOuterRadius", "PadOuterRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("PadInnerRadius", "PadInnerRadius", "PadInnerRadius", GH_ParamAccess.item);
        pManager.AddNumberParameter("DoorStepRadius", "DoorStepRadius", "DoorStepRadius", GH_ParamAccess.item);
    }

    protected override void SolveInstance(IGH_DataAccess DA)
    {
        Brep LowestDeck = null;
        Vector3d DeckVector = new Vector3d();
        double innerRadiusNumber  = 0;
        double outerRadiusNumber  = 0;
        double pipeRadiusNumber         = 0;
        double arcCornerRadiusNumber    = 0;
        double triangleBaseRadiusNumber = 0;
        double padInnerRadiusNumber     = 0;
        double padOuterRadiusNumber     = 0;
        double doorStepRadiusNumber     = 0;
        {
            int inputIndex = 0;

            DA.GetData<Brep>(inputIndex++, ref LowestDeck);
            DA.GetData<Vector3d>(inputIndex++, ref DeckVector);

            DA.GetData<double>(inputIndex++, ref outerRadiusNumber       );
            DA.GetData<double>(inputIndex++, ref innerRadiusNumber);
            DA.GetData<double>(inputIndex++, ref pipeRadiusNumber        );
            DA.GetData<double>(inputIndex++, ref arcCornerRadiusNumber   );
            DA.GetData<double>(inputIndex++, ref triangleBaseRadiusNumber);
            DA.GetData<double>(inputIndex++, ref padOuterRadiusNumber    );
            DA.GetData<double>(inputIndex++, ref padInnerRadiusNumber);
            DA.GetData<double>(inputIndex++, ref doorStepRadiusNumber    );
        }

With bundling I could write:

protected override void RegisterInputParams(GH_InputParamManager pManager)
{
    pManager.AddBrepParameter("LowestDeck", "LowestDeck", "LowestDeck", GH_ParamAccess.item);
    pManager.AddVectorParameter("DeckVector", "DeckVector", "DeckVector", GH_ParamAccess.item);
    pManager.AddDataAccessParameter("KP", "KeyParameters", "Bundled Key Parameters", GH_ParamAccess.item);
}

protected override void SolveInstance(IGH_DataAccess DA)
{
    Brep LowestDeck = null;
    Vector3d DeckVector = new Vector3d();
    double innerRadiusNumber  = 0;
    double outerRadiusNumber  = 0;
    double pipeRadiusNumber         = 0;
    double arcCornerRadiusNumber    = 0;
    double triangleBaseRadiusNumber = 0;
    double padInnerRadiusNumber     = 0;
    double padOuterRadiusNumber     = 0;
    double doorStepRadiusNumber     = 0;

    DA.GetData<Brep>(0, ref LowestDeck);
    DA.GetData<Vector3d>(1, ref DeckVector);
    {
        IGH_DataAccess keyDA = null;
        DA.GetData<IGH_DataAccess>(2, ref keyDA);

        int inputIndex = 0;

        keyDA.GetData<double>(inputIndex++, ref outerRadiusNumber       );
        keyDA.GetData<double>(inputIndex++, ref innerRadiusNumber);
        keyDA.GetData<double>(inputIndex++, ref pipeRadiusNumber        );
        keyDA.GetData<double>(inputIndex++, ref arcCornerRadiusNumber   );
        keyDA.GetData<double>(inputIndex++, ref triangleBaseRadiusNumber);
        keyDA.GetData<double>(inputIndex++, ref padOuterRadiusNumber    );
        keyDA.GetData<double>(inputIndex++, ref padInnerRadiusNumber);
        keyDA.GetData<double>(inputIndex++, ref doorStepRadiusNumber    );
    }

For me the code is almost the same with or without parameter bundling. I could start off without it and then convert to bundling if I think it’s worth it.

It has no more boilerplate than not using bundling.