algorithmic modeling for Rhino
Is there a way to have the outputs of the component be added or removed dynamically? I want to bring in a JSON file in a specific format and then create outputs for the various variables existing in the JSON file.
Hopefully that makes sense. Thanks in advance!
Tags:
Hi Ryan,
yes, it is fairly easy to add and remove parameters from a component. There are however some things you should keep in mind:
My recommendation is to have your component implement IGH_VariableParameterComponent and then provide a null implementation. I.e. always return False for CanInsertParameter and CanRemoveParameter. This means the user will not be able to add/remove parameters, but you do get the added benefits of the uber-smart (de)serialization that comes with IGH_VariableParameterComponent.
The next problem you'll face is to decide when to modify your component. As mentioned before, you should not do this during a solution. You have several options:
Let me know if you have further questions once you've decided on an approach that works for you.
--
David Rutten
david@mcneel.com
Poprad, Slovakia
It is not legal to adjust the number of inputs/outputs during a solution. Not. Ever. Naughty boy!
This made me laugh! Ok, points taken. So ultimately, I have created a dynamic Slider application that will create realtime JSON files. A grasshopper component will then read the JSON file and create outputs to be used in the script. I think the best strategy will be to have the user create an output on the component that matches the slider name. This gives the user complete control.
Edit: Actually, looking at this now. I wonder if I can do a combination of #1 above and giving the user control to add or delete them manually. I will begin looking at implementing a IGH_VariableParameterComponent interface.
Thanks!
I am searching for an implementation example of IGH_VariableParameterComponent but I am currently at a loss. I am still learning component creation on the fly so any small example would be great.
Thanks!
- Ryan
IGH_VariableParameterComponent does two things. One, it provides a ZUI (Zooming User Interface) for manually adding and removing parameters. There are a dozen or so components in GH which allow for this, for example Merge and Sort. It provides this ZUI by asking a number of questions which you have to answer. These questions get potentially asked a lot, so make sure your implementation is spiffy. For example, let's assume that we have a component where we want the user to be able to always add inputs, and always remove inputs as well, provided there's at least one left. Outputs are not dynamic.
First of all we need to make sure that GH knows when it's ok to remove or add a parameter:
public bool CanInsertParameter(GH_ParameterSide side, int index)
{
if (side == GH_ParameterSide.Output) return false;
return true;
}
public bool CanRemoveParameter(GH_ParameterSide side, int index)
{
if (side == GH_ParameterSide.Output) return false;
if (this.Params.Input.Count < 2) return false;
return true;
}
Which is just the English I wrote before implemented in C# (outputs can never be added/removed, inputs can only be removed if we'll end up with at least one of em). If you don't want users to be able to do this manually, just return false for both and you will never see the ZUI.
The above methods are used to decide whether or not to draw the little plus and minus symbols on the canvas when zoomed in on a component. However when the users clicks on one of these symbols, a lot more needs to happen. When a parameter is to be added, you need to provide this parameter. Also, when a parameter is about to be deleted, you need to ok this (though ideally, if it's not ok, you shouldn't have returned true from within CanRemoveParameter).
public IGH_Param CreateParameter(GH_ParameterSide side, int index)
{
return new Grasshopper.Kernel.Parameters.Param_GenericObject();
}
public bool DestroyParameter(GH_ParameterSide side, int index)
{
//If you need to take additional action, now's the time.
return true;
}
Ok, so far so good. All our inputs are generic parameters so we just need to return a new Param_GenericObject. If you want integers, return Param_Integer instead. Note that I haven't assigned a name, nickname, access or description to this parameter. That is because I will implement one final method which will take care of all this. You could of course give the parameter a name, nickname etc. etc. depends on the kind of component you're writing.
Ultimately, there's a cleanup method which gives you last say when it comes to your parameters. This method is called when a ZUI action completes but also when the component finishes reading from a file. If you want to make sure your parameters are set up correct, this is the ideal place to do so:
public void VariableParameterMaintenance()
{
for (int i = 0; i < Params.Input.Count; i++)
{
IGH_Param param = Params.Input[i];
param.Name = string.Format("Input {0}", i);
param.NickName = string.Format("{0}", i);
param.Access = GH_ParamAccess.list;
param.Optional = true;
param.MutableNickName = false;
}
}
Basically, I iterate over all input parameters and make sure they all have correct names, nicknames, access flags, optional flags etc. etc.
The second thing IGH_VariableParameterComponent does (bet you you've forgotten all about part 2 haven't you?) is provide a more extensive (de)serialization. Regular components rely on RegisterInputParams and RegisterOutputParams to populate the input and output lists. Then all the parameters that have been created are asked to read themselves from the gh archive. However this doesn't work with variable parameter components as it is not obvious how many parameters there are supposed to be.
If your component implements the IGH_VariableParameterComponent interface then additional information will be written to the gh files which allows the component to correctly resurrect itself from a file.
--
David Rutten
david@mcneel.com
Poprad, Slovakia
David,
Man, all I wanted was a "little" example. Fantastic explanation! This gets me where I need to be, and I am sure it will help anyone in the future with these same problems.
Thank you so much!
David,
I've been trying to implement this above code in combination with FileSystemWatcher (c#) events and am finding that the methods work for the most part but after a number of events Rhino and Grasshopper freeze up.
I'm not sure but there might be a bug somewhere...
The freeze behavior seems to be triggered when multiple events happen at once, or very close to one another.
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by