diff --git a/src/compute.geometry/GrasshopperDefinition.cs b/src/compute.geometry/GrasshopperDefinition.cs index 2c0bf592..3959238b 100644 --- a/src/compute.geometry/GrasshopperDefinition.cs +++ b/src/compute.geometry/GrasshopperDefinition.cs @@ -313,498 +313,500 @@ public GH_Path GetPath(string p) public void SetInputs(Schema inputSchema) { - var values = inputSchema.Values; - var goos = inputSchema.Goos; - - foreach(var goo in goos) + if(inputSchema.DataFormat == SchemaDataFormat.Grasshopper) { - if (!_input.TryGetValue(goo.ParamName, out var inputGroup)) + foreach (var entry in inputSchema.GrasshopperValues.Values) { - continue; + if (!_input.TryGetValue(entry.Key, out var inputGroup)) + { + continue; + } + inputGroup.Param.ClearData(); + inputGroup.Param.ExpireSolution(false); // mark param as expired but don't recompute just yet! + inputGroup.Param.AddVolatileDataTree(entry.Value); } - inputGroup.Param.ClearData(); - inputGroup.Param.ExpireSolution(false); // mark param as expired but don't recompute just yet! - inputGroup.Param.AddVolatileDataTree(goo.Tree); } - - foreach (var tree in values) + else { - if( !_input.TryGetValue(tree.ParamName, out var inputGroup)) + foreach (var tree in inputSchema.Values) { - continue; - } + if (!_input.TryGetValue(tree.ParamName, out var inputGroup)) + { + continue; + } - if (inputGroup.AlreadySet(tree)) - { - LogDebug("Skipping input tree... same input"); - continue; - } + if (inputGroup.AlreadySet(tree)) + { + LogDebug("Skipping input tree... same input"); + continue; + } - inputGroup.CacheTree(tree); + inputGroup.CacheTree(tree); - IGH_ContextualParameter contextualParameter = inputGroup.Param as IGH_ContextualParameter; - if(contextualParameter != null) - { - var treeAccess = Convert.ToBoolean(contextualParameter.GetType().GetProperty("TreeAccess")?.GetValue(contextualParameter, null)); + IGH_ContextualParameter contextualParameter = inputGroup.Param as IGH_ContextualParameter; if (contextualParameter != null) { - switch (ParamTypeName(inputGroup.Param)) + var treeAccess = Convert.ToBoolean(contextualParameter.GetType().GetProperty("TreeAccess")?.GetValue(contextualParameter, null)); + if (contextualParameter != null) { - case "Boolean": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + switch (ParamTypeName(inputGroup.Param)) + { + case "Boolean": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var b = new GH_Boolean(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(b, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var b = new GH_Boolean(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(b, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Number": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Number": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var d = new GH_Number(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(d, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var d = new GH_Number(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(d, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Integer": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Integer": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var integer = new GH_Integer(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(integer, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var integer = new GH_Integer(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(integer, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Point": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Point": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var p = new GH_Point(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(p, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var p = new GH_Point(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(p, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Plane": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Plane": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var p = new GH_Plane(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(p, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var p = new GH_Plane(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(p, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Line": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Line": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var l = new GH_Line(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(l, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var l = new GH_Line(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(l, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Text": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Text": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - GH_String s; - ResthopperObject restobj = entree.Value[i]; - try - { - // Use JsonConvert to properly unescape the string - s = new GH_String(JsonConvert.DeserializeObject(restobj.Data)); - inputTree.Add(s, path); - } - catch (Exception) + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) { - s = new GH_String(System.Text.RegularExpressions.Regex.Unescape(restobj.Data)); - inputTree.Add(s, path); + GH_String s; + ResthopperObject restobj = entree.Value[i]; + try + { + // Use JsonConvert to properly unescape the string + s = new GH_String(JsonConvert.DeserializeObject(restobj.Data)); + inputTree.Add(s, path); + } + catch (Exception) + { + s = new GH_String(System.Text.RegularExpressions.Regex.Unescape(restobj.Data)); + inputTree.Add(s, path); + } } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; - case "Geometry": - { - Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); - foreach (KeyValuePair> entree in tree) + break; + case "Geometry": { - GH_Path path = GetPath(entree.Key); - for (int i = 0; i < entree.Value.Count; i++) + Grasshopper.DataTree inputTree = new Grasshopper.DataTree(); + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - var dict = JsonConvert.DeserializeObject>(restobj.Data); - var gb = Rhino.Runtime.CommonObject.FromJSON(dict) as GeometryBase; - var goo = GH_Convert.ToGeometricGoo(gb); - inputTree.Add(goo, path); + GH_Path path = GetPath(entree.Key); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + var dict = JsonConvert.DeserializeObject>(restobj.Data); + var gb = Rhino.Runtime.CommonObject.FromJSON(dict) as GeometryBase; + var goo = GH_Convert.ToGeometricGoo(gb); + inputTree.Add(goo, path); + } } + contextualParameter.GetType() + .GetMethod("AssignContextualDataTree")? + .Invoke(contextualParameter, new object[] { inputTree }); } - contextualParameter.GetType() - .GetMethod("AssignContextualDataTree")? - .Invoke(contextualParameter, new object[] { inputTree }); - } - break; + break; + } + continue; } - continue; } - } - - inputGroup.Param.VolatileData.Clear(); - inputGroup.Param.ExpireSolution(false); // mark param as expired but don't recompute just yet! - if (inputGroup.Param is Param_Point) - { - foreach (KeyValuePair> entree in tree) + inputGroup.Param.VolatileData.Clear(); + inputGroup.Param.ExpireSolution(false); // mark param as expired but don't recompute just yet! + + if (inputGroup.Param is Param_Point) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Point3d rPt = JsonConvert.DeserializeObject(restobj.Data); - GH_Point data = new GH_Point(rPt); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Point3d rPt = JsonConvert.DeserializeObject(restobj.Data); + GH_Point data = new GH_Point(rPt); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Vector) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Vector) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Vector3d rhVector = JsonConvert.DeserializeObject(restobj.Data); - GH_Vector data = new GH_Vector(rhVector); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Vector3d rhVector = JsonConvert.DeserializeObject(restobj.Data); + GH_Vector data = new GH_Vector(rhVector); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Integer) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Integer) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - int rhinoInt = JsonConvert.DeserializeObject(restobj.Data); - GH_Integer data = new GH_Integer(rhinoInt); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + int rhinoInt = JsonConvert.DeserializeObject(restobj.Data); + GH_Integer data = new GH_Integer(rhinoInt); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Number) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Number) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - double rhNumber = JsonConvert.DeserializeObject(restobj.Data); - GH_Number data = new GH_Number(rhNumber); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + double rhNumber = JsonConvert.DeserializeObject(restobj.Data); + GH_Number data = new GH_Number(rhNumber); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_String) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_String) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - string rhString = restobj.Data; - GH_String data = new GH_String(rhString); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + string rhString = restobj.Data; + GH_String data = new GH_String(rhString); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Line) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Line) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Line rhLine = JsonConvert.DeserializeObject(restobj.Data); - GH_Line data = new GH_Line(rhLine); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Line rhLine = JsonConvert.DeserializeObject(restobj.Data); + GH_Line data = new GH_Line(rhLine); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Curve) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Curve) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - GH_Curve ghCurve; - try - { - Rhino.Geometry.Polyline data = JsonConvert.DeserializeObject(restobj.Data); - Rhino.Geometry.Curve c = new Rhino.Geometry.PolylineCurve(data); - ghCurve = new GH_Curve(c); - } - catch + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) { - var dict = JsonConvert.DeserializeObject>(restobj.Data); - var c = (Rhino.Geometry.Curve)Rhino.Runtime.CommonObject.FromJSON(dict); - ghCurve = new GH_Curve(c); + ResthopperObject restobj = entree.Value[i]; + GH_Curve ghCurve; + try + { + Rhino.Geometry.Polyline data = JsonConvert.DeserializeObject(restobj.Data); + Rhino.Geometry.Curve c = new Rhino.Geometry.PolylineCurve(data); + ghCurve = new GH_Curve(c); + } + catch + { + var dict = JsonConvert.DeserializeObject>(restobj.Data); + var c = (Rhino.Geometry.Curve)Rhino.Runtime.CommonObject.FromJSON(dict); + ghCurve = new GH_Curve(c); + } + inputGroup.Param.AddVolatileData(path, i, ghCurve); } - inputGroup.Param.AddVolatileData(path, i, ghCurve); } + continue; } - continue; - } - if (inputGroup.Param is Param_Circle) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Circle) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Circle rhCircle = JsonConvert.DeserializeObject(restobj.Data); - GH_Circle data = new GH_Circle(rhCircle); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Circle rhCircle = JsonConvert.DeserializeObject(restobj.Data); + GH_Circle data = new GH_Circle(rhCircle); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Plane) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Plane) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Plane rhPlane = JsonConvert.DeserializeObject(restobj.Data); - GH_Plane data = new GH_Plane(rhPlane); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Plane rhPlane = JsonConvert.DeserializeObject(restobj.Data); + GH_Plane data = new GH_Plane(rhPlane); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Rectangle) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Rectangle) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Rectangle3d rhRectangle = JsonConvert.DeserializeObject(restobj.Data); - GH_Rectangle data = new GH_Rectangle(rhRectangle); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Rectangle3d rhRectangle = JsonConvert.DeserializeObject(restobj.Data); + GH_Rectangle data = new GH_Rectangle(rhRectangle); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Box) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Box) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Box rhBox = JsonConvert.DeserializeObject(restobj.Data); - GH_Box data = new GH_Box(rhBox); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Box rhBox = JsonConvert.DeserializeObject(restobj.Data); + GH_Box data = new GH_Box(rhBox); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Surface) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Surface) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Surface rhSurface = JsonConvert.DeserializeObject(restobj.Data); - GH_Surface data = new GH_Surface(rhSurface); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Surface rhSurface = JsonConvert.DeserializeObject(restobj.Data); + GH_Surface data = new GH_Surface(rhSurface); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Brep) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Brep) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Brep rhBrep = JsonConvert.DeserializeObject(restobj.Data); - GH_Brep data = new GH_Brep(rhBrep); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Brep rhBrep = JsonConvert.DeserializeObject(restobj.Data); + GH_Brep data = new GH_Brep(rhBrep); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Mesh) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Mesh) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - Rhino.Geometry.Mesh rhMesh = JsonConvert.DeserializeObject(restobj.Data); - GH_Mesh data = new GH_Mesh(rhMesh); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + Rhino.Geometry.Mesh rhMesh = JsonConvert.DeserializeObject(restobj.Data); + GH_Mesh data = new GH_Mesh(rhMesh); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is GH_NumberSlider) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is GH_NumberSlider) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - double rhNumber = JsonConvert.DeserializeObject(restobj.Data); - GH_Number data = new GH_Number(rhNumber); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + double rhNumber = JsonConvert.DeserializeObject(restobj.Data); + GH_Number data = new GH_Number(rhNumber); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is Param_Boolean || inputGroup.Param is GH_BooleanToggle) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is Param_Boolean || inputGroup.Param is GH_BooleanToggle) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - bool boolean = JsonConvert.DeserializeObject(restobj.Data); - GH_Boolean data = new GH_Boolean(boolean); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + bool boolean = JsonConvert.DeserializeObject(restobj.Data); + GH_Boolean data = new GH_Boolean(boolean); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; - } - if (inputGroup.Param is GH_Panel) - { - foreach (KeyValuePair> entree in tree) + if (inputGroup.Param is GH_Panel) { - GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); - for (int i = 0; i < entree.Value.Count; i++) + foreach (KeyValuePair> entree in tree) { - ResthopperObject restobj = entree.Value[i]; - string rhString = JsonConvert.DeserializeObject(restobj.Data); - GH_String data = new GH_String(rhString); - inputGroup.Param.AddVolatileData(path, i, data); + GH_Path path = new GH_Path(GhPath.FromString(entree.Key)); + for (int i = 0; i < entree.Value.Count; i++) + { + ResthopperObject restobj = entree.Value[i]; + string rhString = JsonConvert.DeserializeObject(restobj.Data); + GH_String data = new GH_String(rhString); + inputGroup.Param.AddVolatileData(path, i, data); + } } + continue; } - continue; } } - } - public Schema Solve(int rhinoVersion) + public Schema Solve(int rhinoVersion, SchemaDataFormat format) { HasErrors = false; Schema outputSchema = new Schema(); - outputSchema.Algo = ""; + outputSchema.Algo = string.Empty; + outputSchema.DataFormat = format; // solve definition Definition.Enabled = true; @@ -823,11 +825,10 @@ public Schema Solve(int rhinoVersion) if (param == null) continue; - if(param is Param_GenericObject) + if(format == SchemaDataFormat.Grasshopper) { - var tree = (GH_Structure)param.VolatileData; - var outputTree = new GooTree() { ParamName = kvp.Key, Tree = tree }; - outputSchema.Goos.Add(outputTree); + var data = (GH_Structure)param.VolatileData; + outputSchema.GrasshopperValues.Values.Add(kvp.Key, data); } else { @@ -1026,7 +1027,7 @@ public Schema Solve(int rhinoVersion) } - if (outputSchema.Values.Count < 1 && outputSchema.Goos.Count < 1) + if (outputSchema.Values.Count < 1 && outputSchema.GrasshopperValues.Values.Count < 1) throw new System.Exceptions.PayAttentionException("Looks like you've missed something..."); // TODO // Setting warnings and errors to null ever so slightly shrinks down the json sent back to the client @@ -1067,12 +1068,6 @@ private void LogRuntimeMessages(IEnumerable objects, Schema sc static string ParamTypeName(IGH_Param param) { - Type t = param.GetType(); - // TODO: Figure out why the GetGeometryParameter throws exceptions when calling TypeName - if (t.Name.Equals("GetGeometryParameter")) - { - return "Geometry"; - } return param.TypeName; } diff --git a/src/compute.geometry/IO/GhPath.cs b/src/compute.geometry/IO/GhPath.cs index 6a3d4796..5c6eb37f 100644 --- a/src/compute.geometry/IO/GhPath.cs +++ b/src/compute.geometry/IO/GhPath.cs @@ -8,6 +8,7 @@ using Grasshopper.Kernel.Types; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; +using Rhino.Geometry; namespace Resthopper.IO { @@ -82,64 +83,70 @@ public bool LastIndexSame(int i) } } - public class ValueTree - { - public string ParamName { get; set; } - } - - public class GooTree : ValueTree + public class GrasshopperValues { [JsonIgnore] - public Grasshopper.Kernel.Data.GH_Structure Tree; - public string InnerTree + public readonly Dictionary> Values = new Dictionary>(); + public string Data { - get + get { - var base64 = string.Empty; var archive = new GH_Archive(); archive.CreateNewRoot(true); var chunk = archive.GetRootNode; - foreach (var list in Tree.Branches) + foreach (var entry in Values) { - for (int i = 0; i < list.Count; i++) + var param = chunk.CreateChunk(entry.Key); + + foreach (var list in entry.Value.Branches) { - var goo = list[i]; - // Removing ref ID in order to send as internalized geometry - if (goo is IGH_GeometricGoo geometricGoo) + for (int i = 0; i < list.Count; i++) { - geometricGoo = geometricGoo.DuplicateGeometry(); - geometricGoo.ReferenceID = Guid.Empty; - list[i] = geometricGoo; + var goo = list[i]; + // Removing ref ID in order to send as internalized geometry + if (goo is IGH_GeometricGoo geometricGoo && geometricGoo.IsReferencedGeometry) + { + geometricGoo = geometricGoo.DuplicateGeometry(); + geometricGoo.ReferenceID = Guid.Empty; + list[i] = geometricGoo; + } } } + + entry.Value.Write(param); } - Tree.Write(chunk); var binary = archive.Serialize_Binary(); - base64 = Convert.ToBase64String(binary); - return base64; + return Convert.ToBase64String(binary); } - set + set { + Values.Clear(); var base64 = value; var binary = Convert.FromBase64String(base64); var archive = new GH_Archive(); archive.Deserialize_Binary(binary); var chunk = archive.GetRootNode; - Tree = new Grasshopper.Kernel.Data.GH_Structure(); - Tree.Read(chunk); + foreach (var param in chunk.Chunks) + { + var values = new Grasshopper.Kernel.Data.GH_Structure(); + values.Read(param as GH_IReader); + Values.Add(param.Name, values); + } } } } - public class DataTree : ValueTree + public class DataTree { public DataTree() { _tree = new Dictionary>(); //_GhPathIndexer = new Dictionary(); } + public string ParamName { get; set; } + private Dictionary> _tree; //Dictionary _GhPathIndexer; diff --git a/src/compute.geometry/IO/Schema.cs b/src/compute.geometry/IO/Schema.cs index 295cd92e..f74d7c33 100644 --- a/src/compute.geometry/IO/Schema.cs +++ b/src/compute.geometry/IO/Schema.cs @@ -6,6 +6,11 @@ namespace Resthopper.IO { + public enum SchemaDataFormat + { + Resthopper = 0, + Grasshopper = 1 + } public class Schema { public Schema() {} @@ -23,6 +28,10 @@ public Schema() {} [JsonProperty(PropertyName = "dataversion")] public int DataVersion { get; set; } = 7; + // Format of the data being serialized/deserialized + [JsonProperty(PropertyName = "dataformat")] + public SchemaDataFormat DataFormat { get; set; } = SchemaDataFormat.Resthopper; + [JsonProperty(PropertyName = "algo")] public string Algo { get; set; } @@ -41,8 +50,8 @@ public Schema() {} [JsonProperty(PropertyName = "values")] public List> Values { get; set; } = new List>(); - [JsonProperty(PropertyName = "goos")] - public List Goos { get; set; } = new List(); + [JsonProperty(PropertyName = "values-grasshopper")] + public GrasshopperValues GrasshopperValues { get; set; } = new GrasshopperValues(); // Return warnings from GH [JsonProperty(PropertyName = "warnings", DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/compute.geometry/ResthopperEndpoints.cs b/src/compute.geometry/ResthopperEndpoints.cs index 59ce95a3..e243351b 100644 --- a/src/compute.geometry/ResthopperEndpoints.cs +++ b/src/compute.geometry/ResthopperEndpoints.cs @@ -113,7 +113,7 @@ static string GrasshopperSolveHelper(Schema input, string body, System.Diagnosti definition.SetInputs(input); long decodeTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); - var output = definition.Solve(input.DataVersion); + var output = definition.Solve(input.DataVersion, input.DataFormat); output.Pointer = definition.CacheKey; long solveTime = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); diff --git a/src/hops/RemoteDefinition.cs b/src/hops/RemoteDefinition.cs index 3c13683f..f1552a99 100644 --- a/src/hops/RemoteDefinition.cs +++ b/src/hops/RemoteDefinition.cs @@ -556,95 +556,101 @@ public Schema Solve(Schema inputSchema, bool useMemoryCache) public void SetComponentOutputs(Schema schema, IGH_DataAccess DA, List outputParams, HopsComponent component) { - foreach(var goo in schema.Goos) + if(schema.DataFormat == SchemaDataFormat.Grasshopper) { - string outputParamName = goo.ParamName; - if (outputParamName.StartsWith("RH_OUT:")) + foreach (var param in schema.GrasshopperValues.Values) { - var chunks = outputParamName.Split(new char[] { ':' }); - outputParamName = chunks[chunks.Length - 1]; - } - int paramIndex = 0; - for (int i = 0; i < outputParams.Count; i++) - { - if (outputParams[i].Name.Equals(outputParamName)) + string outputParamName = param.Key; + if (outputParamName.StartsWith("RH_OUT:")) { - paramIndex = i; - break; + var chunks = outputParamName.Split(new char[] { ':' }); + outputParamName = chunks[chunks.Length - 1]; } + int paramIndex = 0; + for (int i = 0; i < outputParams.Count; i++) + { + if (outputParams[i].Name.Equals(outputParamName)) + { + paramIndex = i; + break; + } + } + DA.SetDataTree(paramIndex, param.Value); } - DA.SetDataTree(paramIndex, goo.Tree); } - foreach (var datatree in schema.Values) + else { - string outputParamName = datatree.ParamName; - if (outputParamName.StartsWith("RH_OUT:")) + foreach (var datatree in schema.Values) { - var chunks = outputParamName.Split(new char[] { ':' }); - outputParamName = chunks[chunks.Length - 1]; - } - int paramIndex = 0; - for (int i = 0; i < outputParams.Count; i++) - { - if (outputParams[i].Name.Equals(outputParamName)) + string outputParamName = datatree.ParamName; + if (outputParamName.StartsWith("RH_OUT:")) { - paramIndex = i; - break; + var chunks = outputParamName.Split(new char[] { ':' }); + outputParamName = chunks[chunks.Length - 1]; + } + int paramIndex = 0; + for (int i = 0; i < outputParams.Count; i++) + { + if (outputParams[i].Name.Equals(outputParamName)) + { + paramIndex = i; + break; + } } - } - var structure = new Grasshopper.Kernel.Data.GH_Structure(); - Grasshopper.Kernel.Types.IGH_Goo goo = null; + var structure = new Grasshopper.Kernel.Data.GH_Structure(); + Grasshopper.Kernel.Types.IGH_Goo goo = null; - //Determine if the data coming into any of the inputs is a Data Tree - bool hasDataTreeAsInput = false; - foreach(var param in component.Params.Input) - { - if(param.VolatileData.PathCount > 1) + //Determine if the data coming into any of the inputs is a Data Tree + bool hasDataTreeAsInput = false; + foreach (var param in component.Params.Input) { - hasDataTreeAsInput = true; - break; + if (param.VolatileData.PathCount > 1) + { + hasDataTreeAsInput = true; + break; + } } - } - foreach (var kv in datatree.InnerTree) - { - var tokens = kv.Key.Trim(new char[] { '{', '}' }).Split(';'); - List elements = new List(); - if (datatree.InnerTree.Count == 1 && !hasDataTreeAsInput) + foreach (var kv in datatree.InnerTree) { - for (int i = 0; i < tokens.Length; i++) + var tokens = kv.Key.Trim(new char[] { '{', '}' }).Split(';'); + List elements = new List(); + if (datatree.InnerTree.Count == 1 && !hasDataTreeAsInput) { - if (i < tokens.Length - 1) + for (int i = 0; i < tokens.Length; i++) { - if (!string.IsNullOrWhiteSpace(tokens[i])) - elements.Add(int.Parse(tokens[i])); + if (i < tokens.Length - 1) + { + if (!string.IsNullOrWhiteSpace(tokens[i])) + elements.Add(int.Parse(tokens[i])); + } + else + elements.Add(DA.Iteration); } - else - elements.Add(DA.Iteration); } - } - else - { - foreach (var token in tokens) + else { - if (!string.IsNullOrWhiteSpace(token)) - elements.Add(int.Parse(token)); + foreach (var token in tokens) + { + if (!string.IsNullOrWhiteSpace(token)) + elements.Add(int.Parse(token)); + } } - } - var path = new Grasshopper.Kernel.Data.GH_Path(elements.ToArray()); - var localBranch = structure.EnsurePath(path); - for (int gooIndex = 0; gooIndex < kv.Value.Count; gooIndex++) - { - goo = GooFromResthopperObject(kv.Value[gooIndex]); - localBranch.Add(goo); + var path = new Grasshopper.Kernel.Data.GH_Path(elements.ToArray()); + var localBranch = structure.EnsurePath(path); + for (int gooIndex = 0; gooIndex < kv.Value.Count; gooIndex++) + { + goo = GooFromResthopperObject(kv.Value[gooIndex]); + localBranch.Add(goo); + } } + if (structure.DataCount == 1) + DA.SetData(paramIndex, goo); + else + DA.SetDataTree(paramIndex, structure); } - if (structure.DataCount == 1) - DA.SetData(paramIndex, goo); - else - DA.SetDataTree(paramIndex, structure); } foreach (var error in schema.Errors) @@ -1250,6 +1256,7 @@ public Schema CreateSolveInput(IGH_DataAccess DA, bool cacheSolveOnServer, int r warnings = new List(); errors = new List(); var schema = new Resthopper.IO.Schema(); + schema.DataFormat = SchemaDataFormat.Grasshopper; schema.RecursionLevel = recursionLevel; schema.AbsoluteTolerance = GetDocumentTolerance(); schema.AngleTolerance = GetDocumentAngleTolerance(); @@ -1266,12 +1273,11 @@ public Schema CreateSolveInput(IGH_DataAccess DA, bool cacheSolveOnServer, int r string computeName = input.Name; int inputListCount = 0; GH_ParamAccess access = AccessFromInput(input); - if(param is Grasshopper.Kernel.Parameters.Param_GenericObject) + if(schema.DataFormat == SchemaDataFormat.Grasshopper) { var goos = new Grasshopper.Kernel.Data.GH_Structure(); CollectDataHelper(DA, _parentComponent, inputName, input, access, ref inputListCount, goos, ref warnings, ref errors); - schema.Goos.Add(new GooTree() { Tree = goos, ParamName = computeName }); - break; + schema.GrasshopperValues.Values.Add(computeName, goos); } else {