/** Copyright (C) 2018-2025 by Autodesk, Inc. All rights reserved. Meltio M450 DED post configuration. $Revision: 44161 f187ea25b82f4dac92873cf91c53c80db78df59a $ $Date: 2025-01-22 11:35:28 $ FORKID {1C80CAA7-D8B4-4AAC-86B5-F42F646E9760} */ description = "Meltio M450"; vendor = "Meltio"; vendorUrl = "http://www.meltio3d.com"; legal = "Copyright (C) 2012-2025 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 45702; longDescription = "Meltio M450 post to export DED toolpaths using the additive fff operations in gcode format"; extension = "gcode"; setCodePage("ascii"); capabilities = CAPABILITY_ADDITIVE; tolerance = spatial(0.002, MM); highFeedrate = toPreciseUnit(3000, MM); // needed for range checking, will be effectively passed from Fusion var printerLimits = { x: {min:0, max:150.0}, //Defines the x bed size y: {min:0, max:150.0}, //Defines the y bed size z: {min:0, max:450.0} //Defines the z bed size }; // user-defined properties properties = { shieldGas: { title : "Shield Gas", description: "Shield Gas Flow Rate (L/min)", type : "integer", value : 5000, scope : "post" }, hotWireVoltage: { title : "Hot Wire Voltage", description: "Set Hot Wire Voltage (V)", type : "integer", value : 5000, scope : "post" }, hotWireCurrent: { title : "Hot Wire Current", description: "Set Hot Wire Current (A)", type : "integer", value : 1, scope : "post" }, comperatorVoltage: { title : "Comperator Voltage", description: "Comperator Voltage", type : "integer", value : 4000, scope : "post" } }; var extruderOffsets = [[0, 0, 0], [0, 0, 0]]; var activeExtruder = 0; //Track the active extruder. var integerFormat = createFormat({decimals:0}); var xyzFormat; var xFormat; var yFormat; var zFormat; var fFormat = createFormat({prefix:"F", zeropad:false}); var gFormat = createFormat({prefix:"G", width:1, zeropad:false, decimals:0}); var mFormat = createFormat({prefix:"M", width:2, zeropad:true, decimals:0}); var sFormat = createFormat({prefix:"S", zeropad:false}); var tFormat = createFormat({prefix:"T", width:1, zeropad:false, decimals:0}); var wFormat = createFormat({prefix:"W", zeropad:false}); var feedFormat; var dimensionFormat; var gMotionModal = createModal({force:true}, gFormat); // modal group 1 // G0-G3, ... var gPlaneModal = createModal({onchange:function () {gMotionModal.reset();}}, gFormat); // modal group 2 // G17-19 //Actually unused var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 var depositionModal = createModal({}, mFormat); var xOutput; var yOutput; var zOutput; var feedOutput; var eOutput; // Extrusion length var layerHeight = 0; var currentHeight = 0; // generic functions // Writes the specified block. function writeBlock() { writeWords(arguments); } function formatComment(text) { return ";" + text; } /** Output a comment. */ function writeComment(text) { writeln(formatComment(text)); } // onOpen helper functions function formatCycleTime(cycleTime) { var seconds = cycleTime % 60 | 0; var minutes = ((cycleTime - seconds) / 60 | 0) % 60; var hours = (cycleTime - minutes * 60 - seconds) / (60 * 60) | 0; if (hours > 0) { return subst(localize("%1h:%2m:%3s"), hours, minutes, seconds); } else if (minutes > 0) { return subst(localize("%1m:%2s"), minutes, seconds); } else { return subst(localize("%1s"), seconds); } } function getPrinterGeometry() { machineConfiguration = getMachineConfiguration(); // Get the printer geometry from the machine configuration printerLimits.x.min = 0 - machineConfiguration.getCenterPositionX(); printerLimits.y.min = 0 - machineConfiguration.getCenterPositionY(); printerLimits.z.min = 0 + machineConfiguration.getCenterPositionZ(); printerLimits.x.max = machineConfiguration.getWidth() - machineConfiguration.getCenterPositionX(); printerLimits.y.max = machineConfiguration.getDepth() - machineConfiguration.getCenterPositionY(); printerLimits.z.max = machineConfiguration.getHeight() + machineConfiguration.getCenterPositionZ(); extruderOffsets[0][0] = machineConfiguration.getExtruderOffsetX(1); extruderOffsets[0][1] = machineConfiguration.getExtruderOffsetY(1); extruderOffsets[0][2] = machineConfiguration.getExtruderOffsetZ(1); if (numberOfExtruders > 1) { extruderOffsets[1] = []; extruderOffsets[1][0] = machineConfiguration.getExtruderOffsetX(2); extruderOffsets[1][1] = machineConfiguration.getExtruderOffsetY(2); extruderOffsets[1][2] = machineConfiguration.getExtruderOffsetZ(2); } } function setFormats(_desiredUnit) { // Do we need to force the output in millimeter, as some firmware doesn't support inches output? if (_desiredUnit != unit) { writeComment(subst(localize("Outputting the code in %1 since the printer does not support switching unit via G20/G21."), _desiredUnit == IN ? "inches" : "millimeters")); unit = _desiredUnit; } xyzFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); xFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); yFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); zFormat = createFormat({decimals:(unit == MM ? 3 : 4)}); feedFormat = createFormat({decimals:(unit == MM ? 0 : 1)}); dimensionFormat = createFormat({decimals:(unit == MM ? 3 : 4), zeropad:false, suffix:(unit == MM ? "mm" : "in")}); xOutput = createVariable({prefix:"X"}, xFormat); yOutput = createVariable({prefix:"Y"}, yFormat); zOutput = createVariable({prefix:"Z"}, zFormat); feedOutput = createVariable({prefix:"F"}, feedFormat); eOutput = createIncrementalVariable({prefix:"E"}, xyzFormat); // extrusion length sOutput = createVariable({prefix:"S", force:true}, xyzFormat); // parameter temperature or speed iOutput = createReferenceVariable({prefix:"I", force:true}, xyzFormat); // circular output jOutput = createReferenceVariable({prefix:"J", force:true}, xyzFormat); // circular output } function onOpen() { setFormats(MM); // machine require input code in MM if (highFeedMapping != HIGH_FEED_NO_MAPPING) { highFeedMapping = HIGH_FEED_NO_MAPPING; warning(localize("The selected High Feedrate mapping method is not supported and has been automatically set to 'Preserve rapid movement' by the postprocessor.")); } getPrinterGeometry(); if (programName) { writeComment(programName); } if (programComment) { writeComment(programComment); } writeComment("Printer Name: " + machineConfiguration.getVendor() + " " + machineConfiguration.getModel()); writeComment("Print Time: " + xyzFormat.format(printTime) + "s"); writeComment("Duration : " + formatCycleTime(printTime) + " " + integerFormat.format(layerCount) + " layers"); writeComment("Material Used: " + dimensionFormat.format(getExtruder(1).extrusionLength)); writeComment("Material Name: " + getExtruder(1).materialName); writeComment("Wire Filament Diameter: " + dimensionFormat.format(getExtruder(1).filamentDiameter)); writeComment("Layer Count: " + integerFormat.format(layerCount)); if (hasGlobalParameter("ext2-extrusion-len") && hasGlobalParameter("ext2-nozzle-dia") && hasGlobalParameter("ext2-temp") && hasGlobalParameter("ext2-filament-dia") && hasGlobalParameter("ext2-material-name") ) { writeComment("Extruder 2 Material Used: " + dimensionFormat.format(getExtruder(2).extrusionLength)); writeComment("Extruder 2 Material Name: " + getExtruder(2).materialName); writeComment("Extruder 2 Filament Diameter: " + dimensionFormat.format(getExtruder(2).filamentDiameter)); writeComment("Extruder 2 Nozzle Diameter: " + dimensionFormat.format(getExtruder(2).nozzleDiameter)); writeComment("Extruder 2 Max Temp: " + integerFormat.format(getExtruder(2).temperature)); writeComment("Extruder 2 Offset X: " + dimensionFormat.format(extruderOffsets[1][0])); writeComment("Extruder 2 Offset Y: " + dimensionFormat.format(extruderOffsets[1][1])); writeComment("Extruder 2 Offset Z: " + dimensionFormat.format(extruderOffsets[1][2])); } writeComment("Count of Bodies: " + integerFormat.format(partCount)); writeComment("Version of Fusion: " + getGlobalParameter("version")); writeBlock(" "); writeBlock("----Process setup----"); writeBlock(gAbsIncModal.format(90), formatComment("Absolute mode")); writeBlock(mFormat.format(83), formatComment("Wire feeder relative mode")); writeBlock(mFormat.format(106), sFormat.format(0)); writeBlock(gFormat.format(119), "Z" + integerFormat.format(0), formatComment("Set temporary Z offset to zero")); writeBlock(gFormat.format(29), fFormat.format(0), formatComment("Maintain compensation throughout the print")); writeBlock(gFormat.format(29), "A", formatComment("Activate Z live offset")); writeBlock(gFormat.format(215), "Z" + integerFormat.format(1), formatComment("Turn on shield gas")); writeBlock(gFormat.format(215), wFormat.format(1)); writeBlock(gFormat.format(215), "F" + integerFormat.format(getProperty("shieldGas")), formatComment("Set Shield gas flow rate")); writeBlock(" "); writeComment("Setup process control"); writeBlock(gFormat.format(122), "S" + integerFormat.format(getProperty("comperatorVoltage")), formatComment("Set comperator voltage")); writeBlock(gFormat.format(112), "V" + integerFormat.format(getProperty("hotWireVoltage")), "C" + integerFormat.format(getProperty("hotWireCurrent")), formatComment("Set hotwire voltage and current")); writeBlock(" "); writeBlock(";" + gFormat.format(113), sFormat.format(50), formatComment("Start blower fan at 50%")); writeBlock(gFormat.format(100), fFormat.format(1), formatComment("Turn on door fan")); writeBlock(mFormat.format(400), formatComment("Ensure all above commands have been executed")); writeBlock(gFormat.format(4), sFormat.format(4), formatComment("Wait")); writeBlock(gFormat.format(114), formatComment("Tare the load cell")); writeBlock(mFormat.format(400), formatComment("Ensure all above commands have been executed")); writeBlock(gFormat.format(4), sFormat.format(2), formatComment("Wait")); writeBlock(mFormat.format(400), formatComment("Ensure all above commands have been executed")); writeBlock(mFormat.format(83), formatComment("Wire feeder relative mode")); writeBlock(" "); writeBlock(gFormat.format(28), "X" + xyzFormat.format(0), formatComment("Home X")); writeBlock(gFormat.format(28), "Y" + xyzFormat.format(0), formatComment("Home Y")); writeBlock(gFormat.format(1), xOutput.format(toPreciseUnit(75, MM)), yOutput.format(toPreciseUnit(85, MM)), feedOutput.format(toPreciseUnit(2000, MM)), formatComment("Go to center for first probe")); //++++++++++++++------------------ writeBlock(" "); writeBlock(mFormat.format(102), formatComment("Probe Z")); writeBlock(tFormat.format(0), formatComment("Select tool zero")); writeBlock(" "); writeBlock("----Toolpath----"); depositionModal.format(103);// to disable the first output } // generic helper functions /** Force output of X, Y, and Z. */ function forceXYZ() { xOutput.reset(); yOutput.reset(); zOutput.reset(); } function forceFeed() { feedOutput.reset(); } function onSection() { var range = currentSection.getBoundingBox(); axes = ["x", "y", "z"]; formats = [xFormat, yFormat, zFormat]; for (var element in axes) { var min = formats[element].getResultingValue(range.lower[axes[element]]); var max = formats[element].getResultingValue(range.upper[axes[element]]); if (printerLimits[axes[element]].max < max || printerLimits[axes[element]].min > min) { error(localize("A toolpath is outside of the build volume.")); } } currentHeight = 0; } // miscellaneous entry functions function onComment(message) { writeComment(message); } function onParameter(name, value) { } // additive entry functions function onLayer(num) { writeComment(" layer " + integerFormat.format(num) + ", Z = " + xyzFormat.format(currentHeight)); if (num == 1) { layerHeight = getGlobalParameter("layer-height-first", 0); } else { layerHeight = getGlobalParameter("layer-height", 0); } currentHeight += layerHeight; } // motion entry functions function onRapid(_x, _y, _z) { writeBlock(depositionModal.format(103)); // disable deposition forceXYZ(); var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z - layerHeight); // fff toolpath generate at the bead top, DED need the bead bottom coordinate var f = feedOutput.format(toPreciseUnit(highFeedrate, MM)); if (x || y || z) { writeBlock(gMotionModal.format(1), x, y, z, f); } forceFeed(); } function onLinearExtrude(_x, _y, _z, _f, _e) { writeBlock(depositionModal.format(101)); // enable deposition forceXYZ(); var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z - layerHeight); // fff toolpath generate at the bead top, DED need the bead bottom coordinate var f = feedOutput.format(_f); var e = eOutput.format(_e); if (x || y || z || f || e) { writeBlock(gMotionModal.format(1), x, y, z, f, e); } } function onClose() { writeln(""); writeComment("End of gcode"); depositionModal.reset(); writeBlock(depositionModal.format(103)); depositionModal.reset(); writeBlock(" "); writeBlock(mFormat.format(140), sFormat.format(0), formatComment("Turn off bed")); writeBlock(gFormat.format(112), "P", "O", formatComment("Turn off TDK completely")); writeBlock(gFormat.format(108), "P", "O", formatComment("Laser off and set to zero")); writeBlock(gFormat.format(215), "Z" + integerFormat.format(0), formatComment("Turn off shielding gas")); writeBlock(gFormat.format(215), "F0000", formatComment("Set flow rate to zero")); writeBlock(gFormat.format(215), "Z" + integerFormat.format(0)); writeBlock(gFormat.format(215), wFormat.format(0)); writeBlock(gFormat.format(215), fFormat.format(0)); writeBlock(" "); writeBlock(gAbsIncModal.format(90)); writeBlock(depositionModal.format(103)); writeBlock(gAbsIncModal.format(91)); writeBlock(gFormat.format(1), zOutput.format(toPreciseUnit(20, MM)), feedOutput.format(toPreciseUnit(1000, MM))); writeBlock(gAbsIncModal.format(90)); writeBlock(" "); writeBlock(mFormat.format(400)); writeBlock(gFormat.format(4), sFormat.format(2), formatComment("wait for filer fan to stop")); writeBlock(mFormat.format(400)); writeBlock(gFormat.format(113), sFormat.format(100)); writeBlock(gFormat.format(4), sFormat.format(60)); writeBlock(gFormat.format(113), sFormat.format(0)); writeBlock(gFormat.format(100), fFormat.format(0)); } function setProperty(property, value) { properties[property].current = value; }