/** Copyright (C) 2012-2018 by Autodesk, Inc. All rights reserved. WinPC-NC post processor configuration. $Revision: 42267 13d826b34503344f783e15c8e23378994271f93c $ $Date: 2019-03-08 15:06:59 $ FORKID {B8184849-2A4D-42E5-A651-1270582D3E42} */ description = "WinPC-NC"; vendor = "WinPC-NC"; vendorUrl = "http://www.lewetz.de"; legal = "Copyright (C) 2012-2018 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 40783; longDescription = "Generic post for machines using WinPC-NC control software. If you are using a fourth axis, make sure to select which axis it is mounted along. If you have an automatic tool changer, enable the property 'useToolChanger'. If you need the feedrates in mm/s, please set the property 'useUnitPerSecondFeedrates' to true."; extension = "nc"; setCodePage("ascii"); capabilities = CAPABILITY_MILLING; tolerance = spatial(0.002, MM); minimumChordLength = spatial(0.25, MM); minimumCircularRadius = spatial(0.01, MM); maximumCircularRadius = spatial(1000, MM); minimumCircularSweep = toRad(0.01); maximumCircularSweep = toRad(180); allowHelicalMoves = true; allowedCircularPlanes = 1 << PLANE_XY; // allow only XY circular motion // user-defined properties properties = { writeMachine: true, // write machine writeTools: true, // writes the tools showSequenceNumbers: true, // show sequence numbers sequenceNumberStart: 10, // first sequence number sequenceNumberIncrement: 1, // increment for sequence numbers separateWordsWithSpace: true, // specifies that the words should be separated with a white space useToolChanger: false, // specifies that a tool changer is available /* toolChangePositionX: 0, // specifies the tool change position for X toolChangePositionY: 0, // specifies the tool change position for Y */ fourthAxisAround: "none", // specifies which axis the 4th axis is mounted along useUnitPerSecondFeedrates: false, // specifies to output feedrate in unit/seconds instead of unit/min /*referenceRun: true*/ // move to reference point first at the beginning of the program reverseZAxis: true // postive Z moves down in Z when set to true }; // user-defined property definitions propertyDefinitions = { writeMachine: {title:"Write machine", description:"Output the machine settings in the header of the code.", group:0, type:"boolean"}, writeTools: {title:"Write tool list", description:"Output a tool list in the header of the code.", group:0, type:"boolean"}, showSequenceNumbers: {title:"Use sequence numbers", description:"Use sequence numbers for each block of outputted code.", group:1, type:"boolean"}, sequenceNumberStart: {title:"Start sequence number", description:"The number at which to start the sequence numbers.", group:1, type:"integer"}, sequenceNumberIncrement: {title:"Sequence number increment", description:"The amount by which the sequence number is incremented by in each block.", group:1, type:"integer"}, separateWordsWithSpace: {title:"Separate words with space", description:"Adds spaces between words if 'yes' is selected.", type:"boolean"}, useToolChanger: {title:"Use tool changer", description:"Specifies that a tool changer is available.", type:"boolean"}, // toolChangePositionX: {title:"Tool change position X", description:"X-axis tool change position.", type:"number"}, // toolChangePositionY: {title:"Tool change position Y", description:"Y-axis tool change position.", type:"number"}, fourthAxisAround: {title:"Fourth axis mounted along", description:"Specifies which axis the fourth axis is mounted on.", type:"enum", values:[{id:"none", title:"None"}, {id:"x", title:"Along X"}, {id:"y", title:"Along Y"}]}, useUnitPerSecondFeedrates: {title:"Feedrate output per second", description:"If enabled, the feedrate output is set to units/sec rather than units/min.", type:"boolean"}, reverseZAxis: {title:"Reverse Z-axis direction", description:"If enabled, positive Z-output moves down in the Z-axis.", type:"boolean"} }; var singleLineCoolant = false; // specifies to output multiple coolant codes in one line rather than in separate lines // samples: // {id: COOLANT_THROUGH_TOOL, on: 88, off: 89} // {id: COOLANT_THROUGH_TOOL, on: [8, 88], off: [9, 89]} var coolants = [ {id: COOLANT_FLOOD, on: 8}, {id: COOLANT_MIST, on: 7}, {id: COOLANT_THROUGH_TOOL}, {id: COOLANT_AIR}, {id: COOLANT_AIR_THROUGH_TOOL}, {id: COOLANT_SUCTION}, {id: COOLANT_FLOOD_MIST}, {id: COOLANT_FLOOD_THROUGH_TOOL}, {id: COOLANT_OFF, off: 9} ]; var gFormat = createFormat({prefix:"G", decimals:1, width:2, zeropad:true}); var mFormat = createFormat({prefix:"M", decimals:0, width:2, zeropad:true}); var hFormat = createFormat({prefix:"H", decimals:0}); var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var zFormat; // defined in onOpen var abcFormat = createFormat({decimals:3, forceDecimal:true, scale:DEG}); var feedFormat = createFormat({decimals:(unit == MM ? 1 : 2)}); var toolFormat = createFormat({decimals:0}); var rpmFormat = createFormat({decimals:0}); var secFormat = createFormat({decimals:3, forceDecimal:true}); // seconds - range 0.001-1000 var milliFormat = createFormat({decimals:0}); // milliseconds - range 1-? var taperFormat = createFormat({decimals:1, scale:DEG}); var pitchFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true}); var xOutput = createVariable({prefix:"X"}, xyzFormat); var yOutput = createVariable({prefix:"Y"}, xyzFormat); var zOutput; // defined in onOpen var aOutput = createVariable({prefix:"A"}, abcFormat); var bOutput = createVariable({prefix:"B"}, abcFormat); var cOutput = createVariable({prefix:"C"}, abcFormat); var feedOutput = createVariable({prefix:"F"}, feedFormat); var sOutput = createVariable({prefix:"S", force:true}, rpmFormat); var pitchOutput = createVariable({prefix:"K", force:true}, pitchFormat); // circular output var iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat); var jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat); var kOutput = createReferenceVariable({prefix:"K", force:true}, xyzFormat); var gMotionModal = createModal({force:true}, gFormat); // modal group 1 // G0-G3, ... // var gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19 var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-22 var gCycleModal = createModal({}, gFormat); // modal group 9 // G81, ... var WARNING_WORK_OFFSET = 0; // collected state var sequenceNumber; var currentWorkOffset; var retracted = false; // specifies that the tool has been retracted to the safe plane /** Writes the specified block. */ function writeBlock() { if (!formatWords(arguments)) { return; } if (properties.showSequenceNumbers) { writeWords2("N" + sequenceNumber, arguments); sequenceNumber += properties.sequenceNumberIncrement; } else { writeWords(arguments); } } function formatComment(text) { return "(" + String(text).replace(/[[\]]/g, "") + ")"; } /** Output a comment. */ function writeComment(text) { writeln(formatComment(text)); } function onOpen() { if (properties.reverseZAxis) { zFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true, scale:-1}); } else { zFormat = createFormat({decimals:(unit == MM ? 3 : 4), forceDecimal:true, scale:1}); } zOutput = createVariable({onchange:function () {retracted = false;}, prefix:"Z"}, zFormat); if (properties.fourthAxisAround != "none") { var aAxis = createAxis({coordinate:0, table:true, axis:[(properties.fourthAxisAround == "x" ? 1 : 0), (properties.fourthAxisAround == "y" ? 1 : 0), 0], cyclic:false, range:[-360.0001, 360.0001], preference:0}); machineConfiguration = new MachineConfiguration(aAxis); setMachineConfiguration(machineConfiguration); optimizeMachineAngles2(1); // map tip mode } if (!machineConfiguration.isMachineCoordinate(0)) { aOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(1)) { bOutput.disable(); } if (!machineConfiguration.isMachineCoordinate(2)) { cOutput.disable(); } if (properties.useUnitPerSecondFeedrates) { if (unit == IN) { error(localize("Feedrates per seconds is not supported for INCH mode. Please set the property 'useUnitPerSecondFeedrates' to false.")); return; } feedFormat.setScale(1/60); // mm/min feedOutput = createVariable({prefix:"F"}, feedFormat); } if (!properties.separateWordsWithSpace) { setWordSeparator(""); } sequenceNumber = properties.sequenceNumberStart; writeln("%"); if (programName) { writeComment(programName); } if (programComment) { writeComment(programComment); } // dump machine configuration var vendor = machineConfiguration.getVendor(); var model = machineConfiguration.getModel(); var description = machineConfiguration.getDescription(); if (properties.writeMachine && (vendor || model || description)) { writeComment(localize("Machine")); if (vendor) { writeComment(" " + localize("vendor") + ": " + vendor); } if (model) { writeComment(" " + localize("model") + ": " + model); } if (description) { writeComment(" " + localize("description") + ": " + description); } } // dump tool information if (properties.writeTools) { var zRanges = {}; if (is3D()) { var numberOfSections = getNumberOfSections(); for (var i = 0; i < numberOfSections; ++i) { var section = getSection(i); var zRange = section.getGlobalZRange(); var tool = section.getTool(); if (zRanges[tool.number]) { zRanges[tool.number].expandToRange(zRange); } else { zRanges[tool.number] = zRange; } } } var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { for (var i = 0; i < tools.getNumberOfTools(); ++i) { var tool = tools.getTool(i); var comment = "T" + toolFormat.format(tool.number) + " " + "D=" + xyzFormat.format(tool.diameter) + " " + localize("CR") + "=" + xyzFormat.format(tool.cornerRadius); if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { comment += " " + localize("TAPER") + "=" + taperFormat.format(tool.taperAngle) + localize("deg"); } if (zRanges[tool.number]) { comment += " - " + localize("ZMIN") + "=" + xyzFormat.format(zRanges[tool.number].getMinimum()); } comment += " - " + getToolTypeName(tool.type); writeComment(comment); } } } if ((getNumberOfSections() > 0) && (getSection(0).workOffset == 0)) { for (var i = 0; i < getNumberOfSections(); ++i) { if (getSection(i).workOffset > 0) { error(localize("Using multiple work offsets is not possible if the initial work offset is 0.")); return; } } } // absolute coordinates writeBlock(gAbsIncModal.format(90)); /* if (properties.referenceRun) { writeBlock(gFormat.format(28.1)); } */ switch (unit) { case IN: writeBlock(gUnitModal.format(70)); break; case MM: writeBlock(gUnitModal.format(71)); break; } } function onComment(message) { writeComment(message); } /** Force output of X, Y, and Z. */ function forceXYZ() { xOutput.reset(); yOutput.reset(); zOutput.reset(); } /** Force output of A, B, and C. */ function forceABC() { aOutput.reset(); bOutput.reset(); cOutput.reset(); } /** Force output of X, Y, Z, A, B, C, and F on next output. */ function forceAny() { forceXYZ(); forceABC(); forceFeed(); } function forceFeed() { currentFeedId = undefined; feedOutput.reset(); } function onParameter(name, value) { } var currentWorkPlaneABC = undefined; function forceWorkPlane() { currentWorkPlaneABC = undefined; } function setWorkPlane(abc) { if (!machineConfiguration.isMultiAxisConfiguration()) { return; // ignore } if (!((currentWorkPlaneABC == undefined) || abcFormat.areDifferent(abc.x, currentWorkPlaneABC.x) || abcFormat.areDifferent(abc.y, currentWorkPlaneABC.y) || abcFormat.areDifferent(abc.z, currentWorkPlaneABC.z))) { return; // no change } onCommand(COMMAND_UNLOCK_MULTI_AXIS); if (!retracted) { writeRetract(Z); } gMotionModal.reset(); writeBlock( gMotionModal.format(0), conditional(machineConfiguration.isMachineCoordinate(0), "A" + abcFormat.format(abc.x)), conditional(machineConfiguration.isMachineCoordinate(1), "B" + abcFormat.format(abc.y)), conditional(machineConfiguration.isMachineCoordinate(2), "C" + abcFormat.format(abc.z)) ); onCommand(COMMAND_LOCK_MULTI_AXIS); currentWorkPlaneABC = abc; } var closestABC = false; // choose closest machine angles var currentMachineABC; function getWorkPlaneMachineABC(workPlane) { var W = workPlane; // map to global frame var abc = machineConfiguration.getABC(W); if (closestABC) { if (currentMachineABC) { abc = machineConfiguration.remapToABC(abc, currentMachineABC); } else { abc = machineConfiguration.getPreferredABC(abc); } } else { abc = machineConfiguration.getPreferredABC(abc); } try { abc = machineConfiguration.remapABC(abc); currentMachineABC = abc; } catch (e) { error( localize("Machine angles not supported") + ":" + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) ); } var direction = machineConfiguration.getDirection(abc); if (!isSameDirection(direction, W.forward)) { error(localize("Orientation not supported.")); return new Vector(); } if (!machineConfiguration.isABCSupported(abc)) { error( localize("Work plane is not supported") + ":" + conditional(machineConfiguration.isMachineCoordinate(0), " A" + abcFormat.format(abc.x)) + conditional(machineConfiguration.isMachineCoordinate(1), " B" + abcFormat.format(abc.y)) + conditional(machineConfiguration.isMachineCoordinate(2), " C" + abcFormat.format(abc.z)) ); } var tcp = false; if (tcp) { setRotation(W); // TCP mode } else { var O = machineConfiguration.getOrientation(abc); var R = machineConfiguration.getRemainingOrientation(abc, W); setRotation(R); } return abc; } function isProbeOperation() { return hasParameter("operation-strategy") && (getParameter("operation-strategy") == "probe"); } function onSection() { var insertToolCall = isFirstSection() || currentSection.getForceToolChange && currentSection.getForceToolChange() || (tool.number != getPreviousSection().getTool().number); retracted = false; // specifies that the tool has been retracted to the safe plane var newWorkOffset = isFirstSection() || (getPreviousSection().workOffset != currentSection.workOffset); // work offset changes var newWorkPlane = isFirstSection() || !isSameDirection(getPreviousSection().getGlobalFinalToolAxis(), currentSection.getGlobalInitialToolAxis()) || (currentSection.isOptimizedForMachine() && getPreviousSection().isOptimizedForMachine() && Vector.diff(getPreviousSection().getFinalToolAxisABC(), currentSection.getInitialToolAxisABC()).length > 1e-4) || (!machineConfiguration.isMultiAxisConfiguration() && currentSection.isMultiAxis()) || (!getPreviousSection().isMultiAxis() && currentSection.isMultiAxis() || getPreviousSection().isMultiAxis() && !currentSection.isMultiAxis()); // force newWorkPlane between indexing and simultaneous operations if (insertToolCall || newWorkOffset || newWorkPlane) { // retract to safe plane /* writeRetract(Z); */ } writeln(""); if (hasParameter("operation-comment")) { var comment = getParameter("operation-comment"); if (comment) { writeComment(comment); } } if (insertToolCall) { forceWorkPlane(); if (!isFirstSection()) { setCoolant(COOLANT_OFF); } if (properties.useToolChanger) { writeBlock("T" + toolFormat.format(tool.number), mFormat.format(6)); } else { if (insertToolCall && !isFirstSection()) { writeBlock(mFormat.format(0) + " (CHANGE TOOL)"); } else { writeComment(localize("CHANGE TOOL")); } // writeBlock(gMotionModal.format(0), gFormat.format(53), "X" + xyzFormat.format(properties.toolChangePositionX), "Y" + xyzFormat.format(properties.toolChangePositionY)); writeBlock("T" + toolFormat.format(tool.number), mFormat.format(6) + " (" + getToolTypeName(tool.type).toUpperCase() + " D=" + xyzFormat.format(tool.diameter) + (tool.description ? " " + tool.description.toUpperCase() : "") + ")"); } if (tool.comment) { writeComment(tool.comment); } var showToolZMin = false; if (showToolZMin) { if (is3D()) { var numberOfSections = getNumberOfSections(); var zRange = currentSection.getGlobalZRange(); var number = tool.number; for (var i = currentSection.getId() + 1; i < numberOfSections; ++i) { var section = getSection(i); if (section.getTool().number != number) { break; } zRange.expandToRange(section.getGlobalZRange()); } writeComment(localize("ZMIN") + "=" + zRange.getMinimum()); } } } if (insertToolCall || isFirstSection() || (rpmFormat.areDifferent(spindleSpeed, sOutput.getCurrent())) || (tool.clockwise != getPreviousSection().getTool().clockwise)) { if (spindleSpeed < 1) { error(localize("Spindle speed out of range.")); return; } if (spindleSpeed > 99999) { warning(localize("Spindle speed exceeds maximum value.")); } writeBlock(sOutput.format(spindleSpeed), mFormat.format(tool.clockwise ? 3 : 4)); } // wcs if (insertToolCall) { // force work offset when changing tool currentWorkOffset = undefined; } var workOffset = currentSection.workOffset; if (workOffset == 0) { warningOnce(localize("Work offset has not been specified. Using G54 as WCS."), WARNING_WORK_OFFSET); workOffset = 1; } if (workOffset > 0) { if (workOffset > 6) { error(localize("Work offset out of range.")); return; } else { if (workOffset != currentWorkOffset) { writeBlock(gFormat.format(53 + workOffset)); // G54->G59 currentWorkOffset = workOffset; } } } forceXYZ(); if (machineConfiguration.isMultiAxisConfiguration()) { // use 5-axis indexing for multi-axis mode // set working plane after datum shift var abc = new Vector(0, 0, 0); if (currentSection.isMultiAxis()) { forceWorkPlane(); cancelTransformation(); abc = currentSection.getInitialToolAxisABC(); } else { abc = getWorkPlaneMachineABC(currentSection.workPlane); } setWorkPlane(abc); } else { // pure 3D var remaining = currentSection.workPlane; if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { error(localize("Tool orientation is not supported.")); return; } setRotation(remaining); } // set coolant after we have positioned at Z setCoolant(tool.coolant); forceAny(); var initialPosition = getFramePosition(currentSection.getInitialPosition()); if (!retracted && !insertToolCall) { if (getCurrentPosition().z < initialPosition.z) { writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); } } if (insertToolCall || retracted) { var lengthOffset = tool.lengthOffset; if (lengthOffset > 99) { error(localize("Length offset out of range.")); return; } gMotionModal.reset(); if (!machineConfiguration.isHeadConfiguration()) { writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y) ); writeBlock(gMotionModal.format(0), zOutput.format(initialPosition.z)); } else { writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y), zOutput.format(initialPosition.z) ); } } else { writeBlock( gAbsIncModal.format(90), gMotionModal.format(0), xOutput.format(initialPosition.x), yOutput.format(initialPosition.y) ); } } var currentCoolantMode = COOLANT_OFF; var coolantOff = undefined; function setCoolant(coolant) { var coolantCodes = getCoolantCodes(coolant); if (Array.isArray(coolantCodes)) { if (singleLineCoolant) { writeBlock(coolantCodes.join(getWordSeparator())); } else { for (var c in coolantCodes) { writeBlock(coolantCodes[c]); } } return undefined; } return coolantCodes; } function getCoolantCodes(coolant) { var multipleCoolantBlocks = new Array(); // create a formatted array to be passed into the outputted line if (!coolants) { error(localize("Coolants have not been defined.")); } if (isProbeOperation()) { // avoid coolant output for probing coolant = COOLANT_OFF; } if (coolant == currentCoolantMode) { return undefined; // coolant is already active } if ((coolant != COOLANT_OFF) && (currentCoolantMode != COOLANT_OFF)) { if (Array.isArray(coolantOff)) { for (var i in coolantOff) { multipleCoolantBlocks.push(mFormat.format(coolantOff[i])); } } else { multipleCoolantBlocks.push(mFormat.format(coolantOff)); } } var m; var coolantCodes = {}; for (var c in coolants) { // find required coolant codes into the coolants array if (coolants[c].id == coolant) { coolantCodes.on = coolants[c].on; if (coolants[c].off != undefined) { coolantCodes.off = coolants[c].off; break; } else { for (var i in coolants) { if (coolants[i].id == COOLANT_OFF) { coolantCodes.off = coolants[i].off; break; } } } } } if (coolant == COOLANT_OFF) { m = !coolantOff ? coolantCodes.off : coolantOff; // use the default coolant off command when an 'off' value is not specified } else { coolantOff = coolantCodes.off; m = coolantCodes.on; } if (!m) { onUnsupportedCoolant(coolant); m = 9; } else { if (Array.isArray(m)) { for (var i in m) { multipleCoolantBlocks.push(mFormat.format(m[i])); } } else { multipleCoolantBlocks.push(mFormat.format(m)); } currentCoolantMode = coolant; return multipleCoolantBlocks; // return the single formatted coolant value } return undefined; } function onDwell(seconds) { if (seconds > 99999.999) { warning(localize("Dwelling time is out of range.")); } seconds = clamp(0.001, seconds, 99999.999); writeBlock(gFormat.format(4), "X" + secFormat.format(seconds)); } function onSpindleSpeed(spindleSpeed) { writeBlock(sOutput.format(spindleSpeed)); } function onCycle() { } function getCommonCycle(x, y, z, r) { forceXYZ(); return [xOutput.format(x), yOutput.format(y), zOutput.format(z), (r !== undefined) ? "R" + xyzFormat.format(-r) : ""]; // inverted Z-axis } function onCyclePoint(x, y, z) { if (!isSameDirection(getRotation().forward, new Vector(0, 0, 1))) { expandCyclePoint(x, y, z); return; } if (isFirstCyclePoint()) { repositionToCycleClearance(cycle, x, y, z); // return to initial Z which is clearance plane and set absolute mode var F = cycle.feedrate; var P = !cycle.dwell ? 0 : clamp(1, cycle.dwell * 1000, 99999999); // in milliseconds switch (cycleType) { case "drilling": writeBlock( gAbsIncModal.format(90), gCycleModal.format(81), getCommonCycle(x, y, z, cycle.retract), feedOutput.format(F) ); break; case "counter-boring": if (P > 0) { writeBlock( gAbsIncModal.format(90), gCycleModal.format(82), getCommonCycle(x, y, z, cycle.retract), "P" + milliFormat.format(P), feedOutput.format(F) ); } else { writeBlock( gAbsIncModal.format(90), gCycleModal.format(81), getCommonCycle(x, y, z, cycle.retract), feedOutput.format(F) ); } break; /* case "chip-breaking": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gAbsIncModal.format(90), gCycleModal.format(73), getCommonCycle(x, y, z, cycle.retract), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } break; case "deep-drilling": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gAbsIncModal.format(90), gCycleModal.format(83), getCommonCycle(x, y, z, cycle.retract), "Q" + xyzFormat.format(cycle.incrementalDepth), feedOutput.format(F) ); } break; case "tapping": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gAbsIncModal.format(90), gCycleModal.format((tool.type == TOOL_TAP_LEFT_HAND) ? 33.2 : 33.1), zOutput.format(z), pitchOutput.format(tool.threadPitch) ); gCycleModal.reset(); } break; case "left-tapping": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gAbsIncModal.format(90), gCycleModal.format(33.2), zOutput.format(z), pitchOutput.format(tool.threadPitch) ); gCycleModal.reset(); } break; case "right-tapping": if (P > 0) { expandCyclePoint(x, y, z); } else { writeBlock( gAbsIncModal.format(90), gCycleModal.format(33.1), zOutput.format(z), pitchOutput.format(tool.threadPitch) ); gCycleModal.reset(); } break; case "tapping-with-chip-breaking": case "left-tapping-with-chip-breaking": case "right-tapping-with-chip-breaking": error(localize("Tapping with chip breaking is not supported.")); return; */ default: expandCyclePoint(x, y, z); } } else { if (cycleExpanded) { expandCyclePoint(x, y, z); } else { var _x = xOutput.format(x); var _y = yOutput.format(y); if (!_x && !_y) { xOutput.reset(); // at least one axis is required _x = xOutput.format(x); } writeBlock(_x, _y); } } } function onCycleEnd() { if (!cycleExpanded) { writeBlock(gCycleModal.format(80)); zOutput.reset(); } } var pendingRadiusCompensation = -1; function onRadiusCompensation() { pendingRadiusCompensation = radiusCompensation; error(localize("Radius compensation is not supported for WinPC-NC. Please change the compensation type to 'in computer' for the toolpath.")); return; } function onRapid(_x, _y, _z) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); if (x || y || z) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation mode cannot be changed at rapid traversal.")); return; } writeBlock(gMotionModal.format(0), x, y, z); feedOutput.reset(); } } function onLinear(_x, _y, _z, feed) { // at least one axis is required if (pendingRadiusCompensation >= 0) { // ensure that we end at desired position when compensation is turned off xOutput.reset(); yOutput.reset(); } var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var f = feedOutput.format(feed); if (x || y || z) { if (pendingRadiusCompensation >= 0) { pendingRadiusCompensation = -1; var d = tool.diameterOffset; switch (radiusCompensation) { case RADIUS_COMPENSATION_LEFT: writeBlock( gMotionModal.format(1), gFormat.format(41), x, y, z, conditional(properties.useToolChanger, "O" + xyzFormat.format(tool.diameter/2)), f ); break; case RADIUS_COMPENSATION_RIGHT: writeBlock( gMotionModal.format(1), gFormat.format(42), x, y, z, conditional(properties.useToolChanger, "O" + xyzFormat.format(tool.diameter/2)), f ); break; default: writeBlock(gMotionModal.format(1), gFormat.format(40), x, y, z, f); } } else { writeBlock(gMotionModal.format(1), x, y, z, f); } } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion feedOutput.reset(); // force feed on next line } else { writeBlock(gMotionModal.format(1), f); } } } function onRapid5D(_x, _y, _z, _a, _b, _c) { if (!currentSection.isOptimizedForMachine()) { error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); return; } if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation mode cannot be changed at rapid traversal.")); return; } var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var a = aOutput.format(_a); var b = bOutput.format(_b); var c = cOutput.format(_c); writeBlock(gMotionModal.format(0), x, y, z, a, b, c); feedOutput.reset(); } function onLinear5D(_x, _y, _z, _a, _b, _c, feed) { if (!currentSection.isOptimizedForMachine()) { error(localize("This post configuration has not been customized for 5-axis simultaneous toolpath.")); return; } // at least one axis is required if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for 5-axis move.")); return; } var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var a = aOutput.format(_a); var b = bOutput.format(_b); var c = cOutput.format(_c); var f = feedOutput.format(feed); if (x || y || z || a || b || c) { writeBlock(gMotionModal.format(1), x, y, z, a, b, c, f); } else if (f) { if (getNextRecord().isMotion()) { // try not to output feed without motion feedOutput.reset(); // force feed on next line } else { writeBlock(gMotionModal.format(1), f); } } } function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { if (pendingRadiusCompensation >= 0) { error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); return; } var start = getCurrentPosition(); if (isFullCircle()) { if (isHelical()) { linearize(tolerance); return; } switch (getCircularPlane()) { case PLANE_XY: writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), feedOutput.format(feed)); break; default: linearize(tolerance); } } else { switch (getCircularPlane()) { case PLANE_XY: writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), feedOutput.format(feed)); break; default: linearize(tolerance); } } } var mapCommand = { }; function onCommand(command) { switch (command) { case COMMAND_STOP: writeBlock(mFormat.format(2)); return; case COMMAND_COOLANT_OFF: setCoolant(COOLANT_OFF); return; case COMMAND_START_SPINDLE: onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); return; case COMMAND_SPINDLE_CLOCKWISE: writeBlock(mFormat.format(3)); return; case COMMAND_SPINDLE_COUNTERCLOCKWISE: writeBlock(mFormat.format(4)); return; case COMMAND_STOP_SPINDLE: writeBlock(mFormat.format(5)); return; case COMMAND_ORIENTATE_SPINDLE: return; case COMMAND_LOCK_MULTI_AXIS: return; case COMMAND_UNLOCK_MULTI_AXIS: return; case COMMAND_BREAK_CONTROL: return; case COMMAND_TOOL_MEASURE: return; } var stringId = getCommandStringId(command); var mcode = mapCommand[stringId]; if (mcode != undefined) { writeBlock(mFormat.format(mcode)); } else { onUnsupportedCommand(command); } } function onSectionEnd() { if (!isLastSection() && (getNextSection().getTool().coolant != tool.coolant)) { setCoolant(COOLANT_OFF); } forceAny(); } /** Output block to do safe retract and/or move to home position. */ function writeRetract() { if (arguments.length == 0) { error(localize("No axis specified for writeRetract().")); return; } var words = []; // store all retracted axes in an array for (var i = 0; i < arguments.length; ++i) { let instances = 0; // checks for duplicate retract calls for (var j = 0; j < arguments.length; ++j) { if (arguments[i] == arguments[j]) { ++instances; } } if (instances > 1) { // error if there are multiple retract calls for the same axis error(localize("Cannot retract the same axis twice in one line")); return; } switch (arguments[i]) { case X: words.push("X" + xyzFormat.format(machineConfiguration.hasHomePositionX() ? machineConfiguration.getHomePositionX() : 0)); break; case Y: words.push("Y" + xyzFormat.format(machineConfiguration.hasHomePositionY() ? machineConfiguration.getHomePositionY() : 0)); break; case Z: words.push("Z" + xyzFormat.format(machineConfiguration.getRetractPlane())); retracted = true; // specifies that the tool has been retracted to the safe plane break; default: error(localize("Bad axis specified for writeRetract().")); return; } } if (words.length > 0) { gMotionModal.reset(); writeBlock(gAbsIncModal.format(90), gFormat.format(53), gMotionModal.format(0), words); // retract } zOutput.reset(); } function onClose() { onCommand(COMMAND_COOLANT_OFF); onCommand(COMMAND_STOP_SPINDLE); // writeRetract(Z); setWorkPlane(new Vector(0, 0, 0)); // reset working plane // writeBlock(gFormat.format(28)); // retract writeBlock(mFormat.format(30)); zOutput.reset(); }