Grasshopperのカスタムコンポーネントで、GH_ParamAccess.ItemでInputを定義したらリスト型のデータは受け取らないって思ってません?私は思ってました。
GH_ParamAccess.ItemのInputは1つの値を受け取るので、イメージとしては図のような対応。
ところが、GH_ParamAccess.Itemとしていても、仕組みとしてリストのデータも渡せてしまうようです。
コンポーネントはリストからアイテムを1個ずつ順番に受け取って処理しています。コンポーネントからはデータが1つだけ送られてくるように見えます。
これで出力先ががリスト型を受け取れるコンポーネントなら矛盾なく処理できます。良くできてますね。
1個に制限したい
しかし、データは1個だけ受け取りたいケースもあります。実際1個しかデータ受け取らない前提でカスタムコンポーネントを書いていたら破綻しました。困ったな。
カスタムコンポーネントで受け取ったGeometryに合せてInputを動的に追加、削除する処理をしていました。
リストでまとまってきちゃうと、最後のGeometryの条件でInputを追加削除しちゃうんですよね。
敢えてListで受け取る
発想を変えて、逆にはじめからリストで受け取って、複数個のデータがきたらエラーで処理するように変えてみました。
データを1個に制限するのに、Inputはリストにするのは変な感じがしますが、うまくいきました。
ソースコードの例はこちら↓
/// <summary>
/// Registers all the input parameters for this component.
/// </summary>
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
//pManager.AddBrepParameter("Brep", "B", "Input Brep", GH_ParamAccess.item);
pManager.AddBrepParameter("Brep list", "L", "Input Brep", GH_ParamAccess.list);
}
/// <summary>
/// Registers all the output parameters for this component.
/// </summary>
protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
}
/// <summary>
/// This is the method that actually does the work.
/// </summary>
/// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
protected override void SolveInstance(IGH_DataAccess DA)
{
List<Brep> breps = new List<Brep>();
if (!DA.GetDataList(0, breps) || breps == null)
return;
if (breps.Count > 1)
{
AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Please input only one item.");
return;
}
// From here, write code limited to one piece of data
}
動作環境
以下の環境で動作を確認しています。
- Windows11 Pro(64bit, 23H2)
- Rhinoceros 8 SR9
- Visual Studio Professional 2022(17.10.3)