/** Copyright (C) 2012-2025 by Autodesk, Inc. All rights reserved. CREALITY post processor configuration. $Revision: 44161 f187ea25b82f4dac92873cf91c53c80db78df59a $ $Date: 2025-01-22 11:35:28 $ FORKID {76576242-61D1-4860-B383-89EB860D8E0A} */ description = "Creality family"; vendor = "CREALITY"; vendorUrl = "https://www.creality.com/"; legal = "Copyright (C) 2012-2025 by Autodesk, Inc."; certificationLevel = 2; minimumRevision = 45917; longDescription = "Post for exporting toolpath to the CREALITY CR10, CR20, and Ender range of printers in gcode (CR10, CR10 V2..., CR20 ..., Ender 3, 5...). As some firmware doesn't support inch gcode, we force millimeter generation by default. For allowing inch output change the 'Allow g-code output in Inches' property"; extension = "gcode"; setCodePage("ascii"); capabilities = CAPABILITY_ADDITIVE; tolerance = spatial(0.002, MM); highFeedrate = toPreciseUnit(6000, MM); minimumChordLength = spatial(0.25, MM); minimumCircularRadius = spatial(0.4, MM); maximumCircularRadius = spatial(1000, MM); minimumCircularSweep = toRad(0.01); maximumCircularSweep = toRad(180); allowHelicalMoves = false; // disable helical support allowSpiralMoves = false; // disable spiral support allowedCircularPlanes = 1 << PLANE_XY; // allow XY circular motion // user-defined properties properties = { enableBedLeveling: { title : "Enable bed leveling", description: "Specifies if the bed leveling is activated via G29 or M420.", type : "enum", values : [ {title:"G29", id:"g29"}, {title:"M420", id:"m420"}, {title:"No leveling", id:"no"} ], value: "no", scope: "post" }, fadeHeight: { title : "Fade height for compensation", description: "Specifies the maximum height for compensation.", type : "string", value : "2mm", scope : "post", kind : "spatial" }, allowInchesOutput: { title : "Allow g-code output in inches", description: "Specifies if the firmware support printing gcode generated in inches (G20).", type : "boolean", value : false, scope : "post" } }; // included properties if (typeof properties != "object") { properties = {}; } if (typeof groupDefinitions != "object") { groupDefinitions = {}; } // >>>>> INCLUDED FROM ../common/propertyTemperatureTower.cpi properties._trigger = { title : "Trigger", description: "Specifies whether to use the Z-height or layer number as the trigger to change temperature of the active Extruder.", type : "enum", values : [ {title:"Disabled", id:"disabled"}, {title:"by Height", id:"height"}, {title:"by Layer", id:"layer"} ], value: "disabled", scope: "post", group: "temperatureTower" }; properties._triggerValue = { title : "Trigger Value", description: "This number specifies either the Z-height or the layer number increment on when a change should be triggered.", type : "number", value : 10, scope : "post", group : "temperatureTower" }; properties.tempStart = { title : "Start Temperature", description: "Specifies the starting temperature for the active Extruder (degrees C). Note that the temperature specified in the print settings will be overridden by this value.", type : "integer", value : 190, range : [50, 450], scope : "post", group : "temperatureTower" }; properties.tempInterval = { title : "Temperature Interval", description: "Every step, increase the temperature of the active Extruder by this amount (degrees C).", type : "integer", value : 5, range : [-30, 30], scope : "post", group : "temperatureTower" }; groupDefinitions.temperatureTower = { title : "Temperature Tower", description: "Temperature Towers are used to test new filaments in order to identify the best printing temperature. " + "When utilized, this functionality generates a Gcode file where the temperature increases by a set amount, every step in height or layer number.", collapsed: true, order : 0 }; // <<<<< INCLUDED FROM ../common/propertyTemperatureTower.cpi // >>>>> INCLUDED FROM ../common/propertyRelativeExtrusion.cpi properties.relativeExtrusion = { title : "Relative extrusion mode", description: "Select the filament extrusion mode, either absolute or relative.", type : "boolean", value : true, scope : "post" }; // <<<<< INCLUDED FROM ../common/propertyRelativeExtrusion.cpi var gFormat = createFormat({prefix:"G", width:1, decimals:0}); var mFormat = createFormat({prefix:"M", width:2, zeropad:true, decimals:0}); var tFormat = createFormat({prefix:"T", width:1, decimals:0}); var integerFormat = createFormat({decimals:0}); var gMotionModal = createOutputVariable({control:CONTROL_FORCE}, gFormat); // modal group 1 - G0-G3 var gAbsIncModal = createOutputVariable({}, gFormat); // modal group 3 - G90-91 // Specify the required commands for your printer below. var commands = { extruderChangeCommand : undefined, // command to change the extruder setExtruderTemperature: mFormat.format(104), // command to set the extruder temperature waitExtruder : mFormat.format(109), // wait command for the extruder temperature setBedTemperature : mFormat.format(140), // command to set the bed temperature waitBed : mFormat.format(190), // wait command for the bed temperature reportTemperatures : mFormat.format(105), // command to report the temperatures to the printer fan : {on:mFormat.format(106), off:mFormat.format(107)}, // command turn the fan on/off extrusionMode : {relative:mFormat.format(83), absolute:mFormat.format(82)} // commands for relative / absolute filament extrusion mode }; var settings = { useG0 : true, // specifies to either use G0 or G1 commands for rapid movements skipParkPosition: false, // set to true to avoid output of the park position at the end of the program comments : { permittedCommentChars: " abcdefghijklmnopqrstuvwxyz0123456789.,=_-*+:/'", // letters are not case sensitive, use option 'outputFormat' below. Set to 'undefined' to allow any character prefix : ";", // specifies the prefix for the comment suffix : "", // specifies the suffix for the comment outputFormat : "ignoreCase", // can be set to "upperCase", "lowerCase" and "ignoreCase". Set to "ignoreCase" to write comments without upper/lower case formatting maximumLineLength : 80 // the maximum number of characters allowed in a line } }; // collected state var activeExtruder = 0; // track the active extruder. var bedLevelingHeight; function onOpen() { if (!getProperty("allowInchesOutput") && unit == IN) { writeComment(localize("The gcode had been generated in millimeters.")); writeComment(localize("As some Creality firmware dont support gcode in inches we forced millimeter")); writeComment(localize("If your firmware handle inches, ")); writeComment(localize("change the post property 'Allow g-code output in inches'")); } setFormats(!getProperty("allowInchesOutput") ? MM : unit); initializeMachineParameters(); bedLevelingHeight = getProperty("fadeHeight"); if (typeof writeProgramHeader == "function") { writeProgramHeader(); } writeBlock(gFormat.format(unit == MM ? 21 : 20)); // set unit } function onSection() { writeBlock(gMotionModal.format(0), feedOutput.format(rapidFeedrate)); writeBlock(gAbsIncModal.format(90)); // absolute spatial coordinates writeBlock(getCode(getProperty("relativeExtrusion") ? commands.extrusionMode.relative : commands.extrusionMode.absolute)); writeComment(localize("Reset multiplier")); writeBlock(mFormat.format(220), sOutput.format(100)); // reset FeedRate multiplier writeBlock(mFormat.format(221), sOutput.format(100)); // reset FlowRate multiplier // homing writeBlock(gFormat.format(28)); if (getProperty("enableBedLeveling") == "g29") { writeBlock(gFormat.format(29)); // enable auto bed leveling } if (getProperty("enableBedLeveling") == "m420") { writeComment(localize("Enable auto bed leveling")); writeBlock(mFormat.format(420), sOutput.format(1), zOutput.format(bedLevelingHeight)); // enable auto bed levelling } // lower build plate var initialPosition = getFramePosition(currentSection.getInitialPosition()); writeBlock(gMotionModal.format(1), zOutput.format(initialPosition.z), feedOutput.format(highFeedrate)); writeBlock(gFormat.format(92), eOutput.format(0)); forceXYZE(); } function onClose() { writeComment(localize("Disable stepper on all axis except z")); writeBlock(mFormat.format(84) + " X Y E"); writeComment(localize("END OF GCODE")); } // >>>>> INCLUDED FROM ../common/onBedTemp.cpi function onBedTemp(temp, wait) { if (wait) { writeBlock(getCode(commands.reportTemperatures)); writeBlock(getCode(commands.waitBed), sOutput.format(temp)); } else { writeBlock(getCode(commands.setBedTemperature), sOutput.format(temp)); } } // <<<<< INCLUDED FROM ../common/onBedTemp.cpi // >>>>> INCLUDED FROM ../common/onExtruderTemp.cpi function onExtruderTemp(temp, wait, id) { if (typeof executeTempTowerFeatures == "function" && getProperty("_trigger") != undefined) { if (getProperty("_trigger") != "disabled" && (getCurrentPosition().z == 0)) { temp = getProperty("tempStart"); // override temperature with the starting temperature for the temp tower feature } } if (wait) { writeBlock(getCode(commands.reportTemperatures)); writeBlock(getCode(commands.waitExtruder), sOutput.format(temp), tFormat.format(id)); } else { writeBlock(getCode(commands.setExtruderTemperature), sOutput.format(temp), tFormat.format(id)); } } // <<<<< INCLUDED FROM ../common/onExtruderTemp.cpi // >>>>> INCLUDED FROM ../common/onExtruderChange.cpi function onExtruderChange(id) { if (id > machineConfiguration.getNumberExtruders()) { error(subst(localize("This printer does not support the extruder '%1'."), integerFormat.format(id))); return; } writeBlock(getCode(commands.extruderChangeCommand), tFormat.format(id)); activeExtruder = id; forceXYZE(); } // <<<<< INCLUDED FROM ../common/onExtruderChange.cpi // >>>>> INCLUDED FROM ../common/onExtrusionReset.cpi function onExtrusionReset(length) { if (getProperty("relativeExtrusion")) { eOutput.setCurrent(0); } eOutput.reset(); writeBlock(gFormat.format(92), eOutput.format(length)); } // <<<<< INCLUDED FROM ../common/onExtrusionReset.cpi // >>>>> INCLUDED FROM ../common/onFanSpeed.cpi function onFanSpeed(speed, id) { if (!commands.fan) { return; } if (speed == 0) { writeBlock(getCode(commands.fan.off)); } else { writeBlock(getCode(commands.fan.on), sOutput.format(speed)); } } // <<<<< INCLUDED FROM ../common/onFanSpeed.cpi // >>>>> INCLUDED FROM ../common/onLayer.cpi function onLayer(num) { if (typeof executeTempTowerFeatures == "function") { executeTempTowerFeatures(num); } if (num == 1) { writeComment("LAYER_COUNT:" + integerFormat.format(layerCount)); } writeComment("LAYER:" + integerFormat.format(num)); if (typeof changeFilament == "function" && getProperty("changeLayers") != undefined) { changeFilament(num); } if (typeof pausePrint == "function" && getProperty("pauseLayers") != undefined) { pausePrint(num); } } // <<<<< INCLUDED FROM ../common/onLayer.cpi // >>>>> INCLUDED FROM ../common/writeProgramHeader.cpi function writeProgramHeader() { if (programName) { writeComment(programName); } if (programComment) { writeComment(programComment); } writeComment(subst(localize("Printer name: %1 %2"), machineConfiguration.getVendor(), machineConfiguration.getModel())); writeComment("TIME:" + integerFormat.format(printTime)); // do not localize writeComment(subst(localize("Print time: %1"), formatCycleTime(printTime))); for (var i = 1; i <= numberOfExtruders; ++i) { writeComment(subst(localize("Extruder %1 material used: %2"), i, dimensionFormat.format(toPreciseUnit(getExtruder(i).extrusionLength, MM)))); writeComment(subst(localize("Extruder %1 material name: %2"), i, getExtruder(i).materialName)); writeComment(subst(localize("Extruder %1 filament diameter: %2"), i, dimensionFormat.format(toPreciseUnit(getExtruder(i).filamentDiameter, MM)))); writeComment(subst(localize("Extruder %1 nozzle diameter: %2"), i, dimensionFormat.format(toPreciseUnit(getExtruder(i).nozzleDiameter, MM)))); writeComment(subst(localize("Extruder %1 offset x: %2"), i, dimensionFormat.format(toPreciseUnit(machineConfiguration.getExtruderOffsetX(i), MM)))); writeComment(subst(localize("Extruder %1 offset y: %2"), i, dimensionFormat.format(toPreciseUnit(machineConfiguration.getExtruderOffsetY(i), MM)))); writeComment(subst(localize("Extruder %1 offset z: %2"), i, dimensionFormat.format(toPreciseUnit(machineConfiguration.getExtruderOffsetZ(i), MM)))); writeComment(subst(localize("Extruder %1 max temp: %2"), i, integerFormat.format(getExtruder(i).temperature))); } writeComment(subst(localize("Bed temp: %1"), integerFormat.format(bedTemp))); writeComment(subst(localize("Layer count: %1"), integerFormat.format(layerCount))); writeComment(subst(localize("Width: %1"), dimensionFormat.format(toPreciseUnit(machineConfiguration.getWidth() - machineConfiguration.getCenterPositionX(), MM)))); writeComment(subst(localize("Depth: %1"), dimensionFormat.format(toPreciseUnit(machineConfiguration.getDepth() - machineConfiguration.getCenterPositionY(), MM)))); writeComment(subst(localize("Height: %1"), dimensionFormat.format(toPreciseUnit(machineConfiguration.getHeight() + machineConfiguration.getCenterPositionZ(), MM)))); writeComment(subst(localize("Center x: %1"), dimensionFormat.format(toPreciseUnit((machineConfiguration.getWidth() / 2.0) - machineConfiguration.getCenterPositionX(), MM)))); writeComment(subst(localize("Center y: %1"), dimensionFormat.format(toPreciseUnit((machineConfiguration.getDepth() / 2.0) - machineConfiguration.getCenterPositionY(), MM)))); writeComment(subst(localize("Center z: %1"), dimensionFormat.format(toPreciseUnit(machineConfiguration.getCenterPositionZ(), MM)))); writeComment(subst(localize("Count of bodies: %1"), integerFormat.format(partCount))); writeComment(subst(localize("Fusion version: %1"), getGlobalParameter("version"))); } // <<<<< INCLUDED FROM ../common/writeProgramHeader.cpi // >>>>> INCLUDED FROM ../common/setFormats.cpi function setFormats(_desiredUnit) { if (_desiredUnit != unit) { writeComment(subst(localize("This printer does not support programs in %1."), unit == IN ? "inches" : "millimeters")); writeComment(localize("The program has been converted to the supported unit.")); unit = _desiredUnit; } xyzFormat = 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 = createOutputVariable({prefix:"X"}, xyzFormat); yOutput = createOutputVariable({prefix:"Y"}, xyzFormat); zOutput = createOutputVariable({prefix:"Z"}, xyzFormat); feedOutput = createOutputVariable({prefix:"F"}, feedFormat); eOutput = createOutputVariable({prefix:"E", type:getProperty("relativeExtrusion") ? TYPE_INCREMENTAL : TYPE_ABSOLUTE}, xyzFormat); sOutput = createOutputVariable({prefix:"S", control:CONTROL_FORCE}, xyzFormat); // parameter temperature or speed iOutput = createOutputVariable({prefix:"I", control:CONTROL_FORCE}, xyzFormat); // circular output jOutput = createOutputVariable({prefix:"J", control:CONTROL_FORCE}, xyzFormat); // circular output if (typeof parseSpatialProperties == "function") { parseSpatialProperties(); } } // <<<<< INCLUDED FROM ../common/setFormats.cpi // >>>>> INCLUDED FROM ../common/commonAdditiveFunctions.cpi function writeBlock() { writeWords(arguments); } validate(settings.comments, "Setting 'comments' is required but not defined."); function formatComment(text) { var prefix = settings.comments.prefix; var suffix = settings.comments.suffix; var _permittedCommentChars = settings.comments.permittedCommentChars == undefined ? "" : settings.comments.permittedCommentChars; switch (settings.comments.outputFormat) { case "upperCase": text = text.toUpperCase(); _permittedCommentChars = _permittedCommentChars.toUpperCase(); break; case "lowerCase": text = text.toLowerCase(); _permittedCommentChars = _permittedCommentChars.toLowerCase(); break; case "ignoreCase": _permittedCommentChars = _permittedCommentChars.toUpperCase() + _permittedCommentChars.toLowerCase(); break; default: error(localize("Unsupported option specified for setting 'comments.outputFormat'.")); } if (_permittedCommentChars != "") { text = filterText(String(text), _permittedCommentChars); } text = String(text).substring(0, settings.comments.maximumLineLength - prefix.length - suffix.length); return text != "" ? prefix + text + suffix : ""; } /** Output a comment. */ function writeComment(text) { if (!text) { return; } var comments = String(text).split(EOL); for (comment in comments) { var _comment = formatComment(comments[comment]); if (_comment) { writeln(_comment); } } } function onComment(text) { writeComment(text); } function forceXYZE() { xOutput.reset(); yOutput.reset(); zOutput.reset(); eOutput.reset(); } function getCode(code) { return typeof code == "undefined" ? "" : code; } function onParameter(name, value) { switch (name) { case "feedRate": rapidFeedrate = toPreciseUnit(value, MM); break; } } var nextTriggerValue; var newTemperature; function executeTempTowerFeatures(num) { if (getProperty("_trigger") != "disabled") { var multiplier = getProperty("_trigger") == "height" ? 100 : 1; var currentValue = getProperty("_trigger") == "height" ? xyzFormat.format(getCurrentPosition().z * 100) : (num - 1); if (num == 1) { // initialize nextTriggerValue = getProperty("_triggerValue") * multiplier; newTemperature = getProperty("tempStart"); } else { if (currentValue >= nextTriggerValue) { newTemperature += getProperty("tempInterval"); nextTriggerValue += getProperty("_triggerValue") * multiplier; if (newTemperature <= maximumExtruderTemp[activeExtruder]) { onExtruderTemp(newTemperature, false, activeExtruder); } else { error(subst( localize("Temperature tower - The requested extruder temperature of '%1' exceeds the maximum value of '%2'."), newTemperature, maximumExtruderTemp[activeExtruder]) ); } } } } } 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 onRapid(_x, _y, _z) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var f = feedOutput.format(rapidFeedrate); if (settings.skipParkPosition) { var num = (!xyzFormat.areDifferent(_x, currentSection.getFinalPosition().x) ? 1 : 0) + (!xyzFormat.areDifferent(_y, currentSection.getFinalPosition().y) ? 1 : 0) + (!xyzFormat.areDifferent(_z, currentSection.getFinalPosition().z) ? 1 : 0); if (num > 0 && isLastMotionRecord(getNextRecord().getId() + 1)) { return; // skip movements to park position } } if (x || y || z || f) { writeBlock(gMotionModal.format(settings.useG0 ? 0 : 1), x, y, z, f); feedOutput.reset(); } } function onLinearExtrude(_x, _y, _z, _f, _e) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); 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 onCircularExtrude(_clockwise, _cx, _cy, _cz, _x, _y, _z, _f, _e) { var x = xOutput.format(_x); var y = yOutput.format(_y); var z = zOutput.format(_z); var f = feedOutput.format(_f); var e = eOutput.format(_e); var start = getCurrentPosition(); var i = iOutput.format(_cx - start.x); var j = jOutput.format(_cy - start.y); switch (getCircularPlane()) { case PLANE_XY: writeBlock(gMotionModal.format(_clockwise ? 2 : 3), x, y, i, j, f, e); break; default: linearize(tolerance); } } function getLayersFromProperty(_property) { var layer = getProperty(_property).toString().split(","); for (var i in layer) { if (!isNaN(parseFloat(layer[i])) && !isNaN(layer[i] - 0) && (layer[i] - Math.floor(layer[i])) === 0) { layer[i] = parseFloat(layer[i], 10); } else { error(subst( localize("The property '%1' contains an invalid value of '%2'. Only integers are allowed."), _property.title, layer[i]) ); return undefined; } } return layer; // returns an array of layer numbers as integers } var pauseLayers; function pausePrint(num) { if (getProperty("pauseLayers") != "") { validate(commands.pauseCommand != undefined, "The pause command is not defined."); if (num == 1) { // initialize array pauseLayers = getLayersFromProperty(properties.pauseLayers); } if (pauseLayers.indexOf(num) > -1) { writeComment(localize("PAUSE PRINT")); writeBlock(getCode(commands.displayCommand), getProperty("pauseMessage")); forceXYZE(); writeBlock(gMotionModal.format(1), zOutput.format(machineConfiguration.getParkPositionZ())); writeBlock(gMotionModal.format(1), xOutput.format(machineConfiguration.getParkPositionX()), yOutput.format(machineConfiguration.getParkPositionY())); writeBlock(getCode(commands.pauseCommand)); } } } var changeLayers; function changeFilament(num) { if (getProperty("changeLayers") != "") { validate(commands.changeFilament.command != undefined, "The filament change command is not defined."); if (num == 1) { // initialize array changeLayers = getLayersFromProperty(properties.changeLayers); } if (changeLayers.indexOf(num) > -1) { writeComment(localize("FILAMENT CHANGE")); if (getProperty("changeMessage") != "") { writeBlock(getCode(commands.displayCommand), getProperty("changeMessage")); } var words = new Array(); words.push(commands.changeFilament.command); /* if (!getProperty("useFirmwareConfiguration")) { words.push("X" + xyzFormat.format(machineConfiguration.getParkPositionX())); words.push("Y" + xyzFormat.format(machineConfiguration.getParkPositionY())); words.push("Z" + xyzFormat.format(getProperty("zPosition"))); words.push(commands.changeFilament.initialRetract + xyzFormat.format(getProperty("initialRetract"))); words.push(commands.changeFilament.removalRetract + xyzFormat.format(getProperty("removalRetract"))); } */ writeBlock(words); forceXYZE(); feedOutput.reset(); } } } function isLastMotionRecord(record) { while (!(getRecord(record).isMotion())) { if (getRecord(record).getType() == RECORD_OPERATION_END) { return true; } ++record; } return false; } var maximumExtruderTemp = [210, 210]; var rapidFeedrate = highFeedrate; function initializeMachineParameters() { var machineData = hasGlobalParameter("machine-v2") ? JSON.parse(getGlobalParameter("machine-v2")) : null; if (machineData && typeof machineData == "object") { // data in the machine definition is always stored as degree celsius and millimeters maximumExtruderTemp[0] = parseFloat(machineData.additive_extruder[0].max_temp); // max temp for extruder 1 if (machineData.additive_extruder[1]) { maximumExtruderTemp[1] = parseFloat(machineData.additive_extruder[1].max_temp); // max temp for extruder 2 } rapidFeedrate = toPreciseUnit(parseFloat(machineData.limits.default.speed_xy_max) * 60, MM); // convert mm/s to mm/min } else { warning("Failed to read machine data, default values will be used instead."); } 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.")); } } // <<<<< INCLUDED FROM ../common/commonAdditiveFunctions.cpi // >>>>> INCLUDED FROM include_files/parseSpatialProperties.cpi function parseSpatialProperties() { for (property in properties) { if (properties[property].kind && properties[property].kind == "spatial") { if (properties[property].type != "string") { error(localize("Spatial unit properties must be defined with a type of \"string\".")); } if (properties[property].scope.indexOf("operation") != -1) { error(localize("Spatial properties with scope \"operation\" are currently not supported.")); } var text = getProperty(property).toString().toUpperCase(); var unitStr = text.replace(/[^A-Z]/g, ""); var value = text.slice(0, text.length - 2); if (unitStr != "IN" && unitStr != "MM") { error(subst(localize("Unsupported unit \"%1\" entered for property \"%2\". Only 'IN' and 'MM' are supported."), unitStr, property)); } if (value.indexOf(",") != -1) { error(subst(localize("Invalid decimal separator 'comma' entered for property \"%1\". Only 'point' is supported."), property)); } properties[property].value = Number(value); if (isNaN(properties[property].value)) { error(subst(localize("Invalid numeric value of \"%1\" entered for property \"%2\"."), value, property)); } setProperty(property, properties[property].value *= (unitStr == "IN" && unit == MM) ? 25.4 : ((unitStr == "MM" && unit == IN) ? 1 / 25.4 : 1) ); } } } // <<<<< INCLUDED FROM include_files/parseSpatialProperties.cpi