// This C# project calls the STEP-NC API using the .NET interface. It // prints all tool moves in a machining program. // // You can find more examples and other documentation at: // // http://www.steptools.com/support/ // using System; using STEPNCLib; namespace MyCNC { class Program { static void Main(string[] args) { Finder finder = new Finder(); Adaptive ctl = new Adaptive(); // Read a model and traversing the process finder.OpenProject("digital_thread_model.stpnc"); ctl.StartProject(); // Select some process events to respond to. We will emit // codes for individual tool moves and tool changes. We // will also note begin/end of operations. ctl.SetWanted(Adaptive.CtlEvent.MOVE); ctl.SetWanted(Adaptive.CtlEvent.TOOL_CHANGE); ctl.SetWanted(Adaptive.CtlEvent.OPERATION_START); ctl.SetWanted(Adaptive.CtlEvent.OPERATION_END); // other process event are available, some include: // ctl.SetWanted(Adaptive.CtlEvent.EXEC_WORKPLAN_START); // ctl.SetWanted(Adaptive.CtlEvent.EXEC_WORKPLAN_END); // ctl.SetWanted(Adaptive.CtlEvent.TOOLPATH_START); // The Move event is the only one selected by default while (ctl.Next() != Adaptive.CtlEvent.DONE) { long id; switch (ctl.Event()) { case Adaptive.CtlEvent.EXEC_WORKPLAN_START: id = ctl.GetActiveWorkplan(); Console.WriteLine("STARTING WORKPLAN #{0} [{1}]", id, finder.GetExecutableName(id)); break; case Adaptive.CtlEvent.EXEC_WORKPLAN_END: Console.WriteLine("ENDING WORKPLAN #{0}", ctl.GetActiveWorkplan()); break; case Adaptive.CtlEvent.OPERATION_START: id = ctl.GetActiveExec(); Console.WriteLine("STARTING OPERATION #{0} (workstep #{1}) [{2}]", ctl.GetActiveOperation(), id, finder.GetExecutableName(id)); break; case Adaptive.CtlEvent.OPERATION_END: id = ctl.GetActiveExec(); Console.WriteLine("Ending OPERATION #{0} (workstep #{1}) [{2}]", ctl.GetActiveOperation(), id, finder.GetExecutableName(id)); break; case Adaptive.CtlEvent.TOOL_CHANGE: id = ctl.GetActiveExec(); long tool_id = ctl.GetActiveTool(); bool dummy; Console.WriteLine("T{0}", finder.GetToolNumber (tool_id, out dummy)); break; case Adaptive.CtlEvent.MOVE: id = ctl.GetActiveExec(); switch (ctl.GetActiveType()) { case Adaptive.CtlType.MOVE: printend(ctl, ctl.GetMoveEnd()); break; case Adaptive.CtlType.MOVE_ARC: printarc(ctl, ctl.GetMoveArc()); break; case Adaptive.CtlType.MOVE_HELIX: Console.WriteLine("HELIX MOVE"); printarc(ctl, ctl.GetMoveArc()); printend(ctl, ctl.GetMoveEnd()); break; } break; default: Console.WriteLine("UNEXPECTED EVENT"); break; } } } static double old_feed = 0; static double x = 9999.99; static double y = 9999.99; static double z = 9999.99; static void printend(Adaptive ctl, uint p) { double a, b, c; ctl.GetPosXYZ(out a, out b, out c, p); if (a == x && b == y && c == z) return; if (ctl.GetMoveIsRapid()) { Console.Write("G0"); if (x != a) Console.Write(" X{0:0.0####}", a); if (y != b) Console.Write(" Y{0:0.0####}", b); if (z != c) Console.Write(" Z{0:0.0####}", c); } else { double feed = ctl.GetMoveFeed(); if (feed != old_feed) { Console.WriteLine("F{0:0.0####}", feed); old_feed = feed; } Console.Write("G1"); if (x != a) Console.Write(" X{0:0.0####}", a); if (y != b) Console.Write(" Y{0:0.0####}", b); if (z != c) Console.Write(" Z{0:0.0####}", c); } if (ctl.GetPosDirZ(out a, out b, out c, p)) { // Tool tilt is stored as IJK in part space. Some controls can use // directly, like Siemens TRAORI A3/B3/C3=, or FANUC G43.5 TCP mode. // For others, we can calculate AC/BC/AB angles. Console.Write(" I{0:0.0####} J{1:0.0####} K{2:0.0####}", a, b, c); } Console.WriteLine(); x = a; y = b; z = c; } // Print arc center, radius, and direction for an arc move // static void printarc(Adaptive ctl, uint p) { double a, b, c; ctl.GetPosXYZ(out a, out b, out c, p); if (ctl.GetArcIsCW(p)) Console.Write("G2"); else Console.Write("G3"); Console.Write(" X{0:0.0####} Y{1:0.0####} Z{2:0.0####}", a, b, c); Console.Write(" R{0:0.0####}", ctl.GetArcRadius(p)); // can also get angle, helix height, test for 180+, full circle etc Console.WriteLine(); } } }