Compute Grasshopper Text parameters fail unless Type explicitly set

Hi @will ,

I am using C# to send grasshopper scripts to Rhino.Compute for solving.
I have been using the following pattern advised in your samples:

  var trees = new List<GrasshopperDataTree>();    
  var value1 = new GrasshopperObject(10);
  var param1 = new GrasshopperDataTree("RH_IN:Radius");
  param1.Add("0", new List<GrasshopperObject> { value1 } );
  trees.Add(param1);  
  var result = Rhino.Compute.GrasshopperCompute.EvaluateDefinition(definitionPath, trees);

Note that the above suggested code in the samples doesn’t bother to set the type of the parameter.
Whilst this has worked well for most of my scripts that have numeric parameters I have found that it is insufficient for Text Parameters.

My scripts with Text Parameters fail silently unless I explicitly set the type using:

  var trees = new List<GrasshopperDataTree>();    
  var value2 = new GrasshopperObject("Hello World");
  var param2 = new GrasshopperDataTree("RH_IN:MyTextParameter");

  param2.Type = GH_Types.gh_string.ToString();

  param2.Add("0", new List<GrasshopperObject> { value2 } );
  trees.Add(param2);  
  var result = Rhino.Compute.GrasshopperCompute.EvaluateDefinition(definitionPath, trees);

Am I using an out of date methodology? - Is it because I am using “RH_IN:” groups rather than the components themselves (I think i read somewhere that is the old way to do things)?

please advise
dan

The GrasshoppDataTree is a custom class which you can look at if you pull down the compute repo and look at Rhino.Compute.cs in the compute.geometry project (around line 12168). Anyway, the constructor of that class looks like this:

public GrasshopperDataTree(string paramName)
{
    ParamName = paramName;
    _tree = new Dictionary<string, List<GrasshopperObject>>();
}

As far as I know, it doesn’t really care about the type because it’s just creating a dictionary with a list of GrasshopperObject. It’s the GrasshopperObject that should be controlling the type (I think). Looking at that class (around line 12006 in the same file), you can see the constructor looks like this

public GrasshopperObject(object obj)
{
    this.Data = JsonConvert.SerializeObject(obj, GeometryResolver.Settings);
    this.Type = obj.GetType().FullName;
}

So, it should theoretically be setting the type there since you’re passing in a string… but I’m unsure why it seems to fail in your case. What happens if you instantiate your value 2 like this?

var value2 = new GrasshopperObject(new GH_String("Hello World"));

Thanks @AndyPayne - my simplification above masked what I was really doing but your drawing attention to what’s happening in the constructor has helped…
So in my samples above i showed value1 and value2 = new GrasshopperObject(explicit var) but in my actual code I am looping through a list of values = List<object> :

myValues = List<object> ; // populated in previous methods as generic objects.
foreach(object o in myValues)
{
     var value = new GrasshopperObject(o); 
     ...
}

and the methods that populated myValues list was not always setting the underlying type to be more specific – having refactored to ensure each element in my list is converted or cast to its correct underlying type before calling new GrasshopperObject() my issue is resolved.
My bad.

1 Like