public static object readArbitraryResult(IKernelLink ml, GH_Component component) { Object exprOrObjectResult = null; ILinkMark mark = ml.CreateMark(); try { exprOrObjectResult = ml.GetObject(); } catch (MathLinkException) { ml.ClearError(); ml.SeekMark(mark); // Technically, GetExpr() should never throw MathLinkException. But there was at least one bug I found and fixed where it did. // So to be safe we leave this try/catch here, otherwise the link will get in a bad state. try { Expr ex = ml.GetExpr(); exprOrObjectResult = new ExprType(ex); } catch (MathLinkException) { ml.ClearError(); component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error reading result as an Expr. This is a bug in RhinoLink, not the user program."); } } finally { ml.DestroyMark(mark); ml.NewPacket(); } return(exprOrObjectResult); }
/// <summary> /// Returns true if all branches have the same number of elements, and each element is /// equal/similar under epsilon tolerance. /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="comp"></param> /// <param name="epsilon"></param> /// <returns></returns> internal static bool EqualDataTreeContent(GH_Structure <T> A, GH_Structure <T> B, GH_Component comp, double epsilon = 0) { // Compare number of items in each branch. var bA = A.Branches; var bB = B.Branches; for (int i = bA.Count - 1; i >= 0; i--) { if (bA[i].Count != bB[i].Count) { return(false); } } // Figure out data types and branch down to a different comparison method try { Type type = typeof(T); if (type == BOOL_TYPE) { return(EqualBoolData(A as GH_Structure <GH_Boolean>, B as GH_Structure <GH_Boolean>)); } else if (type == INT_TYPE) { return(EqualIntData(A as GH_Structure <GH_Integer>, B as GH_Structure <GH_Integer>)); } else if (type == NUMBER_TYPE) { return(EqualNumData(A as GH_Structure <GH_Number>, B as GH_Structure <GH_Number>, epsilon)); } else if (type == POINT_TYPE) { return(EqualPointData(A as GH_Structure <GH_Point>, B as GH_Structure <GH_Point>, epsilon)); } else if (type == VECTOR_TYPE) { return(EqualVectorData(A as GH_Structure <GH_Vector>, B as GH_Structure <GH_Vector>, epsilon)); } else if (type == PLANE_TYPE) { return(EqualPlaneData(A as GH_Structure <GH_Plane>, B as GH_Structure <GH_Plane>, epsilon)); } else if (type == LINE_TYPE) { return(EqualLineData(A as GH_Structure <GH_Line>, B as GH_Structure <GH_Line>, epsilon)); } else if (type == TEXT_TYPE) { return(EqualTextData(A as GH_Structure <GH_String>, B as GH_Structure <GH_String>)); } } catch { comp.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went wrong with the data here..."); } // If here, something went wring with comparison, so flag false for an update return(false); }
public static bool ConnectToFrame(GH_Component com, out Animation.Frame frameComponent) { if (Animation.Frame.Component == null || Animation.Frame.Component.OnPingDocument() != com.OnPingDocument()) { com.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Please Set Frame Component First!"); frameComponent = null; return(false); } else if (Animation.Frame.Component.Params.Input[0].SourceCount == 0) { com.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Please Finish Frame Component!"); frameComponent = null; return(false); } else { frameComponent = Animation.Frame.Component; return(true); } }
public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e) { try { _doubleClickAction(); } catch (Exception ex) { _component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, ex.Message); } return(base.RespondToMouseDoubleClick(sender, e)); }
public static string ReadVariable(ref Socket clientSocket, string variableRead, GH_Component component) { if (clientSocket == null) { throw new ArgumentNullException(nameof(clientSocket)); } if (variableRead == null) { throw new ArgumentNullException(nameof(variableRead)); } if (component == null) { throw new ArgumentNullException(nameof(component)); } byte[] messageReq = ReadMessageRequest(variableRead, out var outputString); byte[] receivedData = new byte[256]; int receivedBytes = 0; try //Try to receive message. { int sentBytes = clientSocket.Send(messageReq); //Request a specific message according to VarRead variable component.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Sent:" + sentBytes.ToString() + " bytes as " + outputString); component.Message = "Sent"; receivedBytes = clientSocket.Receive(receivedData); //Receive data back. } catch (SocketException e) { component.ClearRuntimeMessages(); component.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Your connection is abruptly closed by the host, make sure to check your cables and if the server is running."); } catch (ArgumentNullException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Read Variable :{0}" + e.ToString()); } catch (ObjectDisposedException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Read Variable :{0}" + e.ToString()); } catch (SecurityException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Write Variable Receive :{0}" + e.ToString()); } //Format received data to extract value. MessageReceiveFormat response = new MessageReceiveFormat(receivedData); component.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Received:" + receivedBytes.ToString() + " bytes as" + response._varValue); component.Message = "Received"; return(response._varValue); }
public static string WriteVariable(ref Socket clientSocket, string variableWrite, string dataWrite, GH_Component component) { if (clientSocket == null) { throw new ArgumentNullException(nameof(clientSocket)); } if (variableWrite == null) { throw new ArgumentNullException(nameof(variableWrite)); } if (dataWrite == null) { throw new ArgumentNullException(nameof(dataWrite)); } if (component == null) { throw new ArgumentNullException(nameof(component)); } byte[] messageReq = WriteMessageRequest(variableWrite, dataWrite, out string outputString); byte[] receivedData = new byte[256]; int receivedBytes = 0; try { int sentBytes = clientSocket.Send(messageReq); component.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Sent:" + sentBytes.ToString() + " bytes as " + outputString); component.Message = "Sent"; receivedBytes = clientSocket.Receive(receivedData); } catch (SocketException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "SocketException :{0}" + e.ToString()); } catch (ArgumentNullException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Write Variable :{0}" + e.ToString()); } catch (ObjectDisposedException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Write Variable :{0}" + e.ToString()); } catch (SecurityException e) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Write Variable Receive :{0}" + e.ToString()); } MessageReceiveFormat response = new MessageReceiveFormat(receivedData); component.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Received:" + receivedBytes.ToString() + " bytes as " + response._varValue); component.Message = "Received"; return(response._varValue); }
public static double RemapByType(double t, int type, GH_Component com) { switch (type) { case 0: return(t); case 1: double domainForSigmoid = 6; double realSig = 1 / (1 + Math.Pow(Math.E, domainForSigmoid - 2 * domainForSigmoid * t)); return((realSig - 0.5) / (1 - 2 / (1 + Math.Pow(Math.E, domainForSigmoid))) + 0.5); case 2: return(0); case 3: return(1); default: com.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Input Type must be in 0-3!"); return(t); } }
/// <summary> /// Display the error message if the conversion failed /// </summary> private void ShowInputsError() { ghc.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, Constants.Constants.INPUT_ERROR_MESSAGE); }
// M code must ensure that the only types that can arrive in this function are ones that are currently handled here. public static bool ReadAndStoreResult(string type, int index, IKernelLink link, IGH_DataAccess DA, GH_ParamAccess accessType, GH_Component component) { try { switch (accessType) { case GH_ParamAccess.item: { object res = ReadSingleItemAsType(type, link); DA.SetData(index, res); break; } case GH_ParamAccess.list: { ILinkMark mark = link.CreateMark(); int length = 1; bool isList = false; try { length = link.CheckFunction("List"); isList = true; } catch (MathLinkException) { link.ClearError(); } finally { link.SeekMark(mark); link.DestroyMark(mark); } if (isList) { IList list = ReadListOfItemsAsType(type, link); DA.SetDataList(index, list); } else { object item = ReadSingleItemAsType(type, link); DA.SetData(index, item); } break; } case GH_ParamAccess.tree: { // Quick and dirty method. Only support numbers. Read as Expr, then use Dimensions, etc. // TODO: Handle objects. See how it is done in ReadSingleItemAsType(). // This read-as-expr method shows problems for tree type. It would be better, for tree, to not use // the expr, but rather re-read the data from the link (as is done for item, list). In the curremt // method, I don't see any good way to handle "Any". // WAIT, IT'S WORSE. Expr.AsArray() only does Integer, Real, and only up to depth 2. ILinkMark mark = link.CreateMark(); try { Expr e = link.GetExpr(); int[] dims = e.Dimensions; if (dims.Length == 0) { link.SeekMark(mark); object res = ReadSingleItemAsType(type, link); DA.SetData(index, res); } else if (dims.Length == 1) { link.SeekMark(mark); IList list = ReadListOfItemsAsType(type, link); DA.SetDataList(index, list); } else if (dims.Length == 2) { // This code could be cleaner with GH_Structure, but I dont quite understand that class... switch (type) { case "Number": { DataTree <double> tree = new DataTree <double>(); Array dataArray = e.AsArray(ExpressionType.Real, 2); for (int i = 0; i < dims[0]; i++) { GH_Path pth = new GH_Path(i); for (int j = 0; j < dims[1]; j++) { tree.Add((double)dataArray.GetValue(i, j), pth); } } DA.SetDataTree(index, tree); break; } case "Integer": { DataTree <int> tree = new DataTree <int>(); Array dataArray = e.AsArray(ExpressionType.Integer, 2); for (int i = 0; i < dims[0]; i++) { GH_Path pth = new GH_Path(i); for (int j = 0; j < dims[1]; j++) { tree.Add((int)dataArray.GetValue(i, j), pth); } } DA.SetDataTree(index, tree); break; } default: // Can't handle this. return(false); } } else { // TODO. At least set a RuntimeMessage before returning false. return(false); } } finally { link.DestroyMark(mark); } break; // Problem with the read-and-fill-element-by-element approach is that this is a GH_Structure<IGH_Goo>, // so I need to create an IGH_Goo pbjectout of every piece of data. But there are zillions of IGH_Goo // objects out there. I don't want to map every object to its IGH_Goo type (e.g., Circle --> GH_Circle). // For lists, I could simply create a List<anything> and apparently it gets converted to the appopriate // IGH_Goo object later on. But with trees, I don't see the corresponding technique. Compare the signature // of DA.SetDataList() and DA.SetDataTree(). /* * ILinkMark mark3 = link.CreateMark(); * int length = 1; * try { * length = link.CheckFunction("List"); * // Don't catch; allow to fail. Must be a list arriving for tree results. * } finally { * link.DestroyMark(mark3); * } * GH_Structure<IGH_Goo> structure = new GH_Structure<IGH_Goo>(); * GH_Path path = new GH_Path(0); * int pathLen = 1; * int pathIndex = 0; * for (int i = 0; i < length; i++) { * if (isListWaitingOnLink(link)) { * path. * } else { * structure.Append( * } * } */ } } } catch (Exception) { component.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unexpected type of result from Wolfram Engine"); link.ClearError(); link.NewPacket(); return(false); } return(true); }