diff --git a/Flow_Waterjet_BIDC/Bechtel Waterjet.cps b/Flow_Waterjet_BIDC/Bechtel Waterjet.cps index 1ee6df6..9f0a976 100644 --- a/Flow_Waterjet_BIDC/Bechtel Waterjet.cps +++ b/Flow_Waterjet_BIDC/Bechtel Waterjet.cps @@ -1,564 +1,485 @@ -/** - Copyright (C) 2012-2021 by Autodesk, Inc. - All rights reserved. - - Flow waterjet post processor configuration. - - $Revision: 43151 08c79bb5b30997ccb5fb33ab8e7c8c26981be334 $ - $Date: 2021-02-19 00:25:13 $ - - FORKID {F61954EF-5A29-4B93-93E7-870BC2786880} -*/ - -description = "Flow Waterjet ORD"; -vendor = "Flow"; -vendorUrl = "http://www.flowwaterjet.com"; -legal = "Copyright (C) 2012-2021 by Autodesk, Inc."; -certificationLevel = 2; -minimumRevision = 45702; - -longDescription = "Post for Flow Waterjets using software Version 5 or 6. V5=2-axis, V6=3-axis. " + -"V5: Manually set nozzle height. V6: Nozzle height in NC program set by Top Height attribute. " + EOL + -"Feed percentage set by Cutting Mode quality in tool dialog (auto=60, high=20, medium=40, low=100)"; - -extension = "ord"; -setCodePage("ascii"); - -capabilities = CAPABILITY_JET; -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(90); -allowHelicalMoves = false; -allowedCircularPlanes = 1 << PLANE_XY; // allow only XY circular motion - -var maximumLineLength = 80; // the maximum number of charaters allowed in a line - -// formatVersion: -// version 6 should be user selectable, but now use version 5 -// version 5 does not have z moves, so it will be safer for inexperienced users -// version 5 does not have the mysterious parameter after the cutter comp value - -properties = { - useHSMFeedrates: { - title: "Use HSM feedrates", - description: "Specifies whether to output the feedrates from HSM.", - type: "boolean", - value: false, - scope: "post" - }, - maximumFeedrateIPM: { - title: "Maximum feedrate (IPM)", - description: "Sets the maximum feedrate in IPM.", - type: "integer", - value: 700, - scope: "post" - }, - formatVersion: { - title: "Flow control software version", - description: "V5 outputs XY, V6 outputs XYZ", - group: 1, - type: "enum", - values: [ - {title: "V5", id: "5"}, - {title: "V6", id: "6"} - ], - value: "6", - scope: "post" - }, - debugMode: { - title: "Debug Mode", - description: "Display Comments in ORD. Not compatible with machine", - type: "boolean", - value: false, - scope: "post" - } -}; - -staticProperties = { - postVersion: "BIDC-FWJ.G9.A21" -}; - -// use fixed width instead -var xyzFormat = createFormat({decimals:4, trim:false}); -var integerFormat = createFormat({decimals:0}); - -// fixed settings -var thickness = 0; -var arcCounter = 0; -var lineCounter = -1; - -// collected state -var useVersion6 = false; -var arcFinish = undefined; -var feedActive = false; -var prevCoords = undefined; - -// override radius compensation -var compensationOffset = 0; // center compensation - -var etchOperation = false; // though-cut unless set to true -var forceOutput = false; - -/** - * - * @param num - * @returns Little Endian hex string (float) - */ - function ToHex(num) { - if (num == 0) { - return "00000000"; //bypass - } - - var sign = "0"; - - if(num < 0.0) { - sign = "1"; - num = -num; - } - - var mantissa = parseFloat(num).toString(2); - var exponent = 0; - - if (mantissa.indexOf('.') == -1) { - mantissa = mantissa.toString() + ".0"; - } - - if (mantissa.substr(0, 1) === "0") { - exponent = mantissa.indexOf('.') - mantissa.indexOf('1') + 127; - } - else { - exponent = mantissa.indexOf('.') - 1 + 127; - } - - mantissa = mantissa.replace(".", ""); - mantissa = mantissa.substr(mantissa.indexOf('1') + 1); - - if (mantissa.length > 23) { - mantissa = mantissa.substr(0, 23); - } - else { - while (mantissa.length < 23) { - mantissa = mantissa + "0"; - } - } - - var exp = parseFloat(exponent).toString(2); - - while(exp.length < 8) { - exp = "0" + exp; - } - - var numberFull = sign + exp + mantissa; - log("hellow world"); - // var hex = parseInt(numberFull, 2).toString(16).split(''); - // return (hex[6] + hex[7]) + (hex[4] + hex[5]) + (hex[2] + hex[3]) + (hex[0] + hex[1]); - return parseInt(numberFull, 2).toString(16); -} - -/** - * (IN PROGRESS) Write machine config to .sta file - */ -function writeSta() { - try { - var file = new TextFile("C:\\Users\\" + getGlobalParameter("username") + "\\AppData\\Local\\Fusion 360 CAM\\nc\\" + programName + ".sta", true, "utf-8"); - var float = 9.94; - - // var data = BinaryFile.loadBinary("C:\\Users\\kpan8\\Downloads\\stazip\\ld6.sta"); - var hex = toHex(6.0); - // data = String.fromCharCode(hex[0] + hex[1]) + String.fromCharCode(hex[2] + hex[3]) + String.fromCharCode(hex[4] + hex[5]) + String.fromCharCode(hex[6] + hex[7]); - file.writeln(hex); - // BinaryFile.saveBinary("C:\\Users\\" + getGlobalParameter("username") + "\\AppData\\Local\\Fusion 360 CAM\\nc\\" + programName + "bin.sta", data) - - file.close(); - - } catch (e) { - error(localize("Failed to write sta file.")); - } - -} - -/** - Writes the specified block. -*/ -function writeBlock() { - writeWords(arguments); -} - -function formatComment(comment) { - return "// " + comment; -} - -function writeComment(text) { - if (!getProperty("debugMode")) return; - writeln(formatComment(text.substr(0, maximumLineLength - 2))); -} - -var FIELD = " "; - -/** Make sure fields are aligned. */ -function f(text) { - var length = text.length; - if (length > 10) { - return text; - } - return FIELD.substr(0, 10 - length) + text; -} - -var commentField = "// "; - -/** Make sure fields are aligned. */ -function commentf(text) { - var length = text.length; - if (length > 10) { - return text; - } - return commentField.substr(0, 10 - length) + text; -} - -/** Make sure fields are aligned. */ -function fi(text, size) { - var length = text.length; - if (length > size) { - return text; - } - return FIELD.substr(0, size - length) + text; -} - -function onOpen() { - useVersion6 = getProperty("formatVersion") == "6"; - unit = IN; // only inch mode is supported - - redirectToBuffer(); // buffer the entire program to be able to count the linear and circular moves - setWordSeparator(""); - - { // stock - workpiece - var workpiece = getWorkpiece(); - var delta = Vector.diff(workpiece.upper, workpiece.lower); - if (delta.isNonZero()) { - // thickness = (workpiece.upper.z - workpiece.lower.z); - } - } - - if (getNumberOfSections() > 0) { - var firstSection = getSection(0); - - var remaining = firstSection.workPlane; - if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { - error(localize("Tool orientation is not supported.")); - return; - } - setRotation(remaining); - - if (!useVersion6) { - var originZ = firstSection.getGlobalZRange().getMinimum(); // the cutting depth of the first section - - for (var i = 0; i < getNumberOfSections(); ++i) { - var section = getSection(i); - var z = section.getGlobalZRange().getMinimum(); // contour Z of the each section - if (xyzFormat.getResultingValue(z) != xyzFormat.getResultingValue(originZ)) { - error(localize("You are trying to machine at multiple depths which is not allowed.")); - return; - } - } - } - } - forceOutput = true;// force out first line -} - -function onSection() { - var remaining = currentSection.workPlane; - if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { - error(localize("Tool orientation is not supported.")); - return; - } - setRotation(remaining); - - etchOperation = false; - if (currentSection.getType() == TYPE_JET) { - switch (tool.type) { - case TOOL_WATER_JET: - break; - default: - error(localize("The CNC does not support the required tool.")); - return; - } - switch (currentSection.jetMode) { - case JET_MODE_THROUGH: - break; - case JET_MODE_ETCHING: - etchOperation = true; - break; - case JET_MODE_VAPORIZE: - error(localize("Vaporize is not supported by the CNC.")); - return; - default: - error(localize("Unsupported cutting mode.")); - return; - } - } else if (currentSection.getType() == TYPE_MILLING) { - warning(localize("Milling toolpath will be used as waterjet through-cutting toolpath.")); - } else { - error(localize("CNC doesn't support the toolpath.")); - return; - } - - var initialPosition = getFramePosition(currentSection.getInitialPosition()); - onExpandedRapid(initialPosition.x, initialPosition.y, initialPosition.z); -} - -function onParameter(name, value) { -} - -function writeLinear(x, y, z, feed, column7) { - var flag = false; - if (useVersion6) { - flag = xyzFormat.areDifferent(x, getCurrentPosition().x) || - xyzFormat.areDifferent(y, getCurrentPosition().y) || - xyzFormat.areDifferent(z, getCurrentPosition().z); - } else { - flag = xyzFormat.areDifferent(x, getCurrentPosition().x) || - xyzFormat.areDifferent(y, getCurrentPosition().y); - } - - if (flag || forceOutput) { - if (useVersion6) { - switch (writeLinear.caller.name) { - case "onRapid": - writeComment("Rapid"); - break; - case "onLinear": - writeComment("Linear"); - break; - case "finishArcs": - writeComment("Arc Completion"); - break; - } - if (getProperty("debugMode")){ - writeBlock( - commentf("X"), ",", - f("Y"), ",", - f("Z"), ",", - fi("L", 2), ",", - fi("Feed", 5), ",", - fi("C", 2), ",", - fi("?", 2)); - } - writeBlock( - f(xyzFormat.format(x)), ",", - f(xyzFormat.format(y)), ",", - f(xyzFormat.format(z)), ",", - fi(integerFormat.format(0), 2), ",", // linear - fi(integerFormat.format(feed), 5), ",", - fi(integerFormat.format(compensationOffset), 2), ",", // left, center, right - fi(integerFormat.format(column7), 2) // TAG: seen -2..2 - unknown - ); - } else { - switch (writeLinear.caller.name) { - case "onRapid": - writeComment("Rapid"); - break; - case "onLinear": - writeComment("Linear"); - break; - case "finishArcs": - writeComment("Arc Completion"); - break; - } - writeBlock( - f(xyzFormat.format(x)), ",", - f(xyzFormat.format(y)), ",", - fi(integerFormat.format(0), 2), ",", - fi(integerFormat.format(feed), 5), ",", - fi(integerFormat.format(compensationOffset), 2) - ); - } - ++lineCounter; - forceOutput = false; - } - if (feed > 0) { - feedActive = true; - } - prevCoords = {x:x, y:y, z:z}; -} - -function finishArcs() { - if (arcFinish) { - // complete circular motion with output of destination values - forceOutput = true; - writeLinear(arcFinish.x, arcFinish.y, arcFinish.z, arcFinish.feed, 2); - arcFinish = undefined; - } -} - -function onRapid(x, y, z) { - finishArcs(); - if (feedActive) { - forceOutput = true; - writeLinear(prevCoords.x, prevCoords.y, prevCoords.z, 0, 0); - } - writeLinear(x, y, z, 0, 0); // non-cutting - feedActive = false; -} - -function onLinear(x, y, z, feed) { - finishArcs(); - // skip output if next move is an arc. OnCircular record has this move destination XY - if (getNextRecord().getType() != RECORD_CIRCULAR) { - writeLinear(x, y, z, power ? getFeedInPercent(feed) : 0, 2); - } -} - -function onPower(power) { -} - -function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { - // spirals are not allowed - arcs must be < 360deg - // fail if radius compensation is changed for circular move - - // syntax is; start X, start y, arc direction, feed, comp, cx, cy - // end X, end Y, if following move is an arc, is the start x, start y, of the line - // end X, end Y, if following move is a line, is output in OnLinear - // using the arcFinish flag - - circularICode = (clockwise ? 1 : -1); - - if ((getCircularPlane() != PLANE_XY) || isHelical()) { - linearize(tolerance); - } - var p = getCurrentPosition(); - if (useVersion6) { - writeComment("Circular"); - if (getProperty("debugMode")){ - writeBlock( - commentf("X"), ",", - f("Y"), ",", - f("Z"), ",", - fi("CW", 2), ",", - fi("Feed", 5), ",", - fi("C", 2), ",", - fi("?", 2), ",", - f("CX"), ",", - f("CY"), ",", - f("CZ")); - } - writeBlock( - f(xyzFormat.format(p.x)), ",", - f(xyzFormat.format(p.y)), ",", - f(xyzFormat.format(p.z)), ",", - fi(integerFormat.format(circularICode), 2), ",", // arc cw/ccw - fi(integerFormat.format(power ? getFeedInPercent(feed) : 0), 5), ",", - fi(integerFormat.format(compensationOffset), 2), ",", // left, center, right - fi(integerFormat.format(2), 2), ",", // TAG: seen -2..2 - unknown - f(xyzFormat.format(cx)), ",", - f(xyzFormat.format(cy)), ",", - f(xyzFormat.format(0)) // PLANE_XY only - ); - } else { - writeComment("Circular"); - writeBlock( - f(xyzFormat.format(p.x)), ",", - f(xyzFormat.format(p.y)), ",", - fi(integerFormat.format(circularICode), 2), ",", // arc cw/ccw - fi(integerFormat.format(power ? getFeedInPercent(feed) : 0), 5), ",", - fi(integerFormat.format(compensationOffset), 2), ",", // left, center, right - f(xyzFormat.format(cx)), ",", - f(xyzFormat.format(cy)) - ); - } - ++arcCounter; - - // save destination values to complete arc move - arcFinish = {x:x, y:y, z:z, feed:(power ? getFeedInPercent(feed) : 0)}; - if (feed > 0) { - feedActive = true; - } - prevCoords = {x:x, y:y, z:z}; -} - -function getFeedInPercent(feed) { - var feedPercent; - if ((getProperty("maximumFeedrateIPM") > 0) && getProperty("useHSMFeedrates")) { - // use HSM feedrates - // 1 - 99 % - feedPercent = Math.min(Math.ceil(Math.min(getProperty("maximumFeedrateIPM"), feed) / getProperty("maximumFeedrateIPM") * 100), 99); - } else { - // use fixed feedrates per quality selection - switch (currentSection.quality) { - case 1: - // high quality - feedPercent = 20; // very slow, cut surface excellent - break; - case 2: - feedPercent = 40; // slow, cut surface good - break; - case 3: - feedPercent = 100; // fast, cut surface slightly rough - break; - default: - // medium quality - feedPercent = 60; // moderate, cut surface moderate - } - } - return feedPercent; -} - -function onRadiusCompensation() { - switch (radiusCompensation) { - case RADIUS_COMPENSATION_LEFT: - compensationOffset = -1; - break; - case RADIUS_COMPENSATION_RIGHT: - compensationOffset = 1; - break; - default: - compensationOffset = 0; // center compensation - } -} - -function onCycle() { - error(localize("Canned cycles are not supported.")); -} - -function onSectionEnd() { - finishArcs(); - compensationOffset = 0; // center compensation -} - -function onClose() { - writeSta(); - if (isRedirecting()) { - var mainProgram = getRedirectionBuffer(); // TAG: no need for redirection - closeRedirection(); - if (programName) { - var programId; - try { - programId = getAsInt(programName); - } catch (e) { - error(localize("Program name must be a number.")); - return; - } - } - writeComment("O" + programId); - writeComment("Career Account Username: " + getGlobalParameter("username")); - writeComment("Filename: " + getGlobalParameter("document-path")); - writeComment("Date: " + getGlobalParameter("generated-at")); - writeComment("Post Version: " + staticProperties.postVersion); - writeln("// This file was created by FlowMaster(R), which is proprietary to Flow International Corporation. " + lineCounter + " " + arcCounter); - if (useVersion6) { - writeln("VER 6.00"); - } - writeln("// Created by Autodesk HSM"); - if (programComment) { - writeln("// " + programComment); - } - write(mainProgram); - } -} - -function setProperty(property, value) { - properties[property].current = value; -} +/** + Copyright (C) 2012-2021 by Autodesk, Inc. + All rights reserved. + + Flow waterjet post processor configuration. + + $Revision: 43151 08c79bb5b30997ccb5fb33ab8e7c8c26981be334 $ + $Date: 2021-02-19 00:25:13 $ + + FORKID {F61954EF-5A29-4B93-93E7-870BC2786880} +*/ + +description = "Flow Waterjet ORD"; +vendor = "Flow"; +vendorUrl = "http://www.flowwaterjet.com"; +legal = "Copyright (C) 2012-2021 by Autodesk, Inc."; +certificationLevel = 2; +minimumRevision = 45702; + +longDescription = "Post for Flow Waterjets using software Version 5 or 6. V5=2-axis, V6=3-axis. " + +"V5: Manually set nozzle height. V6: Nozzle height in NC program set by Top Height attribute. " + EOL + +"Feed percentage set by Cutting Mode quality in tool dialog (auto=60, high=20, medium=40, low=100)"; + +extension = "ord"; +setCodePage("ascii"); + +capabilities = CAPABILITY_JET; +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(90); +allowHelicalMoves = false; +allowedCircularPlanes = 1 << PLANE_XY; // allow only XY circular motion + +var maximumLineLength = 80; // the maximum number of charaters allowed in a line + +// formatVersion: +// version 6 should be user selectable, but now use version 5 +// version 5 does not have z moves, so it will be safer for inexperienced users +// version 5 does not have the mysterious parameter after the cutter comp value + +properties = { + useHSMFeedrates: { + title: "Use HSM feedrates", + description: "Specifies whether to output the feedrates from HSM.", + type: "boolean", + value: false, + scope: "post" + }, + maximumFeedrateIPM: { + title: "Maximum feedrate (IPM)", + description: "Sets the maximum feedrate in IPM.", + type: "integer", + value: 700, + scope: "post" + }, + formatVersion: { + title: "Flow control software version", + description: "V5 outputs XY, V6 outputs XYZ", + group: 1, + type: "enum", + values: [ + {title: "V5", id: "5"}, + {title: "V6", id: "6"} + ], + value: "6", + scope: "post" + }, + debugMode: { + title: "Debug Mode", + description: "Display Comments in ORD. Not compatible with machine", + type: "boolean", + value: false, + scope: "post" + } +}; + +staticProperties = { + postVersion: "BIDC-FWJ.G9.A21" +}; + +// use fixed width instead +var xyzFormat = createFormat({decimals:4, trim:false}); +var integerFormat = createFormat({decimals:0}); + +// fixed settings +var thickness = 0; +var arcCounter = 0; +var lineCounter = -1; + +// collected state +var useVersion6 = false; +var arcFinish = undefined; +var feedActive = false; +var prevCoords = undefined; + +// override radius compensation +var compensationOffset = 0; // center compensation + +var etchOperation = false; // though-cut unless set to true +var forceOutput = false; + +/** + Writes the specified block. +*/ +function writeBlock() { + writeWords(arguments); +} + +function formatComment(comment) { + return "// " + comment; +} + +function writeComment(text) { + if (!getProperty("debugMode")) return; + writeln(formatComment(text.substr(0, maximumLineLength - 2))); +} + +var FIELD = " "; + +/** Make sure fields are aligned. */ +function f(text) { + var length = text.length; + if (length > 10) { + return text; + } + return FIELD.substr(0, 10 - length) + text; +} + +var commentField = "// "; + +/** Make sure fields are aligned. */ +function commentf(text) { + var length = text.length; + if (length > 10) { + return text; + } + return commentField.substr(0, 10 - length) + text; +} + +/** Make sure fields are aligned. */ +function fi(text, size) { + var length = text.length; + if (length > size) { + return text; + } + return FIELD.substr(0, size - length) + text; +} + +function onOpen() { + useVersion6 = getProperty("formatVersion") == "6"; + unit = IN; // only inch mode is supported + + redirectToBuffer(); // buffer the entire program to be able to count the linear and circular moves + setWordSeparator(""); + + { // stock - workpiece + var workpiece = getWorkpiece(); + var delta = Vector.diff(workpiece.upper, workpiece.lower); + if (delta.isNonZero()) { + // thickness = (workpiece.upper.z - workpiece.lower.z); + } + } + + if (getNumberOfSections() > 0) { + var firstSection = getSection(0); + + var remaining = firstSection.workPlane; + if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { + error(localize("Tool orientation is not supported.")); + return; + } + setRotation(remaining); + + if (!useVersion6) { + var originZ = firstSection.getGlobalZRange().getMinimum(); // the cutting depth of the first section + + for (var i = 0; i < getNumberOfSections(); ++i) { + var section = getSection(i); + var z = section.getGlobalZRange().getMinimum(); // contour Z of the each section + if (xyzFormat.getResultingValue(z) != xyzFormat.getResultingValue(originZ)) { + error(localize("You are trying to machine at multiple depths which is not allowed.")); + return; + } + } + } + } + forceOutput = true;// force out first line +} + +function onSection() { + var remaining = currentSection.workPlane; + if (!isSameDirection(remaining.forward, new Vector(0, 0, 1))) { + error(localize("Tool orientation is not supported.")); + return; + } + setRotation(remaining); + + etchOperation = false; + if (currentSection.getType() == TYPE_JET) { + switch (tool.type) { + case TOOL_WATER_JET: + break; + default: + error(localize("The CNC does not support the required tool.")); + return; + } + switch (currentSection.jetMode) { + case JET_MODE_THROUGH: + break; + case JET_MODE_ETCHING: + etchOperation = true; + break; + case JET_MODE_VAPORIZE: + error(localize("Vaporize is not supported by the CNC.")); + return; + default: + error(localize("Unsupported cutting mode.")); + return; + } + } else if (currentSection.getType() == TYPE_MILLING) { + warning(localize("Milling toolpath will be used as waterjet through-cutting toolpath.")); + } else { + error(localize("CNC doesn't support the toolpath.")); + return; + } + + var initialPosition = getFramePosition(currentSection.getInitialPosition()); + onExpandedRapid(initialPosition.x, initialPosition.y, initialPosition.z); +} + +function onParameter(name, value) { +} + +function writeLinear(x, y, z, feed, column7) { + var flag = false; + if (useVersion6) { + flag = xyzFormat.areDifferent(x, getCurrentPosition().x) || + xyzFormat.areDifferent(y, getCurrentPosition().y) || + xyzFormat.areDifferent(z, getCurrentPosition().z); + } else { + flag = xyzFormat.areDifferent(x, getCurrentPosition().x) || + xyzFormat.areDifferent(y, getCurrentPosition().y); + } + + if (flag || forceOutput) { + if (useVersion6) { + switch (writeLinear.caller.name) { + case "onRapid": + writeComment("Rapid"); + break; + case "onLinear": + writeComment("Linear"); + break; + case "finishArcs": + writeComment("Arc Completion"); + break; + } + if (getProperty("debugMode")){ + writeBlock( + commentf("X"), ",", + f("Y"), ",", + f("Z"), ",", + fi("L", 2), ",", + fi("Feed", 5), ",", + fi("C", 2), ",", + fi("?", 2)); + } + writeBlock( + f(xyzFormat.format(x)), ",", + f(xyzFormat.format(y)), ",", + f(xyzFormat.format(z)), ",", + fi(integerFormat.format(0), 2), ",", // linear + fi(integerFormat.format(feed), 5), ",", + fi(integerFormat.format(compensationOffset), 2), ",", // left, center, right + fi(integerFormat.format(column7), 2) // TAG: seen -2..2 - unknown + ); + } else { + switch (writeLinear.caller.name) { + case "onRapid": + writeComment("Rapid"); + break; + case "onLinear": + writeComment("Linear"); + break; + case "finishArcs": + writeComment("Arc Completion"); + break; + } + writeBlock( + f(xyzFormat.format(x)), ",", + f(xyzFormat.format(y)), ",", + fi(integerFormat.format(0), 2), ",", + fi(integerFormat.format(feed), 5), ",", + fi(integerFormat.format(compensationOffset), 2) + ); + } + ++lineCounter; + forceOutput = false; + } + if (feed > 0) { + feedActive = true; + } + prevCoords = {x:x, y:y, z:z}; +} + +function finishArcs() { + if (arcFinish) { + // complete circular motion with output of destination values + forceOutput = true; + writeLinear(arcFinish.x, arcFinish.y, arcFinish.z, arcFinish.feed, 2); + arcFinish = undefined; + } +} + +function onRapid(x, y, z) { + finishArcs(); + if (feedActive) { + forceOutput = true; + writeLinear(prevCoords.x, prevCoords.y, prevCoords.z, 0, 0); + } + writeLinear(x, y, z, 0, 0); // non-cutting + feedActive = false; +} + +function onLinear(x, y, z, feed) { + finishArcs(); + // skip output if next move is an arc. OnCircular record has this move destination XY + if (getNextRecord().getType() != RECORD_CIRCULAR) { + writeLinear(x, y, z, power ? getFeedInPercent(feed) : 0, 2); + } +} + +function onPower(power) { +} + +function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { + // spirals are not allowed - arcs must be < 360deg + // fail if radius compensation is changed for circular move + + // syntax is; start X, start y, arc direction, feed, comp, cx, cy + // end X, end Y, if following move is an arc, is the start x, start y, of the line + // end X, end Y, if following move is a line, is output in OnLinear + // using the arcFinish flag + + circularICode = (clockwise ? 1 : -1); + + if ((getCircularPlane() != PLANE_XY) || isHelical()) { + linearize(tolerance); + } + var p = getCurrentPosition(); + if (useVersion6) { + writeComment("Circular"); + if (getProperty("debugMode")){ + writeBlock( + commentf("X"), ",", + f("Y"), ",", + f("Z"), ",", + fi("CW", 2), ",", + fi("Feed", 5), ",", + fi("C", 2), ",", + fi("?", 2), ",", + f("CX"), ",", + f("CY"), ",", + f("CZ")); + } + writeBlock( + f(xyzFormat.format(p.x)), ",", + f(xyzFormat.format(p.y)), ",", + f(xyzFormat.format(p.z)), ",", + fi(integerFormat.format(circularICode), 2), ",", // arc cw/ccw + fi(integerFormat.format(power ? getFeedInPercent(feed) : 0), 5), ",", + fi(integerFormat.format(compensationOffset), 2), ",", // left, center, right + fi(integerFormat.format(2), 2), ",", // TAG: seen -2..2 - unknown + f(xyzFormat.format(cx)), ",", + f(xyzFormat.format(cy)), ",", + f(xyzFormat.format(0)) // PLANE_XY only + ); + } else { + writeComment("Circular"); + writeBlock( + f(xyzFormat.format(p.x)), ",", + f(xyzFormat.format(p.y)), ",", + fi(integerFormat.format(circularICode), 2), ",", // arc cw/ccw + fi(integerFormat.format(power ? getFeedInPercent(feed) : 0), 5), ",", + fi(integerFormat.format(compensationOffset), 2), ",", // left, center, right + f(xyzFormat.format(cx)), ",", + f(xyzFormat.format(cy)) + ); + } + ++arcCounter; + + // save destination values to complete arc move + arcFinish = {x:x, y:y, z:z, feed:(power ? getFeedInPercent(feed) : 0)}; + if (feed > 0) { + feedActive = true; + } + prevCoords = {x:x, y:y, z:z}; +} + +function getFeedInPercent(feed) { + var feedPercent; + if ((getProperty("maximumFeedrateIPM") > 0) && getProperty("useHSMFeedrates")) { + // use HSM feedrates + // 1 - 99 % + feedPercent = Math.min(Math.ceil(Math.min(getProperty("maximumFeedrateIPM"), feed) / getProperty("maximumFeedrateIPM") * 100), 99); + } else { + // use fixed feedrates per quality selection + switch (currentSection.quality) { + case 1: + // high quality + feedPercent = 20; // very slow, cut surface excellent + break; + case 2: + feedPercent = 40; // slow, cut surface good + break; + case 3: + feedPercent = 100; // fast, cut surface slightly rough + break; + default: + // medium quality + feedPercent = 60; // moderate, cut surface moderate + } + } + return feedPercent; +} + +function onRadiusCompensation() { + switch (radiusCompensation) { + case RADIUS_COMPENSATION_LEFT: + compensationOffset = -1; + break; + case RADIUS_COMPENSATION_RIGHT: + compensationOffset = 1; + break; + default: + compensationOffset = 0; // center compensation + } +} + +function onCycle() { + error(localize("Canned cycles are not supported.")); +} + +function onSectionEnd() { + finishArcs(); + compensationOffset = 0; // center compensation +} + +function onClose() { + if (isRedirecting()) { + var mainProgram = getRedirectionBuffer(); // TAG: no need for redirection + closeRedirection(); + if (programName) { + var programId; + try { + programId = getAsInt(programName); + } catch (e) { + error(localize("Program name must be a number.")); + return; + } + } + writeComment("O" + programId); + writeComment("Career Account Username: " + getGlobalParameter("username")); + writeComment("Filename: " + getGlobalParameter("document-path")); + writeComment("Date: " + getGlobalParameter("generated-at")); + writeComment("Post Version: " + staticProperties.postVersion); + writeln("// This file was created by FlowMaster(R), which is proprietary to Flow International Corporation. " + lineCounter + " " + arcCounter); + if (useVersion6) { + writeln("VER 6.00"); + } + writeln("// Created by Autodesk HSM"); + if (programComment) { + writeln("// " + programComment); + } + write(mainProgram); + } +} + +function setProperty(property, value) { + properties[property].current = value; +} \ No newline at end of file