diff --git a/plugins/PostProcessingPlugin/scripts/Mark2Tweaks.py b/plugins/PostProcessingPlugin/scripts/Mark2Tweaks.py new file mode 100644 index 0000000000..bc9168e931 --- /dev/null +++ b/plugins/PostProcessingPlugin/scripts/Mark2Tweaks.py @@ -0,0 +1,312 @@ +## +## Mark2Plugin - Mark2Tweaks: Cura PostProcessingPlugin script for the Mark 2. +## Copyright (C) 2016,2017 Krys Lawrence +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU Affero General Public License as +## published by the Free Software Foundation, either version 3 of the +## License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Affero General Public License for more details. +## +## You should have received a copy of the GNU Affero General Public License +## along with this program. If not, see . +## + +"""Add-on script for nallath's PostProcessingPlugin to help the Mark 2. + +See https://github.com/nallath/PostProcessingPlugin for details about the +plugin. + +Put this script in PostProcessingPlugin's scripts folder. +""" + + +import re +import traceback +import contextlib +from UM.Logger import Logger +from ..Script import Script + + +"""Convenience alias for UM.Logger.Logger.log.""" +log = Logger.log + + +@contextlib.contextmanager +def exception_handler(layer_num, log_not_raise=False): + """Either raise or just log the last exception.""" + try: + yield + except: + if log_not_raise: + layer_log(layer_num, 'e', ''.join(traceback.format_exc())) + else: + layer_log(layer_num, 'e', 'Exception! Traceback follows.') + raise + + +def layer_log(layer_num, message_type, message): + """Log a message prefixed with the curent layer number.""" + log(message_type, 'Layer {:.0f}: {}'.format(layer_num, message)) + + +class Mark2Tweaks(Script): + """Optimize the G-code output for the Mark 2.""" + + def getSettingDataString(self): + """Return script identification and GUI options.""" + # Note: The "version" key is not this script's version, but the API + # version of the PostProcessingPlugin. + return '''\ + { + "name": "Mark 2 Tweaks", + "key": "Mark2Tweaks", + "metadata": {}, + "version": 2, + "settings": { + "remove_hack": { + "label": "Clean Up Cura Workaround", + "description": + "The Mark 2 settings include a workaround to a Cura limitation. This tweak cleans up after it.", + "type": "bool", + "default_value": true + }, + "remove_superfluous": { + "label": "Remove Extra Movements", + "description": + "Remove superfluous movements after each tool change. This can improve print quality by preventing materials from incorrectly touching immediately after a tool change.", + "type": "bool", + "default_value": true + }, + "ignore_errors": { + "label": "Ignore Errors", + "description": + "If any errors occur while performing the tweaks, skip them keep going", + "type": "bool", + "default_value": true + } + } + }''' + + def execute(self, data): + """Process all G-code and apply selected tweaks.""" + log('d', '*** MARK 2 TWEAKS START ***') + remove_hack = self.getSettingValueByKey('remove_hack') + remove_superfluous = self.getSettingValueByKey('remove_superfluous') + ignore_errors = self.getSettingValueByKey('ignore_errors') + log('d', 'Remove Hack: {}'.format(remove_hack)) + log('d', 'Remove Superfluous: {}'.format(remove_superfluous)) + log('d', 'Ignore Errors: {}'.format(ignore_errors)) + for layer_idx, layer in enumerate(data): + lines = layer.split('\n') + layer_num = self.find_layer_num(lines) + if layer_num is None: + continue + # Copy of lines so lines can be deleted or inserted in loop + for line_idx, line in enumerate(lines[:]): + if not line in ('T0', 'T1'): + continue + if remove_hack: + with exception_handler(layer_num, ignore_errors): + self.remove_hack(layer_num, lines, line_idx) + if remove_superfluous: + with exception_handler(layer_num, ignore_errors): + self.remove_superfluous(layer_num, lines, line_idx) + data[layer_idx] = '\n'.join(lines) + log('d', '*** MARK 2 TWEAKS END ***') + return data + + def find_layer_num(self, lines): + """Return the current layer number as a float.""" + result = self.find_line(lines, ';LAYER:', whole=False) + if result is not None: + return self.getValue(result, ";LAYER:") + + def remove_hack(self, layer_num, lines, t_idx): + """Remove TinkerGnome's Cura print area workaround line. + + If there is a G0 between T and G10/M104, remove it. + There should only be one. + TinkerGnome says adding it was a hack/workaround so we can kill it. + """ + end_idx = self.find_g10_or_m104(layer_num, lines, t_idx) + hack = self.find_line_and_index(lines, 'G0', ('X', 'Y', 'Z'), t_idx, + end_idx) + if hack is None: + return + hack_line, hack_idx = hack + if (self.getValue(hack_line, 'Z') == 14 + and self.getValue(hack_line, 'Y') == 35): + layer_log(layer_num, 'd', 'Striping Cura print area hack.') + del lines[hack_idx] + + def remove_superfluous(self, layer_num, lines, t_idx): + """Collapse any post tool change movents into a single movement. + + Any non-extrusion movements after tool change should be collapsed into + a single line. Keep only the last G0/G1 but add the F and Z of the + first G0/G1. But only collapse if there is more than one line. + """ + start_idx = self.find_g10_or_m104(layer_num, lines, t_idx) + end_idx = self.find_line_index(lines, ('G0', 'G1'), 'E', start_idx) + assert end_idx is not None, \ + 'Cannot find extruding G0/G1 line after tool change.' + + first_g = self.find_line_and_index(lines, ('G0', 'G1'), None, + start_idx, end_idx) + assert first_g is not None, \ + 'Sanity Check: Could not find a G0/G1 line before extrusion and ' \ + 'after tool change.' + first_g_line, first_g_idx = first_g + assert first_g_idx < end_idx, \ + 'Sanity Check: First G0/G1 is >= to first extrusion.' + + f_value = self.getValue(first_g_line, 'F') + z_value = self.getValue(first_g_line, 'Z') + assert z_value is not None, \ + 'Sanity Check: Z value not found in first G0/G1 line.' + + self.delete_all_g0_or_g1_except_last(layer_num, lines, first_g_idx, + 'Collapsing post tool change movements.') + assert self.is_g0_or_g1(lines[first_g_idx]), \ + 'Sanity Check: Missing G0/G1 after collapse.' + assert not self.is_g0_or_g1(lines[first_g_idx+1]), \ + 'Sanity Check: More than one G0/G1 after collapse.' + + self.add_f_and_z_values(layer_num, lines, first_g_idx, z_value, + f_value) + assert self.getValue(lines[first_g_idx], 'Z') is not None, \ + 'Sanity Check: Missing required Z value.' + + def find_g10_or_m104(self, layer_num, lines, t_idx): + """Find the next G10 or M104 line. + + G10 is for UltiGCode-style G-code. + M104 is for RepRap-style G-code. + """ + idx = self.find_line_index(lines, 'G10', start=t_idx) + if idx is None: # Assume RepRap style G-code + idx = self.find_line_index(lines, 'M104', start=t_idx) + assert idx is not None, \ + 'Cannot find G10/M104 after tool change.' + assert t_idx < idx < t_idx + 10, \ + 'Sanity Check: G10/M104 too far from T' + return idx + + def delete_all_g0_or_g1_except_last(self, layer_num, lines, first_g_idx, + log_msg): + """Delete all G0/G1 lines, except the last one. + + As long as there is more than one G line, delete the first. + Subsequent G line indices move up by one == first_g_idx. + This works only if lines are deleted and not just replaced. + If only one G, never run. Last G is not deleted. + + Also log only once if one or more deletes occurs. + """ + has_logged = False + while self.is_g0_or_g1(lines[first_g_idx+1]): + if not has_logged: + # Never log on single line. Only log once if multiple lines. + layer_log(layer_num, 'd', log_msg) + has_logged = True + del lines[first_g_idx] + + def is_g0_or_g1(self, line): + """Return true is line is a G0 or G1 command.""" + return line.startswith('G0 ') or line.startswith('G1 ') + + def add_f_and_z_values(self, layer_num, lines, g_idx, z_value, + f_value=None): + """Add Z and F values to the indicated G0/G1 line. + + f_value is optional. + Existing Z and F values will not be replaced. + """ + line = lines[g_idx] + fields = line.split(' ') + if f_value is not None and self.getValue(line, 'F') is None: + fields.insert(1, 'F{}'.format(f_value)) + if self.getValue(line, 'Z') is None: + fields.append('Z{}'.format(z_value)) + lines[g_idx] = ' '.join(fields) + + def find_line(self, *args, **kwargs): + """Return just the line from self.find_line_and_index().""" + result = self.find_line_and_index(*args, **kwargs) + if result is not None: + return result[0] + + def find_line_index(self, *args, **kwargs): + """Return just the index from self.find_line_and_index().""" + result = self.find_line_and_index(*args, **kwargs) + if result is not None: + return result[1] + + def find_line_and_index(self, lines, commands, parameters=None, start=0, + end=None, whole=True): + """Find the first line in lines that matches the given criteria. + + lines: The iterable of strings to search + commands: The command string (or iterable thereof) with which the + line must start. If given an iterable (e.g. list), the + line can match *any* given command. + parameters: The parameter string (or iterable thereof) that the line + must contain. Specifically, self.getValue() must return + a value. If gien an iterable, the line must contain + *all* of the given parameters. (Optional) + start: The index after which to search lines. (Optional) + end: The index before witch to seach lines. (Optional) + whole: If true, only match on whole commands. If false, match + any command prefix. E.g. with whole=True, G1 will match + only G1 commands. With whole=False, G1 would match G1 and + G10 commands, or even G1butterfly commands. :) E.g. To + find all T commands, use commands='T' and whole=False. + + Returns: The matching line string and its index in lines as a tuple, or + None if not match was found. + """ + if isinstance(commands, str): + commands = (commands,) + if isinstance(parameters, str): + parameters = (parameters,) + if end is None: + end = len(lines) + for i, line in enumerate(lines[start:end], start): + for command in commands: + # Commands must be standalone, or there must be a space before + # the first parameter. This distinguise between G1 and G10, + # for example. + if (line == command + or line.startswith(command + (' ' if whole else ''))): + if parameters is None: + return line, i + else: + values = (self.getValue(line, p) for p in parameters) + values = (v for v in values if v is not None) + # Consume iterators/generators and force into sequences + if len(tuple(values)) == len(tuple(parameters)): + return line, i + + def getValue(self, line, key, default = None): + """Replacement version of getValue that fixes a couple bugs. + + Specifically, it allows variable length keys and should support missing + leading zeros on values < 1mm (e.g. X.45). CuraEngine likes to emit + those sometimes now. :( + """ + key_pos = line.find(key) + if key_pos == -1 or (';' in line and key_pos > line.find(';')): + return default + sub_part = line[key_pos + len(key):] + m = re.search('^[0-9]*\.?[0-9]*', sub_part) + if m is None: + return default + try: + return float(m.group(0)) + except: + return default \ No newline at end of file diff --git a/resources/definitions/Mark2_for_Ultimaker2.def.json b/resources/definitions/Mark2_for_Ultimaker2.def.json new file mode 100644 index 0000000000..f5f0af5de5 --- /dev/null +++ b/resources/definitions/Mark2_for_Ultimaker2.def.json @@ -0,0 +1,241 @@ +{ + "id": "Mark2_for_Ultimaker2", + "version": 2, + "name": "Mark2 for Ultimaker2", + "inherits": "ultimaker2_plus", + "metadata": { + "visible": true, + "author": "TheUltimakerCommunity", + "manufacturer": "Foehnsturm", + "category": "Other", + "has_variants": true, + "has_materials": true, + "has_machine_materials": false, + "has_machine_quality": false, + "has_variant_materials": false, + "weight": 2, + "file_formats": "text/x-gcode", + "icon": "icon_ultimaker.png", + "platform": "ultimaker2_platform.obj", + "platform_texture": "Mark2_for_Ultimaker2_backplate.png", + "machine_extruder_trains": + { + "0": "Mark2_extruder1", + "1": "Mark2_extruder2" + }, + "supported_actions": ["MachineSettingsAction", "UpgradeFirmware"] + }, + "overrides": { + "machine_name": { "default_value": "Mark2_for_Ultimaker2" }, + "machine_width": { + "default_value": 223 + }, + "machine_depth": { + "default_value": 223 + }, + "machine_height": { + "default_value": 203 + }, + "gantry_height": { + "default_value": 52 + }, + "machine_center_is_zero": { + "default_value": false + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_nozzle_heat_up_speed": { + "default_value": 3.5 + }, + "machine_nozzle_cool_down_speed": { + "default_value": 1.5 + }, + "machine_min_cool_heat_time_window": + { + "default_value": 15.0 + }, + "machine_show_variants": { + "default_value": true + }, + "machine_nozzle_head_distance": { + "default_value": 5 + }, + "machine_nozzle_expansion_angle": { + "default_value": 45 + }, + "machine_heat_zone_length": { + "default_value": 20 + }, + "machine_heated_bed": { + "default_value": true + }, + "speed_infill": { + "value": "speed_print" + }, + "speed_wall_x": { + "value": "speed_wall" + }, + "layer_height_0": { + "value": "round(machine_nozzle_size / 1.5, 2)" + }, + "line_width": { + "value": "round(machine_nozzle_size * 0.875, 2)" + }, + "speed_layer_0": { + "default_value": 20 + }, + "speed_support": { + "value": "speed_wall_0" + }, + "machine_max_feedrate_x": { + "default_value": 250 + }, + "machine_max_feedrate_y": { + "default_value": 250 + }, + "machine_max_feedrate_z": { + "default_value": 40 + }, + "machine_max_feedrate_e": { + "default_value": 45 + }, + "machine_acceleration": { + "default_value": 3000 + }, + "retraction_amount": { + "default_value": 5.1 + }, + "retraction_speed": { + "default_value": 25 + }, + "switch_extruder_retraction_amount": { + "default_value": 0, + "value": "retraction_amount", + "enabled": false + }, + "switch_extruder_retraction_speeds": { + "default_value": 25, + "value": "retraction_speed", + "enabled": false + }, + "switch_extruder_retraction_speed": { + "default_value": 25, + "value": "retraction_retract_speed", + "enabled": false + }, + "switch_extruder_prime_speed": { + "default_value": 25, + "value": "retraction_prime_speed", + "enabled": false + }, + "machine_head_with_fans_polygon": + { + "default_value": [ + [ -44, 14 ], + [ -44, -34 ], + [ 64, 14 ], + [ 64, -34 ] + ] + }, + "machine_use_extruder_offset_to_offset_coords": { + "default_value": false + }, + "machine_gcode_flavor": { + "default_value": "RepRap (Marlin/Sprinter)" + }, + "machine_start_gcode" : { + "default_value": "", + "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T0 ;reset filament diameter\\nM200 D0 T1\\nG28 Z0; home all\\nG28 X0 Y0\\nG0 Z20 F2400 ;move the platform to 20mm\\nG92 E0\\nM190 S{material_bed_temperature_layer_0}\\nM109 T0 S{material_standby_temperature, 0}\\nM109 T1 S{material_print_temperature_layer_0, 1}\\nM104 T0 S{material_print_temperature_layer_0, 0}\\nT1 ; move to the 2th head\\nG0 Z20 F2400\\nG92 E-7.0 ;prime distance\\nG1 E0 F45 ;purge nozzle\\nG1 E-5.1 F1500 ; retract\\nG1 X90 Z0.01 F5000 ; move away from the prime poop\\nG1 X50 F9000\\nG0 Z20 F2400\\nT0 ; move to the first head\\nM104 T1 S{material_standby_temperature, 1}\\nG0 Z20 F2400\\nM104 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 X60 Z0.01 F5000 ; move away from the prime poop\\nG1 X20 F9000\\nM400 ;finish all moves\\nG92 E0\\n;end of startup sequence\\n\"" + }, + "machine_end_gcode" : { + "default_value": "", + "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G90 ;absolute positioning\\nM104 S0 T0 ;extruder heater off\\nM104 S0 T1\\nM140 S0 ;turn off bed\\nT0 ; move to the first head\\nM107 ;fan off\"" + }, + "machine_extruder_count": { + "default_value": 2 + }, + "acceleration_enabled": + { + "default_value": true + }, + "acceleration_print": + { + "default_value": 2000, + "value": "2000" + }, + "acceleration_travel": + { + "default_value": 3000, + "value": "acceleration_print if magic_spiralize else 3000" + }, + "acceleration_layer_0": { "value": "acceleration_topbottom" }, + "acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" }, + "acceleration_support": { "value": "math.ceil(acceleration_print * 2000 / 4000)" }, + "acceleration_support_interface": { "value": "acceleration_topbottom" }, + "acceleration_topbottom": { "value": "math.ceil(acceleration_print * 500 / 4000)" }, + "acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 4000)" }, + "acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 500 / 1000)" }, + "jerk_enabled": + { + "default_value": true + }, + "jerk_print": + { + "default_value": 12 + }, + "jerk_travel": + { + "default_value": 20, + "value": "jerk_print if magic_spiralize else 20" + }, + "jerk_layer_0": { "value": "jerk_topbottom" }, + "jerk_prime_tower": { "value": "10 if jerk_print < 16 else math.ceil(jerk_print * 15 / 25)" }, + "jerk_support": { "value": "10 if jerk_print < 16 else math.ceil(jerk_print * 15 / 25)" }, + "jerk_support_interface": { "value": "jerk_topbottom" }, + "jerk_topbottom": { "value": "10 if jerk_print < 25 else math.ceil(jerk_print * 10 / 25)" }, + "jerk_wall": { "value": "10 if jerk_print < 16 else math.ceil(jerk_print * 15 / 25)" }, + "jerk_wall_0": { "value": "10 if jerk_wall < 16 else math.ceil(jerk_wall * 6 / 10)" }, + "jerk_travel_layer_0": { "value": "math.ceil(jerk_layer_0 * jerk_travel / jerk_print)" }, + "extruder_prime_pos_abs": { "default_value": false }, + "machine_extruder_start_pos_abs": { "default_value": false }, + "machine_extruder_start_pos_x": { "value": 0.0 }, + "machine_extruder_start_pos_y": { "value": 0.0 }, + "machine_extruder_end_pos_abs": { "default_value": false }, + "machine_extruder_end_pos_x": { "value": 0.0 }, + "machine_extruder_end_pos_y": { "value": 0.0 }, + "extruder_prime_pos_x": { "default_value": 0.0, "enabled": false }, + "extruder_prime_pos_y": { "default_value": 0.0, "enabled": false }, + "extruder_prime_pos_z": { "default_value": 0.0, "enabled": false }, + "start_layers_at_same_position": + { + "default_value": false, + "enabled": false, + "value": false + }, + "layer_start_x": + { + "default_value": 105.0, + "enabled": false + }, + "layer_start_y": + { + "default_value": 27.0, + "enabled": false + }, + "prime_tower_position_x": { + "default_value": 185 + }, + "prime_tower_position_y": { + "default_value": 160 + }, + "machine_disallowed_areas": { + "default_value": [ + [[-115, 112.5], [ -10, 112.5], [ -10, 72.5], [-115, 72.5]], + [[ 115, 112.5], [ 115, 72.5], [ 15, 72.5], [ 15, 112.5]], + [[-115, -112.5], [-115, -87.5], [ 115, -87.5], [ 115, -112.5]], + [[-115, 72.5], [-97, 72.5], [-97, -112.5], [-115, -112.5]] + ] + } + } +} diff --git a/resources/extruders/Mark2_extruder1.def.json b/resources/extruders/Mark2_extruder1.def.json new file mode 100644 index 0000000000..915c331083 --- /dev/null +++ b/resources/extruders/Mark2_extruder1.def.json @@ -0,0 +1,19 @@ +{ + "id": "Mark2_extruder1", + "version": 2, + "name": "Extruder 1", + "inherits": "fdmextruder", + "metadata": { + "machine": "Mark2_for_Ultimaker2", + "position": "0" + }, + + "overrides": { + "extruder_nr": { + "default_value": 0, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { "default_value": 0.0 }, + "machine_nozzle_offset_y": { "default_value": 0.0 } + } +} diff --git a/resources/extruders/Mark2_extruder2.def.json b/resources/extruders/Mark2_extruder2.def.json new file mode 100644 index 0000000000..2c05a09391 --- /dev/null +++ b/resources/extruders/Mark2_extruder2.def.json @@ -0,0 +1,19 @@ +{ + "id": "Mark2_extruder2", + "version": 2, + "name": "Extruder 2", + "inherits": "fdmextruder", + "metadata": { + "machine": "Mark2_for_Ultimaker2", + "position": "1" + }, + + "overrides": { + "extruder_nr": { + "default_value": 1, + "maximum_value": "1" + }, + "machine_nozzle_offset_x": { "default_value": 0.0 }, + "machine_nozzle_offset_y": { "default_value": 0.0 } + } +} diff --git a/resources/images/Mark2_for_Ultimaker2_backplate.png b/resources/images/Mark2_for_Ultimaker2_backplate.png new file mode 100644 index 0000000000..c1958c7300 Binary files /dev/null and b/resources/images/Mark2_for_Ultimaker2_backplate.png differ diff --git a/resources/variants/Mark2_for_Ultimaker2_0.25.inst.cfg b/resources/variants/Mark2_for_Ultimaker2_0.25.inst.cfg new file mode 100644 index 0000000000..32d12214b2 --- /dev/null +++ b/resources/variants/Mark2_for_Ultimaker2_0.25.inst.cfg @@ -0,0 +1,19 @@ +[general] +name = 0.25 mm +version = 4 +definition = Mark2_for_Ultimaker2 + +[metadata] +setting_version = 7 +type = variant +hardware_type = nozzle + +[values] +coasting_min_volume = 0.17 +coasting_volume = 0.1 +machine_nozzle_size = 0.25 +machine_nozzle_tip_outer_diameter = 0.8 +raft_airgap = 0.25 +speed_topbottom = =round(speed_print / 1.5, 1) +speed_wall = =round(speed_print / 1.2, 1) +speed_wall_0 = =1 if speed_wall < 5 else (speed_wall - 5) diff --git a/resources/variants/Mark2_for_Ultimaker2_0.4.inst.cfg b/resources/variants/Mark2_for_Ultimaker2_0.4.inst.cfg new file mode 100644 index 0000000000..5a04878a4e --- /dev/null +++ b/resources/variants/Mark2_for_Ultimaker2_0.4.inst.cfg @@ -0,0 +1,17 @@ +[general] +name = 0.4 mm +version = 4 +definition = Mark2_for_Ultimaker2 + +[metadata] +setting_version = 7 +type = variant +hardware_type = nozzle + +[values] +machine_nozzle_size = 0.4 +machine_nozzle_tip_outer_diameter = 1.05 +speed_wall = =round(speed_print / 1.25, 1) +speed_wall_0 = =max(speed_wall - 10, 1) +speed_topbottom = =round(speed_print / 2.25, 1) + diff --git a/resources/variants/Mark2_for_Ultimaker2_0.6.inst.cfg b/resources/variants/Mark2_for_Ultimaker2_0.6.inst.cfg new file mode 100644 index 0000000000..b9e1745174 --- /dev/null +++ b/resources/variants/Mark2_for_Ultimaker2_0.6.inst.cfg @@ -0,0 +1,18 @@ +[general] +name = 0.6 mm +version = 4 +definition = Mark2_for_Ultimaker2 + +[metadata] +setting_version = 7 +type = variant +hardware_type = nozzle + +[values] +machine_nozzle_size = 0.6 +machine_nozzle_tip_outer_diameter = 1.25 +coasting_volume = 1.36 +speed_wall = =round(speed_print * 4 / 3, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2, 1) + diff --git a/resources/variants/Mark2_for_Ultimaker2_0.8.inst.cfg b/resources/variants/Mark2_for_Ultimaker2_0.8.inst.cfg new file mode 100644 index 0000000000..4656c9f502 --- /dev/null +++ b/resources/variants/Mark2_for_Ultimaker2_0.8.inst.cfg @@ -0,0 +1,18 @@ +[general] +name = 0.8 mm +version = 4 +definition = Mark2_for_Ultimaker2 + +[metadata] +setting_version = 7 +type = variant +hardware_type = nozzle + +[values] +machine_nozzle_size = 0.8 +machine_nozzle_tip_outer_diameter = 1.35 +coasting_volume = 3.22 +speed_wall = =round(speed_print * 4 / 3, 1) +speed_wall_0 = =1 if speed_wall < 10 else (speed_wall - 10) +speed_topbottom = =round(speed_print / 2, 1) +