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)
+