/** Copyright (C) 2015-2017 by Autodesk, Inc. All rights reserved. $Revision: 41602 8a235290846bfe71ead6a010711f4fc730f48827 $ $Date: 2017-09-14 12:16:32 $ FORKID {E251098A-758C-4C19-B8D9-8408A6BDAFC9} */ description = "AutoCAD DXF"; vendor = "Autodesk"; vendorUrl = "http://www.autodesk.com"; legal = "Copyright (C) 2015-2016 by Autodesk, Inc."; certificationLevel = 2; longDescription = "This post outputs the toolpath in the DXF (AutoCAD) file format. Note that the direction of the toolpath will only be preserved if you enabled the 'forceSameDirection' property which will trigger linearization of clockwise arcs. You can turn on 'onlyCutting' to get rid of the linking motion. And you can turn off 'includeDrill' to avoid points at the drilling positions. You can specify a specific layer by setting the property called 'layer'. If you enable the property 'putOperationsInSeparateLayers' each operation will be put into separate layers incremented by 1."; capabilities = CAPABILITY_INTERMEDIATE | CAPABILITY_MILLING | CAPABILITY_JET; extension = "dxf"; mimetype = "application/dxf"; setCodePage("utf-8"); minimumCircularSweep = toRad(0.01); maximumCircularSweep = toRad(180); allowHelicalMoves = false; allowedCircularPlanes = undefined; // only XY arcs properties = { useTimeStamp: false, // enable to output a time stamp onlyCutting: false, // only output the cutting passes - ignore all linking moves includeDrill: true, // output circle for drill positions only2D: false, // only output toolpath as 2D forceSameDirection: false, // enable to keep the direction of the toolpath - clockwise arcs will be linearized layer: 1, // the default layer putOperationsInSeparateLayers: false // enable to put each operation into its own layer }; // user-defined property definitions propertyDefinitions = { useTimeStamp: {title:"Time stamp", description:"Specifies whether to output a time stamp.", type:"boolean"}, onlyCutting: {title:"Only cutting", description:"If enabled, only cutting passes will be outputted, all linking moves will be ignored.", type:"boolean"}, includeDrill: {title:"Include drill", description:"If enabled, circles will be output for all drill positions.", type:"boolean"}, only2D: {title:"Output as 2D", description:"Only output toolpath as 2D.", type:"boolean"}, forceSameDirection: {title:"Force same direction", description:"Enable to keep the direction of the toolpath, clockwise arcs will be linearized.", type:"boolean"}, layer: {title:"Layer", description:"Sets the default layer.", type:"integer"}, putOperationsInSeparateLayers: {title:"Put operations in separate layers", description:"Enable this property to put each operation on its own layer.", type:"boolean"} }; var xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); var nFormat = createFormat({decimals:9}); var angleFormat = createFormat({decimals:6, scale:DEG}); /** Returns the layer for the current section. */ function getLayer() { // the layer to output into if (properties.putOperationsInSeparateLayers) { return properties.layer + getCurrentSectionId(); } return properties.layer; } function onOpen() { // use this to force unit to mm // xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4), scale:(unit == MM) ? 1 : 25.4}); writeln("999"); writeln("Generated by Autodesk CAM - http://cam.autodesk.com"); if (properties.useTimeStamp) { var d = new Date(); writeln("999"); writeln("Generated at " + d); } writeln("0"); writeln("SECTION"); writeln("2"); writeln("HEADER"); writeln("9"); writeln("$ACADVER"); writeln("1"); writeln("AC1006"); writeln("9"); writeln("$ANGBASE"); writeln("50"); writeln("0"); // along +X writeln("9"); writeln("$ANGDIR"); writeln("70"); writeln("0"); // ccw arcs writeln("0"); writeln("ENDSEC"); writeln("0"); writeln("SECTION"); writeln("2"); writeln("BLOCKS"); writeln("0"); writeln("ENDSEC"); var box = new BoundingBox(); // always includes origin for (var i = 0; i < getNumberOfSections(); ++i) { box.expandToBox(getSection(i).getGlobalBoundingBox()); } writeln("9"); writeln("$EXTMIN"); writeln("10"); // X writeln(xyzFormat.format(box.lower.x)); writeln("20"); // Y writeln(xyzFormat.format(box.lower.y)); writeln("30"); // Z writeln(xyzFormat.format(box.lower.z)); writeln("9"); writeln("$EXTMAX"); writeln("10"); // X writeln(xyzFormat.format(box.upper.x)); writeln("20"); // Y writeln(xyzFormat.format(box.upper.y)); writeln("30"); // Z writeln(xyzFormat.format(box.upper.z)); writeln("0"); writeln("SECTION"); writeln("2"); writeln("ENTITIES"); // entities start here } function onComment(text) { } var drillingMode = false; 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); drillingMode = hasParameter("operation-strategy") && (getParameter("operation-strategy") == "drill"); } function onParameter(name, value) { } function onDwell(seconds) { } function onCycle() { } function onCyclePoint(x, y, z) { if (!properties.includeDrill) { return; } writeln("0"); writeln("POINT"); writeln("8"); // layer writeln(getLayer()); writeln("62"); // color writeln(1); writeln("10"); // X writeln(xyzFormat.format(x)); writeln("20"); // Y writeln(xyzFormat.format(y)); writeln("30"); // Z writeln(xyzFormat.format(z)); } function onCycleEnd() { } function writeLine(x, y, z) { if (drillingMode) { return; // ignore since we only want points } if (radiusCompensation != RADIUS_COMPENSATION_OFF) { error(localize("Compensation in control is not supported.")); return; } var color; switch (movement) { case MOVEMENT_CUTTING: case MOVEMENT_REDUCED: case MOVEMENT_FINISH_CUTTING: color = 1; break; case MOVEMENT_RAPID: case MOVEMENT_HIGH_FEED: if (properties.onlyCutting) { return; // skip } color = 3; break; case MOVEMENT_LEAD_IN: case MOVEMENT_LEAD_OUT: case MOVEMENT_LINK_TRANSITION: case MOVEMENT_LINK_DIRECT: if (properties.onlyCutting) { return; // skip } color = 2; break; default: if (properties.onlyCutting) { return; // skip } color = 4; } var start = getCurrentPosition(); if (properties.only2D) { if ((xyzFormat.format(start.x) == xyzFormat.format(x)) && (xyzFormat.format(start.y) == xyzFormat.format(y))) { return; // ignore vertical } } writeln("0"); writeln("LINE"); writeln("8"); // layer writeln(getLayer()); writeln("62"); // color writeln(color); writeln("10"); // X writeln(xyzFormat.format(start.x)); writeln("20"); // Y writeln(xyzFormat.format(start.y)); writeln("30"); // Z writeln(xyzFormat.format(properties.only2D ? 0 : start.z)); writeln("11"); // X writeln(xyzFormat.format(x)); writeln("21"); // Y writeln(xyzFormat.format(y)); writeln("31"); // Z writeln(xyzFormat.format(properties.only2D ? 0 : z)); } function onRapid(x, y, z) { writeLine(x, y, z); } function onLinear(x, y, z, feed) { writeLine(x, y, z); } function onRapid5D(x, y, z, dx, dy, dz) { onRapid(x, y, z); } function onLinear5D(x, y, z, dx, dy, dz, feed) { onLinear(x, y, z); } function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { if (getCircularPlane() != PLANE_XY) { // start and end angle reference is unknown linearize(tolerance); return; } if (clockwise && properties.forceSameDirection) { linearize(tolerance); return; } if (properties.only2D) { if (getCircularPlane() != PLANE_XY) { linearize(tolerance); return; } } if (radiusCompensation != RADIUS_COMPENSATION_OFF) { error(localize("Compensation in control is not supported.")); return; } var color; switch (movement) { case MOVEMENT_CUTTING: case MOVEMENT_REDUCED: case MOVEMENT_FINISH_CUTTING: color = 1; break; case MOVEMENT_RAPID: case MOVEMENT_HIGH_FEED: if (properties.onlyCutting) { return; // skip } color = 3; break; case MOVEMENT_LEAD_IN: case MOVEMENT_LEAD_OUT: case MOVEMENT_LINK_TRANSITION: case MOVEMENT_LINK_DIRECT: if (properties.onlyCutting) { return; // skip } color = 2; break; default: if (properties.onlyCutting) { return; // skip } color = 4; } writeln("0"); writeln("ARC"); writeln("8"); // layer writeln(getLayer()); writeln("62"); // color writeln(color); writeln("10"); // X writeln(xyzFormat.format(cx)); writeln("20"); // Y writeln(xyzFormat.format(cy)); writeln("30"); // Z writeln(xyzFormat.format(properties.only2D ? 0 : cz)); writeln("40"); // radius writeln(xyzFormat.format(getCircularRadius())); var start = getCurrentPosition(); var startAngle = Math.atan2(start.y - cy, start.x - cx); var endAngle = Math.atan2(y - cy, x - cx); // var endAngle = startAngle + (clockwise ? -1 : 1) * getCircularSweep(); if (clockwise) { // we must be ccw var temp = startAngle; startAngle = endAngle; endAngle = temp; } writeln("50"); // start angle writeln(angleFormat.format(startAngle)); writeln("51"); // end angle writeln(angleFormat.format(endAngle)); if (getCircularPlane() != PLANE_XY) { validate(!properties.only2D, "Invalid handling on onCircular()."); var n = getCircularNormal(); writeln("210"); // X writeln(nFormat.format(n.x)); writeln("220"); // Y writeln(nFormat.format(n.y)); writeln("230"); // Y writeln(nFormat.format(n.z)); } } function onCommand() { } function onSectionEnd() { } function onClose() { writeln("0"); writeln("ENDSEC"); writeln("0"); writeln("EOF"); }