Check if a type of IGH_Goo can be casted to other type of IGH_Goo

I want to put a parameter C from code to be the recipient of a parameter A and the source of a parameter B, where before A and B were connected (bridging a wire). I only want to do this when it makes sense according to the data types (IGH_Goo) of A, B and C (IGH_Param), checking whether A-C makes sense and C-B makes sense. This sense is the data conversion logic of GH. I need a function that takes two IGH_Param and returns a boolean which determines if GH can connect them without conversion errors.

I have this, it works well sometimes, as integer to number, but it does not work for example from curve to number, throwing a null reference exception (in toGoo.CastFrom(fromGoo)). I am using a scripting component for debugging purposes.

My logic has been to create an instance of the data type of the two candidate parameters to connect in order to use the IGH_Goo.CastFrom() method.

Any clue how to make this right? Thank you!

 try{
  IGH_Param From = this.Component.Params.Input[0].Sources[0];
  IGH_Param To = this.Component.Params.Input[1].Sources[0];

  IGH_Goo fromGoo;
  if (From.Type == typeof(IGH_Goo) || To.Type == typeof(IGH_GeometricGoo)) fromGoo = new Grasshopper.Kernel.Types.GH_ObjectWrapper();
  else fromGoo = Activator.CreateInstance(From.Type) as IGH_Goo;
  if (fromGoo == null) { Print("fromGoo: null"); return; }
  else {Print("fromGoo: {0}", fromGoo.TypeName);}

  IGH_Goo toGoo;
  if (To.Type == typeof(IGH_Goo) || To.Type == typeof(IGH_GeometricGoo)) toGoo = new Grasshopper.Kernel.Types.GH_ObjectWrapper();
  else toGoo = Activator.CreateInstance(To.Type) as IGH_Goo;
  if (toGoo == null) { Print("toGoo null"); return; }
  else {Print("toGoo: {0}", toGoo.TypeName);}

  Print("CanCast: {0}", toGoo.CastFrom(fromGoo).ToString());

}catch(Exception e){
  Print(e.ToString()); 
}

Check if a type of IGH_Goo can be casted to other type of IGH_Goo.gh (4.8 KB)

This is not possible. Whether or not a conversion is defined actually depends on the state of the data, not just the type. Curves can be converted to Rectangles, but only if they look like rectangles to begin with. Strings can be converted to Integers, but only if they represent an expression that evaluates to a numeric value.

I see, thank you. Then I have to go through the IGH_Goo in From.VolatileData and see if they are convertible to toGoo like this? I have a feeling this is pretty gooey…

 IGH_Param From = this.Component.Params.Input[0].Sources[0];
  IGH_Param To = this.Component.Params.Input[1].Sources[0];
  
  IGH_Goo toGoo;
  if (To.Type == typeof(IGH_Goo) || To.Type == typeof(IGH_GeometricGoo)) toGoo = new Grasshopper.Kernel.Types.GH_ObjectWrapper();
  else toGoo = Activator.CreateInstance(To.Type) as IGH_Goo;
  if (toGoo == null) { Print("toGoo null"); return; }
  else {Print("toGoo: {0}", toGoo.TypeName);}

  foreach(IGH_Goo goo in From.VolatileData.AllData(false)){
    Print("CanCast: {0}", toGoo.CastFrom(goo).ToString());
  }

Gooey and slow. Plus it only works for the current state of the data.

And CastTo or CastFrom are methods on the data types thmeselves, the parameters may choose to add additional conversion logic.

I think what you want is not really possible/doable. You will either have to come up with a set of predefined type pairs you know work (or want to support), or make sure that the changes you’re making are easy to undo.