/// <summary> /// Utility function that returns the origin plane whose normal is perpendicular to the /// vectors of the specified axes if multiple axes are specified, or the plane /// whose normal is the unit vector of the specified axis if a single axis is specified /// </summary> /// <param name="axis">The axes for which to retrieve the corresponding plane</param> /// <returns>The origin plane that corresponds to the specified axes</returns> private Plane GetPlane(AxisFlags axis) { Plane p = new Plane(); switch (axis) { case AxisFlags.X: case AxisFlags.Y | AxisFlags.Z: p.Normal = Vector3.UnitX; break; case AxisFlags.Y: case AxisFlags.X | AxisFlags.Z: p.Normal = Vector3.UnitY; break; case AxisFlags.Z: case AxisFlags.X | AxisFlags.Y: p.Normal = Vector3.UnitZ; break; } if (mTransform == null) { return(p); } p = (mVectorSpace == VectorSpace.Local) ? (Plane.Transform(p, Matrix.CreateFromQuaternion(mTransform.Rotation) * Matrix.CreateTranslation(mTransform.Translation))) : (Plane.Transform(p, Matrix.CreateTranslation(mTransform.Translation))); return(p); }
private void AddCorner(ProbingViewModel probing, bool negx, bool negy, double XYClearance) { af[GrblConstants.X_AXIS] = negx ? -1d : 1d; af[GrblConstants.Y_AXIS] = negy ? -1d : 1d; axisflags = AxisFlags.X | AxisFlags.Y; Position rapidto = new Position(probing.StartPosition); rapidto.X -= XYClearance * af[GrblConstants.X_AXIS]; rapidto.Y += probing.Offset * af[GrblConstants.Y_AXIS]; rapidto.Z -= probing.Depth; probing.Program.AddRapidToMPos(rapidto, AxisFlags.Y); probing.Program.AddRapidToMPos(rapidto, AxisFlags.X); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Z); probing.Program.AddProbingAction(AxisFlags.X, negx); probing.Program.AddRapidToMPos(rapidto, AxisFlags.X); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.X); rapidto.X = probing.StartPosition.X + probing.Offset * af[GrblConstants.X_AXIS]; rapidto.Y = probing.StartPosition.Y; probing.Program.AddRapidToMPos(rapidto, AxisFlags.X | AxisFlags.Y); rapidto.Y = probing.StartPosition.Values[GrblConstants.Y_AXIS] - XYClearance * af[GrblConstants.Y_AXIS]; probing.Program.AddRapidToMPos(rapidto, AxisFlags.Y); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Z); probing.Program.AddProbingAction(AxisFlags.Y, negy); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Y); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); }
/// <summary> /// Utility function that returns the unit axis in Vector3 format that corresponds to the /// specified axes, oriented based on the vector space of the manipulator /// </summary> /// <param name="axis">The axes for which to retrieve the corresponding unit axis</param> /// <returns>The unit axis that corresponds to the specified axes</returns> private Vector3 GetUnitAxis(AxisFlags axes) { Vector3 unit = Vector3.Zero; if ((axes & AxisFlags.X) == AxisFlags.X) { unit += Vector3.UnitX; } if ((axes & AxisFlags.Y) == AxisFlags.Y) { unit += Vector3.UnitY; } if ((axes & AxisFlags.Z) == AxisFlags.Z) { unit += Vector3.UnitZ; } if (unit != Vector3.Zero) { unit.Normalize(); } // in local vector space, rotate the axis with the transform's // rotation component, otherwise return the axis in its default // form for world vector space unit = ((mVectorSpace == VectorSpace.Local) && (mTransform != null)) ? (Vector3.TransformNormal(unit, Matrix.CreateFromQuaternion(mTransform.Rotation))) : (unit); return(unit); }
private void AddCorner(ProbingViewModel probing, bool negx, bool negy) { string x = negx ? "X" : "X-"; string y1 = negy ? "Y" : "Y-"; string y2 = negy ? "Y-" : "Y"; af[GrblConstants.X_AXIS] = negx ? -1d : 1d; af[GrblConstants.Y_AXIS] = negy ? -1d : 1d; axisflags = AxisFlags.X | AxisFlags.Y; var rapidto = new Position(probing.StartPosition); rapidto.X -= probing.XYClearance * af[GrblConstants.X_AXIS]; rapidto.Y -= probing.Offset * af[GrblConstants.Y_AXIS]; rapidto.Z -= probing.Depth; probing.Program.AddRapidToMPos(rapidto, axisflags); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Z); probing.Program.AddProbingAction(AxisFlags.X, negx); probing.Program.AddRapidToMPos(rapidto, axisflags); rapidto.X = probing.StartPosition.X - probing.Offset * af[GrblConstants.X_AXIS]; rapidto.Y = probing.StartPosition.Y - probing.XYClearance * af[GrblConstants.Y_AXIS]; probing.Program.AddRapidToMPos(rapidto, axisflags); probing.Program.AddProbingAction(AxisFlags.Y, negy); probing.Program.AddRapid(y1 + probing.XYClearance.ToInvariantString()); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); }
protected override void OnHandleDragging(BaseHandle handle, HandleEventData eventData) { base.OnHandleDragging(handle, eventData); var rayOrigin = eventData.rayOrigin; if (handle.IndexOfDragSource(rayOrigin) > 0) { return; } if (handle is RadialHandle) { rotate(eventData.deltaRotation, rayOrigin); } else { AxisFlags constraints = 0; var constrainedHandle = handle as IAxisConstraints; if (constrainedHandle != null) { constraints = constrainedHandle.constraints; } translate(eventData.deltaPosition, rayOrigin, constraints); } }
/// <summary> /// Gets the display color of the specified axis /// </summary> /// <param name="axis">The axis for which to retrieve the display color</param> /// <returns>The display color of the specified axis</returns> public Color GetAxisColor(AxisFlags axis) { switch (axis) { case AxisFlags.X: return(mXAxisColor); case AxisFlags.Y: return(mYAxisColor); case AxisFlags.Z: return(mZAxisColor); case AxisFlags.XY: return(mXYPlaneColor); case AxisFlags.XZ: return(mXZPlaneColor); case AxisFlags.YZ: return(mYZPlaneColor); case AxisFlags.XYZ: return(mUniformColor); } return(Color.Black); }
void Translate(Vector3 deltaPosition, Transform rayOrigin, AxisFlags constraints) { if (m_EligibleForDrag) { transform.position += deltaPosition; } }
public static void MoveTo(this GameObject inMover, GameObject inLocator, AxisFlags inAxes = AxisFlags.XYZ) { if(inLocator == null) return; MoveTo(inMover.transform, inLocator.transform); }
public void Add(double[] values, AxisFlags axisFlags) { foreach (int i in axisFlags.ToIndices()) { switch (i) { case 0: X += values[0]; break; case 1: Y += values[1]; break; case 2: Z += values[2]; break; case 3: A += values[3]; break; case 4: B += values[4]; break; case 5: C += values[5]; break; } } }
private Point3D setEndP(double[] values, AxisFlags axisFlags) { machinePos.Set(values, axisFlags, isRelative); action.End = machinePos.Point3D; return(action.End); }
private new Point3D setEndP(double[] values, AxisFlags axisFlags) { base.setEndP(values, axisFlags); action.End = machinePos.Point3D; return(action.End); }
/// <summary> /// Get a Vector3 corresponding to the axis described by this AxisFlags /// </summary> /// <returns>The axis</returns> public static Vector3 GetAxis(this AxisFlags @this) { return(new Vector3( (@this & AxisFlags.X) != 0 ? 1 : 0, (@this & AxisFlags.Y) != 0 ? 1 : 0, (@this & AxisFlags.Z) != 0 ? 1 : 0 )); }
private Color GetAxisColor(TransformationMode mode, AxisFlags axis) { Color color = (mActiveMode == mode) ? (GetAxisColor(axis)) : (mSettings.GetAxisColor(axis)); return(color); }
/// <summary> /// Utility function that returns the display color of the specified world axis /// </summary> /// <param name="axis">The world axis for which to retrieve the corresponding display color</param> /// <returns>The color of the specified axis</returns> private Color GetAxisColor(AxisFlags axis) { Color color = ((mSelectedAxes & axis) == axis) ? (mSettings.SelectionColor) : (mSettings.GetAxisColor(axis)); return(color); }
/// <summary> /// Perform manipulator snapping: Translate a position vector using deltas while also respecting snapping /// </summary> /// <param name="user">The functionality user</param> /// <param name="rayOrigin">The ray doing the translating</param> /// <param name="transforms">The transforms being translated (used to determine bounds; Transforms do not get modified)</param> /// <param name="position">The position being modified by delta. This will be set with a snapped position if possible</param> /// <param name="rotation">The rotation to be modified if rotation snapping is enabled</param> /// <param name="delta">The position delta to apply</param> /// <param name="constraints">The axis constraints</param> /// <param name="pivotMode">The current pivot mode</param> /// <returns>Whether the position was set to a snapped position</returns> public static bool ManipulatorSnap(this IUsesSnapping user, Transform rayOrigin, Transform[] transforms, ref Vector3 position, ref Quaternion rotation, Vector3 delta, AxisFlags constraints, PivotMode pivotMode) { #if FI_AUTOFILL return default(bool); #else return user.provider.ManipulatorSnap(rayOrigin, transforms, ref position, ref rotation, delta, constraints, pivotMode); #endif }
/// <summary> /// Grab orientation by looking ahead of path, returns rotation in world space. /// </summary> public static Quaternion GetOrientation(OrientMode orientMode, AxisFlags orientLockAxis, Transform trans, TweenPlugPath path, float t) { var lookatPt = GetLookAhead(trans, t, path); if (trans.parent) { lookatPt = trans.parent.TransformPoint(lookatPt); } return(GetOrientation(orientMode, orientLockAxis, trans, lookatPt)); }
private void PreviewOnCompleted() { var probing = DataContext as ProbingViewModel; Position pos = new Position(probing.StartPosition); probing.Program.Clear(); foreach (int i in axisflags.ToIndices()) { pos.Values[i] = probing.StartPosition.Values[i] + (i == GrblConstants.Z_AXIS ? 0d : probing.ProbeDiameter / 2d * af[i]); } if (probing.ProbeZ && axisflags != AxisFlags.Z) { Position pz = new Position(pos); pz.X += probing.ProbeDiameter / 2d * af[GrblConstants.X_AXIS]; pz.Y += probing.ProbeDiameter / 2d * af[GrblConstants.Y_AXIS]; probing.Program.AddRapidToMPos(pz, axisflags); probing.Program.AddProbingAction(AxisFlags.Z, true); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); // pos.Z = probing.Grbl.ProbePosition.Z; } probing.Program.AddRapidToMPos(pos, AxisFlags.Y); probing.Program.AddRapidToMPos(pos, AxisFlags.X); if (probing.ProbeZ) { axisflags |= AxisFlags.Z; } if (probing.CoordinateMode == ProbingViewModel.CoordMode.G92) { probing.Program.AddRapidToMPos(pos, AxisFlags.Z); pos.X = -probing.ProbeOffsetX; pos.Y = -probing.ProbeOffsetY; pos.Z = probing.WorkpieceHeight + probing.TouchPlateHeight; probing.Program.Add("G92" + pos.ToString(axisflags)); if (axisflags.HasFlag(AxisFlags.Z)) { probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); } } else { pos.X += probing.ProbeOffsetX; pos.Y += probing.ProbeOffsetY; pos.Z -= probing.WorkpieceHeight + probing.TouchPlateHeight + probing.Grbl.ToolOffset.Z; probing.Program.Add(string.Format("G10L2P{0}{1}", probing.CoordinateSystem, pos.ToString(axisflags))); } }
public void AddProbingAction(AxisFlags axis, bool negative) { var axisLetter = axis.ToString(); _program.Add(probing.FastProbe + axisLetter + (negative ? "-" : "") + probing.ProbeDistance.ToInvariantString()); if (probing.LatchDistance > 0d) { _program.Add("!G0" + axisLetter + (negative ? "" : "-") + probing.LatchDistance.ToInvariantString()); _program.Add(probing.SlowProbe + axisLetter + (negative ? "-" : "") + probing.ProbeDistance.ToInvariantString()); } }
public void AddProbingAction(AxisFlags axis, bool negative) { var axisLetter = axis.ToString(); _program.Add(probing.FastProbe + axisLetter + (negative ? "-" : "") + probing.ProbeDistance.ToInvariantString()); if (probing.LatchDistance > 0d) { _program.Add("!" + probing.RapidCommand + axisLetter + (negative ? "" : "-") + probing.LatchDistance.ToInvariantString()); _program.Add(probing.SlowProbe + axisLetter + (negative ? "-" : "") + Math.Max((probing.LatchDistance * 1.5d), 2d / probing.Grbl.UnitFactor).ToInvariantString()); } }
private void Pick() { Viewport vp = mGraphics.GraphicsDevice.Viewport; mGraphics.GraphicsDevice.Viewport = mInput.Viewport; mPickBuffer.PushMatrix(MatrixMode.View, ViewMatrix); mPickBuffer.PushMatrix(MatrixMode.Projection, ProjectionMatrix); mPickBuffer.PushMatrix(MatrixMode.World, WorldMatrix); mPickBuffer.PushVertexDeclaration(mVertexDeclaration); foreach (TransformationMode mode in mDrawFunctions.Keys) { TransformationMode local_mode = mode; if ((mEnabledModes & local_mode) != local_mode) { continue; } foreach (AxisFlags flags in mDrawFunctions[local_mode].Keys) { AxisFlags local_flags = flags; mPickBuffer.PushPickID(((uint)local_mode << 8) | (uint)flags); mPickBuffer.QueueRenderFunction(delegate(GraphicsDevice device) { mDrawFunctions[local_mode][local_flags](local_flags); }); mPickBuffer.PopPickID(); } } mPickBuffer.PopVertexDeclaration(); mPickBuffer.PopMatrix(MatrixMode.View); mPickBuffer.PopMatrix(MatrixMode.Projection); mPickBuffer.PopMatrix(MatrixMode.World); // render the pick buffer queue mPickBuffer.Render(); // pick using current mouse position and convert picked // value back into an Axis value (safe, as the default pick buffer // id is 0 (AxisFlags.None) and only AxisFlags values are being rendered as // pick ids in the above render pass uint pick_id = mPickBuffer.Pick(mInput.X, mInput.Y); mSelectedAxes = (AxisFlags)(pick_id & 0xFF); mActiveMode = (TransformationMode)((pick_id >> 8) & 0xFF); mGraphics.GraphicsDevice.Viewport = vp; }
public static IEnumerable <int> ToIndices(this AxisFlags axes) { int i = 0, j = (int)axes; while (j != 0) { if ((j & 0x01) != 0) { yield return(i); } i++; j >>= 1; } }
public static void MoveTo(this Component inMover, Component inLocator, AxisFlags inAxes = AxisFlags.XYZ) { if(inLocator == null) return; Vector3 targetPosition = inMover.transform.position; Vector3 locatorPosition = inLocator.transform.position; if((inAxes & AxisFlags.X) > 0) { targetPosition.x = locatorPosition.x; } if((inAxes & AxisFlags.Y) > 0) { targetPosition.y = locatorPosition.y; } if((inAxes & AxisFlags.Z) > 0) { targetPosition.z = locatorPosition.z; } inMover.transform.position = targetPosition; }
/// <summary> /// Creates a new instance of Manipulator /// </summary> /// <param name="graphics">The IGraphicsDeviceService with which drawing will be performed</param> /// <param name="camera">A provider for camera view and projection data</param> /// <param name="input">A provider for input data</param> public Manipulator(IGraphicsDeviceService graphics, XICamera camera, XIInputProvider input) { mGraphics = graphics; mCamera = camera; mInput = input; mSelectedAxes = AxisFlags.None; mActiveMode = TransformationMode.None; mEnabledModes = TransformationMode.None; mVectorSpace = VectorSpace.World; mPickBuffer = new XPickBuffer(graphics); mSettings = new ManipulatorSettings(); mSettings.RestoreDefaults(); mGraphics.DeviceCreated += new EventHandler(OnDeviceCreated); mGraphics.DeviceReset += new EventHandler(CreateDepthBuffer); mGraphics.DeviceResetting += new EventHandler(DisposeDepthBuffer); mGraphics.DeviceDisposing += new EventHandler(OnDeviceDisposing); if ((mGraphics.GraphicsDevice != null) && !mGraphics.GraphicsDevice.IsDisposed) { OnDeviceCreated(this, null); CreateDepthBuffer(this, null); } mUndoStack = new Stack <TransformState>(); mRedoStack = new Stack <TransformState>(); mDrawFunctions = new DrawFunctions(); mManipFunctions = new ManipFunctions(); mDrawFunctions[TransformationMode.None][AxisFlags.X] = mDrawFunctions[TransformationMode.None][AxisFlags.Y] = mDrawFunctions[TransformationMode.None][AxisFlags.Z] = delegate(AxisFlags axis) { Vector3 unit = GetUnitAxis(axis); XPrimitives.DrawLine(mGraphics.GraphicsDevice, Vector3.Zero, unit); }; InitTranslation(); InitRotation(); InitScale(); }
private void PreviewOnCompleted() { var probing = DataContext as ProbingViewModel; AxisFlags axisflags = (mode == FindMode.XY ? AxisFlags.XY : (mode == FindMode.X ? AxisFlags.X : AxisFlags.Y)); probing.Program.Clear(); probing.Program.AddRapidToMPos(probing.StartPosition, axisflags); if (probing.CoordinateMode == ProbingViewModel.CoordMode.G92) { probing.Program.Add("G92X0Y0"); } else { probing.Program.Add(string.Format("G10L2P{0}{1}", probing.CoordinateSystem, probing.StartPosition.ToString(axisflags))); } }
public void AddPoint(Point3D point, AxisFlags axisflags) { if (axisflags.HasFlag(AxisFlags.X)) { Min[0] = Math.Min(Min[0], point.X); Max[0] = Math.Max(Max[0], point.X); } if (axisflags.HasFlag(AxisFlags.Y)) { Min[1] = Math.Min(Min[1], point.Y); Max[1] = Math.Max(Max[1], point.Y); } if (axisflags.HasFlag(AxisFlags.Z)) { Min[2] = Math.Min(Min[2], point.Z); Max[2] = Math.Max(Max[2], point.Z); } }
private Vector3 LockAxis(Vector3 original, Vector3 changed, AxisFlags axis) { var result = original; var axisIndex = (int)axis; switch (axisIndex) { case -1: result = changed; break; case 1: result.x = changed.x; break; case 2: result.y = changed.y; break; case 3: result.x = changed.x; result.y = changed.y; break; case 4: result.z = changed.z; break; case 5: result.x = changed.x; result.z = changed.z; break; case 6: result.y = changed.y; result.z = changed.z; break; } return(result); }
public void Set(double[] values, AxisFlags axisFlags, bool relative = false) { if (relative) { Add(values, axisFlags); } else { foreach (int i in axisFlags.ToIndices()) { switch (i) { case 0: X = values[0]; break; case 1: Y = values[1]; break; case 2: Z = values[2]; break; case 3: A = values[3]; break; case 4: B = values[4]; break; case 5: C = values[5]; break; } } } }
private void AddEdge(ProbingViewModel probing, char axisletter, bool negative, double XYClearance) { int axis = GrblInfo.AxisLetterToIndex(axisletter); af[axis] = negative ? -1d : 1d; axisflags = GrblInfo.AxisLetterToFlag(axisletter); var rapidto = new Position(probing.StartPosition); rapidto.Values[axis] -= XYClearance * af[axis]; rapidto.Z -= probing.Depth; probing.Program.AddRapidToMPos(rapidto, axisflags); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Z); probing.Program.AddProbingAction(axisflags, negative); rapidto.Values[axis] = probing.StartPosition.Values[axis] - XYClearance * af[axis]; probing.Program.AddRapidToMPos(rapidto, axisflags); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); }
void Translate(Vector3 delta, Transform rayOrigin, AxisFlags constraints) { switch (constraints) { case AxisFlags.X | AxisFlags.Y: case AxisFlags.Y | AxisFlags.Z: case AxisFlags.X | AxisFlags.Z: m_TargetPosition += delta; break; default: m_CurrentlySnapping = this.ManipulatorSnap(rayOrigin, Selection.transforms, ref m_TargetPosition, ref m_TargetRotation, delta, constraints, m_PivotMode); if (constraints == 0) { m_CurrentlySnapping = false; } break; } this.Pulse(this.RequestNodeFromRayOrigin(rayOrigin), m_DragPulse); }
private void AddEdge(ProbingViewModel probing, int offsetAxis, int clearanceAxis, double XYClearance) { AxisFlags probeAxis = GrblInfo.AxisIndexToFlag(clearanceAxis); Position rapidto = new Position(probing.StartPosition); rapidto.Values[clearanceAxis] -= XYClearance * af[clearanceAxis]; rapidto.Z -= probing.Depth; probing.Program.AddRapidToMPos(rapidto, probeAxis); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Z); probing.Program.AddProbingAction(probeAxis, af[clearanceAxis] == -1.0d); probing.Program.AddRapidToMPos(rapidto, probeAxis); rapidto.Values[offsetAxis] = probing.StartPosition.Values[offsetAxis] + probing.Offset * af[offsetAxis]; probing.Program.AddRapidToMPos(rapidto, GrblInfo.AxisIndexToFlag(offsetAxis)); probing.Program.AddProbingAction(probeAxis, af[clearanceAxis] == -1.0d); probing.Program.AddRapidToMPos(rapidto, probeAxis); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.XY); }
private static void ApplyLockAxis(AxisFlags lockAxis, Transform trans, ref Vector3 lookAtPt, out Vector3 up) { Vector3 pt = trans.localPosition; if (lockAxis != AxisFlags.None) { up = Vector3.up; if ((lockAxis & AxisFlags.X) != AxisFlags.None) { Vector3 v0 = trans.InverseTransformPoint(lookAtPt); v0.y = 0; lookAtPt = trans.TransformPoint(v0); } if ((lockAxis & AxisFlags.Y) != AxisFlags.None) { Vector3 v0 = trans.InverseTransformPoint(lookAtPt); if (v0.z < 0) { v0.z = -v0.z; //avoid gimbal lock } v0.x = 0; lookAtPt = trans.TransformPoint(v0); up = trans.up; } if ((lockAxis & AxisFlags.Z) != AxisFlags.None) { up = trans.TransformDirection(Vector3.up); up.z = 0f; up.Normalize(); } } else { up = trans.up; } }
private bool AddCorner(ProbingViewModel probing, bool negx, bool negy, double XYClearance) { af[GrblConstants.X_AXIS] = negx ? -1d : 1d; af[GrblConstants.Y_AXIS] = negy ? -1d : 1d; axisflags = AxisFlags.X | AxisFlags.Y; if (XYClearance > probing.Offset && MessageBox.Show("Offset is less than XY Clearance + ½ Probe/tool diameter.\nUse Offset as clearance and run anyway?", "GCode Sender", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No) { return(false); } XYClearance = Math.Min(XYClearance, probing.Offset); var rapidto = new Position(probing.StartPosition); rapidto.X -= XYClearance * af[GrblConstants.X_AXIS]; rapidto.Y -= probing.Offset * af[GrblConstants.Y_AXIS]; rapidto.Z -= probing.Depth; probing.Program.AddRapidToMPos(rapidto, AxisFlags.X | AxisFlags.Y); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Z); probing.Program.AddProbingAction(AxisFlags.X, negx); probing.Program.AddRapidToMPos(rapidto, AxisFlags.X); rapidto.X = probing.StartPosition.X - probing.Offset * af[GrblConstants.X_AXIS]; rapidto.Y = probing.StartPosition.Y - XYClearance * af[GrblConstants.Y_AXIS]; probing.Program.AddRapidToMPos(rapidto, AxisFlags.X | AxisFlags.Y); probing.Program.AddProbingAction(AxisFlags.Y, negy); probing.Program.AddRapidToMPos(rapidto, AxisFlags.Y); probing.Program.AddRapidToMPos(probing.StartPosition, AxisFlags.Z); return(true); }