Compare commits

..
79 changed files with 7988 additions and 25241 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -41
View File
@@ -1,6 +1,6 @@
{
"name": "Anker",
"version": "02.04.00.06",
"version": "02.04.00.05",
"force_update": "0",
"description": "Anker configurations",
"machine_model_list": [
@@ -304,26 +304,6 @@
"name": "Generic PLA Silk @Anker 0.25 nozzle",
"sub_path": "filament/Generic PLA Silk @Anker 0.25 nozzle.json"
},
{
"name": "AnkerMake PLA+ Basic @Anker base",
"sub_path": "filament/AnkerMake PLA+ Basic @Anker base.json"
},
{
"name": "AnkerMake PLA+ Glitter @Anker base",
"sub_path": "filament/AnkerMake PLA+ Glitter @Anker base.json"
},
{
"name": "AnkerMake PLA+ Matte @Anker base",
"sub_path": "filament/AnkerMake PLA+ Matte @Anker base.json"
},
{
"name": "AnkerMake PLA+ Metallic @Anker base",
"sub_path": "filament/AnkerMake PLA+ Metallic @Anker base.json"
},
{
"name": "AnkerMake PLA+ Silk @Anker base",
"sub_path": "filament/AnkerMake PLA+ Silk @Anker base.json"
},
{
"name": "Generic PLA+ @Anker",
"sub_path": "filament/Generic PLA+ @Anker.json"
@@ -347,26 +327,6 @@
{
"name": "Generic TPU @Anker",
"sub_path": "filament/Generic TPU @Anker.json"
},
{
"name": "AnkerMake PLA+ Basic @Anker",
"sub_path": "filament/AnkerMake PLA+ Basic @Anker.json"
},
{
"name": "AnkerMake PLA+ Glitter @Anker",
"sub_path": "filament/AnkerMake PLA+ Glitter @Anker.json"
},
{
"name": "AnkerMake PLA+ Matte @Anker",
"sub_path": "filament/AnkerMake PLA+ Matte @Anker.json"
},
{
"name": "AnkerMake PLA+ Metallic @Anker",
"sub_path": "filament/AnkerMake PLA+ Metallic @Anker.json"
},
{
"name": "AnkerMake PLA+ Silk @Anker",
"sub_path": "filament/AnkerMake PLA+ Silk @Anker.json"
}
],
"machine_list": [
@@ -1,50 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Basic @Anker base",
"inherits": "Generic PLA+ @Anker base",
"from": "system",
"filament_id": "OFUuZlQL",
"instantiation": "false",
"filament_vendor": [
"AnkerMake"
],
"nozzle_temperature": [
"200"
],
"nozzle_temperature_initial_layer": [
"230"
],
"hot_plate_temp": [
"65"
],
"textured_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"textured_plate_temp_initial_layer": [
"65"
],
"filament_flow_ratio": [
"1"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_cooling_layer_time": [
"60"
],
"slow_down_layer_time": [
"8"
],
"slow_down_min_speed": [
"30"
],
"default_filament_colour": [
"#FFFFFF"
],
"filament_max_volumetric_speed": [
"22"
]
}
@@ -1,16 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Basic @Anker",
"inherits": "AnkerMake PLA+ Basic @Anker base",
"from": "system",
"setting_id": "EfM5rmn4w6pMBajC",
"instantiation": "true",
"compatible_printers": [
"Anker M5 0.4 nozzle",
"Anker M5 0.6 nozzle",
"Anker M5 All-Metal 0.4 nozzle",
"Anker M5 All-Metal 0.6 nozzle",
"Anker M5C 0.4 nozzle",
"Anker M5C 0.6 nozzle"
]
}
@@ -1,50 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Glitter @Anker base",
"inherits": "Generic PLA+ @Anker base",
"from": "system",
"filament_id": "OFxCURdg",
"instantiation": "false",
"filament_vendor": [
"AnkerMake"
],
"nozzle_temperature": [
"200"
],
"nozzle_temperature_initial_layer": [
"230"
],
"hot_plate_temp": [
"65"
],
"textured_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"textured_plate_temp_initial_layer": [
"65"
],
"filament_flow_ratio": [
"1"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_cooling_layer_time": [
"60"
],
"slow_down_layer_time": [
"6"
],
"slow_down_min_speed": [
"30"
],
"default_filament_colour": [
"#00AD66"
],
"filament_max_volumetric_speed": [
"22"
]
}
@@ -1,16 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Glitter @Anker",
"inherits": "AnkerMake PLA+ Glitter @Anker base",
"from": "system",
"setting_id": "blGHp0htgHEj7khE",
"instantiation": "true",
"compatible_printers": [
"Anker M5 0.4 nozzle",
"Anker M5 0.6 nozzle",
"Anker M5 All-Metal 0.4 nozzle",
"Anker M5 All-Metal 0.6 nozzle",
"Anker M5C 0.4 nozzle",
"Anker M5C 0.6 nozzle"
]
}
@@ -1,50 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Matte @Anker base",
"inherits": "Generic PLA+ @Anker base",
"from": "system",
"filament_id": "OFKDOyNK",
"instantiation": "false",
"filament_vendor": [
"AnkerMake"
],
"nozzle_temperature": [
"210"
],
"nozzle_temperature_initial_layer": [
"230"
],
"hot_plate_temp": [
"65"
],
"textured_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"textured_plate_temp_initial_layer": [
"65"
],
"filament_flow_ratio": [
"1"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_cooling_layer_time": [
"60"
],
"slow_down_layer_time": [
"6"
],
"slow_down_min_speed": [
"30"
],
"default_filament_colour": [
"#FFFFFF"
],
"filament_max_volumetric_speed": [
"22"
]
}
@@ -1,13 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Matte @Anker",
"inherits": "AnkerMake PLA+ Matte @Anker base",
"from": "system",
"setting_id": "tPgwC1eEXyWPOn9S",
"instantiation": "true",
"compatible_printers": [
"Anker M5 0.4 nozzle",
"Anker M5 All-Metal 0.4 nozzle",
"Anker M5C 0.4 nozzle"
]
}
@@ -1,56 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Metallic @Anker base",
"inherits": "Generic PLA+ @Anker base",
"from": "system",
"filament_id": "OFBfbmtb",
"instantiation": "false",
"filament_vendor": [
"AnkerMake"
],
"nozzle_temperature": [
"200"
],
"textured_plate_temp": [
"60"
],
"textured_plate_temp_initial_layer": [
"60"
],
"filament_flow_ratio": [
"1"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_cooling_layer_time": [
"60"
],
"slow_down_layer_time": [
"6"
],
"slow_down_min_speed": [
"30"
],
"overhang_fan_speed": [
"50"
],
"reduce_fan_stop_start_freq": [
"0"
],
"filament_retraction_length": [
"1"
],
"filament_retraction_speed": [
"50"
],
"filament_deretraction_speed": [
"50"
],
"default_filament_colour": [
"#ACAC8A"
],
"filament_max_volumetric_speed": [
"20"
]
}
@@ -1,13 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Metallic @Anker",
"inherits": "AnkerMake PLA+ Metallic @Anker base",
"from": "system",
"setting_id": "jlbAMNNaEacdUASZ",
"instantiation": "true",
"compatible_printers": [
"Anker M5 0.4 nozzle",
"Anker M5 All-Metal 0.4 nozzle",
"Anker M5C 0.4 nozzle"
]
}
@@ -1,62 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Silk @Anker base",
"inherits": "Generic PLA+ @Anker base",
"from": "system",
"filament_id": "OFkxTGQc",
"instantiation": "false",
"filament_vendor": [
"AnkerMake"
],
"nozzle_temperature": [
"210"
],
"nozzle_temperature_initial_layer": [
"230"
],
"hot_plate_temp": [
"65"
],
"textured_plate_temp": [
"65"
],
"hot_plate_temp_initial_layer": [
"65"
],
"textured_plate_temp_initial_layer": [
"65"
],
"filament_flow_ratio": [
"1"
],
"close_fan_the_first_x_layers": [
"3"
],
"fan_cooling_layer_time": [
"60"
],
"slow_down_layer_time": [
"2"
],
"slow_down_min_speed": [
"20"
],
"filament_retraction_length": [
"0.5"
],
"filament_retraction_speed": [
"20"
],
"filament_wipe": [
"0"
],
"default_filament_colour": [
"#99ADA3"
],
"filament_deretraction_speed": [
"20"
],
"filament_max_volumetric_speed": [
"13"
]
}
@@ -1,15 +0,0 @@
{
"type": "filament",
"name": "AnkerMake PLA+ Silk @Anker",
"inherits": "AnkerMake PLA+ Silk @Anker base",
"from": "system",
"setting_id": "eVM9Ckwjl5vEvEKN",
"instantiation": "true",
"compatible_printers": [
"Anker M5 0.4 nozzle",
"Anker M5 All-Metal 0.4 nozzle",
"Anker M5 All-Metal 0.6 nozzle",
"Anker M5C 0.4 nozzle",
"Anker M5C 0.6 nozzle"
]
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Anycubic",
"version": "02.04.00.09",
"version": "02.04.00.08",
"force_update": "0",
"description": "Anycubic configurations",
"machine_model_list": [
@@ -110,7 +110,7 @@
"default_filament_profile": [
"Generic PLA @Anycubic"
],
"machine_start_gcode": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG0 Z0.2 F1800 ; move nozzle to print position\nG92 E0 ; specify current extruder position as zero\nM109 S[nozzle_temperature_initial_layer] ; wait for nozzle temp to stabilize\nG1 Y10 X180 E50 F1200 ; extrude a line in front of the printer\nG92 E0 ; specify current extruder position as zero\nG0 Z20 F6000 ; move head up\nG1 E-7 F2400 ; retract\nG04 S2 ; wait 2s\nG0 X0 F6000 ; wipe from oozed filament\nG1 E-1 F2400 ; undo some of the retraction to avoid oozing\nG1 F6000 ; set travel speed to move to start printing point\nM117",
"machine_start_gcode": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG0 Z0.2 F1800 ; move nozzle to print position\nG92 E0 ; specify current extruder position as zero\nG1 Y10 X180 E50 F1200 ; extrude a line in front of the printer\nG92 E0 ; specify current extruder position as zero\nG0 Z20 F6000 ; move head up\nG1 E-7 F2400 ; retract\nG04 S2 ; wait 2s\nG0 X0 F6000 ; wipe from oozed filament\nG1 E-1 F2400 ; undo some of the retraction to avoid oozing\nG1 F6000 ; set travel speed to move to start printing point\nM117",
"machine_end_gcode": "G4 ; wait\nG92 E0\nG1{if max_layer_z < printable_height} Z{z_offset+min(max_layer_z+30, printable_height)}{endif} ; move print head up\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200 F3000 ; home X axis\nM84 ; disable motors",
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]",
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "Bambulab",
"url": "http://www.bambulab.com/Parameters/vendor/BBL.json",
"version": "02.08.00.14",
"version": "02.08.00.13",
"force_update": "0",
"description": "the initial version of BBL configurations",
"machine_model_list": [
@@ -8,7 +8,6 @@
"0.4"
],
"printer_variant": "0.4",
"use_3mf": "1",
"bed_exclude_area": [
"0x0",
"28x0",
@@ -9,7 +9,6 @@
"0.4"
],
"printer_variant": "0.4",
"use_3mf": "1",
"best_object_pos": "0.3x0.5",
"bed_exclude_area": [],
"bed_temperature_formula": "by_highest_temp",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Prusa",
"version": "02.04.00.17",
"version": "02.04.00.16",
"force_update": "0",
"description": "Prusa configurations",
"machine_model_list": [
@@ -45,7 +45,7 @@
"35"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.04{elsif nozzle_diameter[filament_extruder_id]==0.25}0.1{elsif nozzle_diameter[filament_extruder_id]==0.3}0.06{elsif nozzle_diameter[filament_extruder_id]==0.35}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.03{elsif nozzle_diameter[filament_extruder_id]==0.6}0.02{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.02{elsif nozzle_diameter[filament_extruder_id]==0.5}0.018{elsif nozzle_diameter[filament_extruder_id]==0.6}0.012{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{elsif nozzle_diameter[filament_extruder_id]==0.25}0.09{elsif nozzle_diameter[filament_extruder_id]==0.3}0.065{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.04{elsif nozzle_diameter[filament_extruder_id]==0.25}0.1{elsif nozzle_diameter[filament_extruder_id]==0.3}0.06{elsif nozzle_diameter[filament_extruder_id]==0.35}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.03{elsif nozzle_diameter[filament_extruder_id]==0.6}0.02{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.02{elsif nozzle_diameter[filament_extruder_id]==0.5}0.018{elsif nozzle_diameter[filament_extruder_id]==0.6}0.012{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{elsif nozzle_diameter[filament_extruder_id]==0.25}0.09{elsif nozzle_diameter[filament_extruder_id]==0.3}0.065{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
],
"hot_plate_temp": [
"110"
@@ -78,7 +78,7 @@
"35"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.04{elsif nozzle_diameter[filament_extruder_id]==0.25}0.1{elsif nozzle_diameter[filament_extruder_id]==0.3}0.06{elsif nozzle_diameter[filament_extruder_id]==0.35}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.03{elsif nozzle_diameter[filament_extruder_id]==0.6}0.02{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.02{elsif nozzle_diameter[filament_extruder_id]==0.5}0.018{elsif nozzle_diameter[filament_extruder_id]==0.6}0.012{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{elsif nozzle_diameter[filament_extruder_id]==0.25}0.09{elsif nozzle_diameter[filament_extruder_id]==0.3}0.065{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.04{elsif nozzle_diameter[filament_extruder_id]==0.25}0.1{elsif nozzle_diameter[filament_extruder_id]==0.3}0.06{elsif nozzle_diameter[filament_extruder_id]==0.35}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.03{elsif nozzle_diameter[filament_extruder_id]==0.6}0.02{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.02{elsif nozzle_diameter[filament_extruder_id]==0.5}0.018{elsif nozzle_diameter[filament_extruder_id]==0.6}0.012{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{elsif nozzle_diameter[filament_extruder_id]==0.25}0.09{elsif nozzle_diameter[filament_extruder_id]==0.3}0.065{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
],
"hot_plate_temp": [
"110"
@@ -50,7 +50,7 @@
"0.8"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.053{elsif nozzle_diameter[filament_extruder_id]==0.5}0.042{elsif nozzle_diameter[filament_extruder_id]==0.6}0.032{elsif nozzle_diameter[filament_extruder_id]==0.8}0.018{elsif nozzle_diameter[filament_extruder_id]==0.25}0.18{elsif nozzle_diameter[filament_extruder_id]==0.3}0.1{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.053{elsif nozzle_diameter[filament_extruder_id]==0.5}0.042{elsif nozzle_diameter[filament_extruder_id]==0.6}0.032{elsif nozzle_diameter[filament_extruder_id]==0.8}0.018{elsif nozzle_diameter[filament_extruder_id]==0.25}0.18{elsif nozzle_diameter[filament_extruder_id]==0.3}0.1{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_wipe": [
"1"
@@ -38,7 +38,7 @@
"15"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One|CORE One L).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_z_hop": [
"0.6"
@@ -58,7 +58,7 @@
"7"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[0]==0.4}0.05{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.07{elsif nozzle_diameter[0]==0.35}0.06{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[0]==0.4}0.03{elsif nozzle_diameter[0]==0.5}0.022{elsif nozzle_diameter[0]==0.6}0.018{elsif nozzle_diameter[0]==0.8}0.012{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.075{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[0]==0.4}0.05{elsif nozzle_diameter[0]==0.25}0.14{elsif nozzle_diameter[0]==0.3}0.07{elsif nozzle_diameter[0]==0.35}0.06{elsif nozzle_diameter[0]==0.6}0.03{elsif nozzle_diameter[0]==0.5}0.035{elsif nozzle_diameter[0]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[0]==0.4}0.03{elsif nozzle_diameter[0]==0.5}0.022{elsif nozzle_diameter[0]==0.6}0.018{elsif nozzle_diameter[0]==0.8}0.012{elsif nozzle_diameter[0]==0.25}0.12{elsif nozzle_diameter[0]==0.3}0.075{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_z_hop": [
"0.6",
@@ -63,7 +63,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.04{elsif nozzle_diameter[filament_extruder_id]==0.25}0.1{elsif nozzle_diameter[filament_extruder_id]==0.3}0.06{elsif nozzle_diameter[filament_extruder_id]==0.35}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.03{elsif nozzle_diameter[filament_extruder_id]==0.6}0.02{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.02{elsif nozzle_diameter[filament_extruder_id]==0.5}0.018{elsif nozzle_diameter[filament_extruder_id]==0.6}0.012{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{elsif nozzle_diameter[filament_extruder_id]==0.25}0.09{elsif nozzle_diameter[filament_extruder_id]==0.3}0.065{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.04{elsif nozzle_diameter[filament_extruder_id]==0.25}0.1{elsif nozzle_diameter[filament_extruder_id]==0.3}0.06{elsif nozzle_diameter[filament_extruder_id]==0.35}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.03{elsif nozzle_diameter[filament_extruder_id]==0.6}0.02{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.02{elsif nozzle_diameter[filament_extruder_id]==0.5}0.018{elsif nozzle_diameter[filament_extruder_id]==0.6}0.012{elsif nozzle_diameter[filament_extruder_id]==0.8}0.01{elsif nozzle_diameter[filament_extruder_id]==0.25}0.09{elsif nozzle_diameter[filament_extruder_id]==0.3}0.065{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S40 ; set heatbreak target temp"
],
"filament_type": [
"ASA"
@@ -65,7 +65,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.6}0.025{elsif nozzle_diameter[filament_extruder_id]==0.8}0.016{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.6}0.025{elsif nozzle_diameter[filament_extruder_id]==0.8}0.016{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp"
],
"filament_type": [
"PA11-CF"
@@ -63,7 +63,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.6}0.025{elsif nozzle_diameter[filament_extruder_id]==0.8}0.016{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.6}0.025{elsif nozzle_diameter[filament_extruder_id]==0.8}0.016{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp"
],
"filament_type": [
"PC"
@@ -65,7 +65,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.6}0.025{elsif nozzle_diameter[filament_extruder_id]==0.8}0.016{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.6}0.025{elsif nozzle_diameter[filament_extruder_id]==0.8}0.016{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S45 ; set heatbreak target temp"
],
"filament_type": [
"PC-CF"
@@ -69,7 +69,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.053{elsif nozzle_diameter[filament_extruder_id]==0.5}0.042{elsif nozzle_diameter[filament_extruder_id]==0.6}0.032{elsif nozzle_diameter[filament_extruder_id]==0.8}0.018{elsif nozzle_diameter[filament_extruder_id]==0.25}0.18{elsif nozzle_diameter[filament_extruder_id]==0.3}0.1{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.07{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.09{elsif nozzle_diameter[filament_extruder_id]==0.35}0.08{elsif nozzle_diameter[filament_extruder_id]==0.6}0.04{elsif nozzle_diameter[filament_extruder_id]==0.5}0.05{elsif nozzle_diameter[filament_extruder_id]==0.8}0.02{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.053{elsif nozzle_diameter[filament_extruder_id]==0.5}0.042{elsif nozzle_diameter[filament_extruder_id]==0.6}0.032{elsif nozzle_diameter[filament_extruder_id]==0.8}0.018{elsif nozzle_diameter[filament_extruder_id]==0.25}0.18{elsif nozzle_diameter[filament_extruder_id]==0.3}0.1{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_type": [
"PETG"
@@ -64,7 +64,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One|CORE One L).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_type": [
"PLA"
@@ -65,7 +65,7 @@
"1"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_type": [
"PVB"
@@ -64,7 +64,7 @@
"0"
],
"filament_start_gcode": [
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|COREONE).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
"M900 K{if nozzle_diameter[filament_extruder_id]==0.4}0.05{elsif nozzle_diameter[filament_extruder_id]==0.25}0.14{elsif nozzle_diameter[filament_extruder_id]==0.3}0.07{elsif nozzle_diameter[filament_extruder_id]==0.35}0.06{elsif nozzle_diameter[filament_extruder_id]==0.6}0.03{elsif nozzle_diameter[filament_extruder_id]==0.5}0.035{elsif nozzle_diameter[filament_extruder_id]==0.8}0.015{else}0{endif} ; Filament gcode\n\n{if printer_notes=~/.*(MK4IS|XLIS|MK4S|MK3.9S|CORE One).*/}\nM572 S{if nozzle_diameter[filament_extruder_id]==0.4}0.036{elsif nozzle_diameter[filament_extruder_id]==0.5}0.025{elsif nozzle_diameter[filament_extruder_id]==0.6}0.022{elsif nozzle_diameter[filament_extruder_id]==0.8}0.014{elsif nozzle_diameter[filament_extruder_id]==0.25}0.12{elsif nozzle_diameter[filament_extruder_id]==0.3}0.08{else}0{endif} ; Filament gcode\n{endif}\n\nM142 S36 ; set heatbreak target temp"
],
"filament_type": [
"PLA"
-1
View File
@@ -405,7 +405,6 @@ set(lisbslic3r_sources
Polyline.hpp
PresetBundle.cpp
PresetBundle.hpp
PrinterBedAssets.hpp
PresetCacheFormat.cpp
PresetCacheFormat.hpp
Preset.cpp
-2
View File
@@ -1,5 +1,3 @@
#pragma once
#include <string>
namespace Slic3r {
+2 -308
View File
@@ -18,7 +18,6 @@
#include <cstdint>
#include <cmath>
#include <ctime>
#include <ios>
#include <optional>
#include <exception>
#include <memory>
@@ -30,7 +29,6 @@
#include <sstream>
#include "PresetBundle.hpp"
#include "PrinterBedAssets.hpp"
#include "Config.hpp"
#include "Exception.hpp"
@@ -66,7 +64,6 @@
#include <boost/algorithm/clamp.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/nowide/convert.hpp>
#include <boost/nowide/cstdio.hpp>
#include <boost/nowide/fstream.hpp>
#include <boost/property_tree/ini_parser.hpp>
@@ -1681,258 +1678,6 @@ bool PresetBundle::apply_vendor_config(
return true;
}
namespace {
// The two bed files a printer bundle can carry. Zip names are bed/<n>/<stem><ext>, never the source basename.
struct BedAssetSlot {
const char *option;
const char *stem;
};
constexpr BedAssetSlot k_bed_asset_slots[] = {
{"bed_custom_texture", "texture"},
{"bed_custom_model", "model"},
};
std::string zip_slashes(std::string name)
{
for (char &c : name)
if (c == '\\')
c = '/';
return name;
}
// The bed dialog loads only png/svg textures and stl models. Anything else is not a bed asset.
bool bed_extension_allowed(const char *option, const std::string &ext)
{
if (std::string(option) == "bed_custom_texture")
return boost::iequals(ext, ".png") || boost::iequals(ext, ".svg");
if (std::string(option) == "bed_custom_model")
return boost::iequals(ext, ".stl");
return false;
}
// Extension including the dot, or empty when this option may not use it.
std::string bed_asset_extension(const std::string &path, const char *option)
{
const auto slash = path.find_last_of("/\\");
const auto base = slash == std::string::npos ? 0 : slash + 1;
const auto dot = path.find_last_of('.');
if (dot == std::string::npos || dot < base || dot + 1 >= path.size())
return {};
const std::string ext = path.substr(dot);
if (!bed_extension_allowed(option, ext))
return {};
return ext;
}
bool utf8_is_file(const std::string &path)
{
if (path.empty())
return false;
boost::system::error_code ec;
#ifdef _WIN32
// A narrow path is the ANSI code page unless nowide_filesystem() has run.
const std::wstring wide = boost::nowide::widen(path);
if (wide.empty())
return false;
return boost::filesystem::is_regular_file(boost::filesystem::path(wide), ec) && !ec;
#else
return boost::filesystem::is_regular_file(path, ec) && !ec;
#endif
}
std::string bed_asset_dest_utf8(const fs::path &dest)
{
#ifdef _WIN32
return boost::nowide::narrow(dest.wstring());
#else
return dest.string();
#endif
}
// True only for bed/<digits>/<stem><ext> with an extension the bed dialog accepts for this field.
bool accepted_bed_zip_name(const std::string &raw, const BedAssetSlot &slot, const fs::path &bundle_dir,
std::string &zip_name, std::string &folder)
{
const std::string name = zip_slashes(raw);
if (name.find("..") != std::string::npos)
return false;
if (name.size() < 8 || name.compare(0, 4, "bed/") != 0)
return false;
const auto slash = name.find('/', 4);
if (slash == std::string::npos || slash == 4 || name.find('/', slash + 1) != std::string::npos)
return false;
const std::string digits = name.substr(4, slash - 4);
for (unsigned char c : digits) {
if (!std::isdigit(c))
return false;
}
const std::string filename = name.substr(slash + 1);
const std::string ext = bed_asset_extension(filename, slot.option);
if (ext.empty() || filename != std::string(slot.stem) + ext)
return false;
if (!is_path_within_root(name, bundle_dir))
return false;
zip_name = name;
folder = digits;
return true;
}
struct PendingBedAsset {
std::string option;
std::string zip_name;
std::string dest;
std::string printer_key;
fs::path final_path;
fs::path staged;
};
// Validated asset names only. A raw manifest value that fails the check is not skipped later,
// so a value like printer/Name.json cannot hide that preset.
// printer_asset is keyed by printer_config zip entry. A flat (unkeyed) object is not read.
std::vector<PendingBedAsset> pending_bed_assets(const json &bundle_json, const fs::path &bundle_dir,
std::unordered_set<std::string> &skip_names,
const std::unordered_set<std::string> &zip_entries)
{
std::vector<PendingBedAsset> pending;
if (!bundle_json.contains("printer_asset") || !bundle_json["printer_asset"].is_object())
return pending;
const json &assets = bundle_json["printer_asset"];
for (auto it = assets.begin(); it != assets.end(); ++it) {
const std::string printer_key = it.key();
if (zip_entries.count(printer_key) == 0) {
BOOST_LOG_TRIVIAL(warning) << "Printer bundle asset entry is ignored, no matching printer in the zip: " << printer_key;
continue;
}
if (!it.value().is_object())
continue;
const json &per_printer = it.value();
for (const BedAssetSlot &slot : k_bed_asset_slots) {
if (!per_printer.contains(slot.option) || !per_printer[slot.option].is_string())
continue;
const std::string raw = per_printer[slot.option].get<std::string>();
std::string zip_name;
std::string folder;
if (!accepted_bed_zip_name(raw, slot, bundle_dir, zip_name, folder)) {
BOOST_LOG_TRIVIAL(warning) << "Printer bundle asset path is rejected: " << raw;
continue;
}
const std::string filename = zip_name.substr(zip_name.rfind('/') + 1);
const fs::path final_path = fs::absolute(bundle_dir / "bed" / folder / filename);
pending.push_back({slot.option, zip_name, bed_asset_dest_utf8(final_path), printer_key, final_path, {}});
skip_names.insert(zip_name);
}
}
return pending;
}
// Stage under temp_folder. The bundle bed/ directory is not touched until a printer preset keeps the path.
bool stage_bed_asset(mz_zip_archive &zip, PendingBedAsset &asset, const fs::path &temp_folder)
{
size_t size = 0;
void *buf = mz_zip_reader_extract_file_to_heap(&zip, asset.zip_name.c_str(), &size, MZ_ZIP_FLAG_CASE_SENSITIVE);
if (buf == nullptr) {
BOOST_LOG_TRIVIAL(warning) << "Printer bundle asset is missing, skipping " << asset.option << ": " << asset.zip_name;
return false;
}
const std::string filename = asset.zip_name.substr(asset.zip_name.rfind('/') + 1);
asset.staged = temp_folder / "bed" / asset.final_path.parent_path().filename() / filename;
boost::system::error_code ec;
fs::create_directories(asset.staged.parent_path(), ec);
const std::string staged_utf8 = bed_asset_dest_utf8(asset.staged);
bool wrote = false;
if (!ec) {
boost::nowide::ofstream out(staged_utf8, std::ios::binary | std::ios::trunc);
wrote = static_cast<bool>(out);
if (wrote && size > 0)
wrote = static_cast<bool>(out.write(static_cast<const char *>(buf), static_cast<std::streamsize>(size)));
}
mz_free(buf);
if (!wrote) {
BOOST_LOG_TRIVIAL(warning) << "Printer bundle asset could not be written, skipping " << asset.option << ": " << staged_utf8;
fs::remove(asset.staged, ec);
return false;
}
return true;
}
bool install_bed_asset(const PendingBedAsset &asset)
{
boost::system::error_code ec;
fs::create_directories(asset.final_path.parent_path(), ec);
if (!ec)
fs::copy_file(asset.staged, asset.final_path, fs::copy_options::overwrite_existing, ec);
if (ec) {
BOOST_LOG_TRIVIAL(warning) << "Printer bundle asset could not be installed: " << asset.dest;
return false;
}
return true;
}
bool is_pending_bed_asset_entry(const std::string &entry, const std::unordered_set<std::string> &names)
{
return names.count(entry) != 0 || names.count(zip_slashes(entry)) != 0;
}
bool printer_kept_bed_paths(const PresetCollection &printers, const std::map<std::string, std::string> &paths)
{
if (paths.empty())
return false;
for (const Preset &preset : printers.get_presets()) {
for (const auto &entry : paths)
if (preset.config.opt_string(entry.first) == entry.second)
return true;
}
return false;
}
} // namespace
bool append_printer_bed_assets(mz_zip_archive &zip, const DynamicPrintConfig &config, json &bundle_structure,
const std::string &printer_config_entry, int printer_index)
{
if (printer_config_entry.empty() || printer_index < 0)
return true;
json assets = json::object();
for (const BedAssetSlot &slot : k_bed_asset_slots) {
if (!config.has(slot.option))
continue;
const std::string stored = config.opt_string(slot.option);
if (stored.empty())
continue;
if (!utf8_is_file(stored)) {
BOOST_LOG_TRIVIAL(warning) << "Bed asset file is missing, skipping " << slot.option << ": " << stored;
continue;
}
const std::string ext = bed_asset_extension(stored, slot.option);
if (ext.empty()) {
BOOST_LOG_TRIVIAL(warning) << "Bed asset extension is not packable, skipping " << slot.option << ": " << stored;
continue;
}
boost::nowide::ifstream in(stored, std::ios::binary);
if (!in) {
BOOST_LOG_TRIVIAL(warning) << "Bed asset file cannot be read, skipping " << slot.option << ": " << stored;
continue;
}
const std::string bytes((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
if (in.bad()) {
BOOST_LOG_TRIVIAL(warning) << "Bed asset file cannot be read, skipping " << slot.option << ": " << stored;
continue;
}
const std::string zip_name = std::string("bed/") + std::to_string(printer_index) + "/" + slot.stem + ext;
const void *data = bytes.empty() ? static_cast<const void *>("") : static_cast<const void *>(bytes.data());
if (mz_zip_writer_add_mem(&zip, zip_name.c_str(), data, bytes.size(), MZ_DEFAULT_COMPRESSION) == MZ_FALSE) {
BOOST_LOG_TRIVIAL(error) << "Failed to add bed asset to printer bundle: " << zip_name;
return false;
}
assets[slot.option] = zip_name;
}
if (!assets.empty())
bundle_structure["printer_asset"][printer_config_entry] = std::move(assets);
return true;
}
// Import presets from UI control
PresetsConfigSubstitutions PresetBundle::import_presets(std::vector<std::string> & files,
std::function<int(std::string const &)> override_confirm,
@@ -2028,44 +1773,14 @@ PresetsConfigSubstitutions PresetBundle::import_presets(std::vector<std::string>
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " No bundle_structure.json found, importing presets into the user preset directory";
}
json bundle_json = json::object();
std::unordered_set<std::string> bed_asset_entries;
std::vector<PendingBedAsset> bed_assets;
std::map<std::string, std::map<std::string, std::string>> bed_paths_by_printer;
bool bed_paths_loaded = false;
if (has_bundle_structure && !bundle_base_dir.empty()) {
try {
boost::nowide::ifstream manifest_in(metadata_path.string());
manifest_in >> bundle_json;
} catch (const std::exception &err) {
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << " failed to read bundle manifest: " << err.what();
bundle_json = json::object();
}
std::unordered_set<std::string> zip_entries;
const int zip_file_count = mz_zip_reader_get_num_files(&zip_archive);
for (int zi = 0; zi < zip_file_count; ++zi) {
mz_zip_archive_file_stat st;
if (mz_zip_reader_file_stat(&zip_archive, zi, &st))
zip_entries.insert(zip_slashes(st.m_filename));
}
bed_assets = pending_bed_assets(bundle_json, bundle_base_dir, bed_asset_entries, zip_entries);
for (PendingBedAsset &asset : bed_assets)
if (stage_bed_asset(zip_archive, asset, temp_folder))
bed_paths_by_printer[asset.printer_key].emplace(asset.option, asset.dest);
}
// Extract Files
int num_files = mz_zip_reader_get_num_files(&zip_archive);
const std::map<std::string, std::string> no_bed_paths;
for (int i = 0; i < num_files; i++) {
mz_zip_archive_file_stat file_stat;
status = mz_zip_reader_file_stat(&zip_archive, i, &file_stat);
if (status) {
std::string file_name = file_stat.m_filename;
const std::string zip_entry = zip_slashes(file_name);
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " From zip file: " << file << ". Read file name: " << file_stat.m_filename;
if (is_pending_bed_asset_entry(file_name, bed_asset_entries))
continue;
size_t index = file_name.find_last_of("/\\");
if (std::string::npos != index) {
file_name = file_name.substr(index + 1);
@@ -2083,26 +1798,13 @@ PresetsConfigSubstitutions PresetBundle::import_presets(std::vector<std::string>
if (MZ_FALSE == status) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Failed to open target file: " << target_file_path;
} else {
const auto paths_it = bed_paths_by_printer.find(zip_entry);
const std::map<std::string, std::string> &this_bed_paths =
paths_it != bed_paths_by_printer.end() ? paths_it->second : no_bed_paths;
bool is_success = import_json_presets(substitutions, target_file_path, override_confirm, rule, overwrite, result,
has_bundle_structure ? bundle_base_dir.string() : std::string(),
this_bed_paths, &bed_paths_loaded);
has_bundle_structure ? bundle_base_dir.string() : std::string());
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " import target file: " << target_file_path << " import result" << is_success;
}
}
}
// Copy into bed/ only after this import loads a printer that still holds the staged path.
// A preset left from an earlier import must not count: declining this import leaves its files alone.
if (bed_paths_loaded) {
for (const PendingBedAsset &asset : bed_assets) {
if (printer_kept_bed_paths(printers, {{asset.option, asset.dest}}))
install_bed_asset(asset);
}
}
// Set imported_time to current time if not already set
if (metadata.imported_time == 0) {
metadata.imported_time = std::time(nullptr);
@@ -2144,9 +1846,7 @@ bool PresetBundle::import_json_presets(PresetsConfigSubstitutions & s
ForwardCompatibilitySubstitutionRule rule,
int & overwrite,
std::vector<std::string> & result,
const std::string & bundle_dir,
const std::map<std::string, std::string> & bed_asset_paths,
bool * bed_paths_loaded)
const std::string & bundle_dir)
{
try {
DynamicPrintConfig config;
@@ -2210,10 +1910,6 @@ bool PresetBundle::import_json_presets(PresetsConfigSubstitutions & s
if (inherit_preset)
inherits_value = inherit_preset->name; // keep the base_id redo below in sync
}
if (collection == &printers) {
for (const auto &entry : bed_asset_paths)
config.option<ConfigOptionString>(entry.first, true)->value = entry.second;
}
if (inherit_preset) {
new_config = inherit_preset->config;
new_config.apply(std::move(config));
@@ -2231,8 +1927,6 @@ bool PresetBundle::import_json_presets(PresetsConfigSubstitutions & s
new_config.apply(std::move(config));
extend_default_config_length(new_config, true, default_preset.config);
}
if (bed_paths_loaded != nullptr && collection == &printers && !bed_asset_paths.empty())
*bed_paths_loaded = true;
Preset &preset = collection->load_preset(collection->path_from_name(name, inherit_preset == nullptr), preset_name, std::move(new_config), false);
preset.bundle_id = load_origin.bundle_id;
+1 -3
View File
@@ -319,9 +319,7 @@ public:
ForwardCompatibilitySubstitutionRule rule,
int& overwrite,
std::vector<std::string>& result,
const std::string& bundle_dir = "",
const std::map<std::string, std::string> &bed_asset_paths = {},
bool *bed_paths_loaded = nullptr);
const std::string& bundle_dir = "");
void save_user_presets(AppConfig& config, std::map<std::string, std::string>& need_to_delete_list);
void check_and_fix_user_presets_syncinfo(const std::string& user_id);
-2
View File
@@ -1148,8 +1148,6 @@ void PrintConfigDef::init_common_params()
def = this->add("print_host", coString);
def->label = L("Hostname, IP or URL");
// The URL is an example of the format to type, not a link, so it stays in the text.
// xgettext:no-url-check
def->tooltip = L("Orca Slicer can upload G-code files to a printer host. This field should contain "
"the hostname, IP address or URL of the printer host instance. "
"Print host behind HAProxy with basic auth enabled can be accessed by putting the user name and password into the URL "
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include "miniz_extension.hpp"
#include <miniz.h>
#include <nlohmann/json_fwd.hpp>
#include <string>
namespace Slic3r {
class DynamicPrintConfig;
// Not on PresetBundle.hpp: miniz.h's zlib-compat macros rename GUI methods (GLTexture::Compressor::compress).
// printer_config_entry is the zip name also pushed onto bundle_structure["printer_config"].
// printer_index is that entry's 0-based index in the exported printer_config list.
bool append_printer_bed_assets(mz_zip_archive &zip, const DynamicPrintConfig &config, nlohmann::json &bundle_structure,
const std::string &printer_config_entry, int printer_index);
} // namespace Slic3r
-2
View File
@@ -1,5 +1,3 @@
#pragma once
// paper: https://people.eecs.berkeley.edu/~jrs/meshpapers/GarlandHeckbert2.pdf
// sum up: https://users.csc.calpoly.edu/~zwood/teaching/csc570/final06/jseeba/
// inspiration: https://github.com/sp4cerat/Fast-Quadric-Mesh-Simplification
+2 -32
View File
@@ -65,7 +65,6 @@
#include <boost/nowide/cstdio.hpp>
#include <wx/valtext.h>
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/PrinterBedAssets.hpp"
#include "I18N.hpp"
#include "GUI_App.hpp"
#include "MsgDialog.hpp"
@@ -3675,20 +3674,9 @@ ExportConfigsDialog::~ExportConfigsDialog()
}
void ExportConfigsDialog::on_dpi_changed(const wxRect &suggested_rect) {
if (m_include_bed_assets)
m_include_bed_assets->Rescale();
Layout();
}
void ExportConfigsDialog::update_include_bed_assets_enabled()
{
const bool on = get_curr_radio_type(m_export_type_btns) == m_exprot_type.preset_bundle;
if (m_include_bed_assets)
m_include_bed_assets->Enable(on);
if (m_include_bed_assets_label)
m_include_bed_assets_label->Enable(on);
}
void ExportConfigsDialog::show_export_result(const ExportCase &export_case)
{
MessageDialog *msg_dlg = nullptr;
@@ -3831,17 +3819,6 @@ wxBoxSizer *ExportConfigsDialog::create_export_config_item(wxWindow *parent)
static_export_printer_preset_bundle_text->SetFont(Label::Body_12);
static_export_printer_preset_bundle_text->SetForegroundColour(wxColour("#6B6B6B"));
radioBoxSizer->Add(static_export_printer_preset_bundle_text, 0, wxEXPAND | wxLEFT, FromDIP(22));
wxBoxSizer *include_bed_sizer = new wxBoxSizer(wxHORIZONTAL);
m_include_bed_assets = new ::CheckBox(parent);
m_include_bed_assets->SetValue(true);
include_bed_sizer->Add(m_include_bed_assets, 0, wxALIGN_CENTER_VERTICAL, 0);
m_include_bed_assets_label = new wxStaticText(parent, wxID_ANY, _L("Include custom bed texture and model"));
m_include_bed_assets_label->SetFont(Label::Body_12);
m_include_bed_assets_label->SetForegroundColour(wxColour("#6B6B6B"));
include_bed_sizer->Add(m_include_bed_assets_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5));
radioBoxSizer->Add(0, 0, 0, wxTOP, FromDIP(6));
radioBoxSizer->Add(include_bed_sizer, 0, wxEXPAND | wxLEFT, FromDIP(22));
update_include_bed_assets_enabled();
radioBoxSizer->Add(create_radio_item(m_exprot_type.filament_bundle, parent, wxEmptyString, m_export_type_btns), 0, wxEXPAND | wxTOP, FromDIP(10));
wxStaticText *static_export_filament_preset_bundle_text = new wxStaticText(parent, wxID_ANY, _L("User's filament preset set.\nCan be shared with others."),
wxDefaultPosition, wxDefaultSize);
@@ -4011,10 +3988,9 @@ void ExportConfigsDialog::select_curr_radiobox(std::vector<std::pair<RadioBox *,
radiobox_list[i].first->SetValue(false);
}
}
update_include_bed_assets_enabled();
}
ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_preset_bundle_to_file(const wxString &path, bool include_bed_assets)
ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_preset_bundle_to_file(const wxString &path)
{
std::string export_path = initial_file_path(path, "");
if (export_path.empty() || "initial_failed" == export_path) return ExportCase::EXPORT_CANCEL;
@@ -4116,12 +4092,6 @@ ExportConfigsDialog::ExportCase ExportConfigsDialog::archive_preset_bundle_to_fi
bundle_structure["filament_config"] = filament_configs;
bundle_structure["process_config"] = process_configs;
if (include_bed_assets &&
!append_printer_bed_assets(zip_archive, printer_preset->config, bundle_structure, printer_config_file_name, 0)) {
mz_zip_writer_end(&zip_archive);
return ExportCase::ADD_FILE_FAIL;
}
std::string bundle_structure_str = bundle_structure.dump();
status = mz_zip_writer_add_mem(&zip_archive, BUNDLE_STRUCTURE_JSON_NAME, bundle_structure_str.data(), bundle_structure_str.size(), MZ_DEFAULT_COMPRESSION);
if (MZ_FALSE == status) {
@@ -4369,7 +4339,7 @@ wxWindow *ExportConfigsDialog::create_dialog_buttons(wxWindow* parent)
const wxString curr_radio_type = get_curr_radio_type(m_export_type_btns);
if (curr_radio_type == m_exprot_type.preset_bundle) {
export_case = archive_preset_bundle_to_file(path, m_include_bed_assets->GetValue());
export_case = archive_preset_bundle_to_file(path);
} else if (curr_radio_type == m_exprot_type.filament_bundle) {
export_case = archive_filament_bundle_to_file(path);
} else if (curr_radio_type == m_exprot_type.printer_preset) {
+1 -4
View File
@@ -271,7 +271,6 @@ protected:
private:
void data_init();
void select_curr_radiobox(std::vector<std::pair<RadioBox *, wxString>> &radiobox_list, int btn_idx);
void update_include_bed_assets_enabled();
void on_dpi_changed(const wxRect &suggested_rect) override;
void show_export_result(const ExportCase &export_case);
bool has_check_box_selected();
@@ -285,7 +284,7 @@ private:
int initial_zip_archive(mz_zip_archive &zip_archive, const std::string &file_path);
ExportCase save_zip_archive_to_file(mz_zip_archive &zip_archive);
ExportCase save_presets_to_zip(const std::string &export_file, const std::vector<std::pair<std::string, std::string>> &config_paths);
ExportCase archive_preset_bundle_to_file(const wxString &path, bool include_bed_assets);
ExportCase archive_preset_bundle_to_file(const wxString &path);
ExportCase archive_filament_bundle_to_file(const wxString &path);
ExportCase archive_printer_preset_to_file(const wxString &path);
ExportCase archive_filament_preset_to_file(const wxString &path);
@@ -305,8 +304,6 @@ private:
wxGridSizer * m_preset_sizer = nullptr;
wxPanel * m_presets_window = nullptr;
wxStaticText * m_serial_text = nullptr;
::CheckBox * m_include_bed_assets = nullptr;
wxStaticText * m_include_bed_assets_label = nullptr;
};
class CreatePresetForPrinterDialog : public DPIDialog
+2 -15
View File
@@ -379,24 +379,14 @@ void FilamentGroupPopup::OnTimer(wxTimerEvent &event)
// leaving event got triggered. So the timer is stopped first, then started
// again, causing the popup being dismissed immediately.
// To fix this, we check if cursor is still inside the popup window before
// dismissing, and keep checking while it is: a leave event is not guaranteed
// to follow, and a popup left open keeps grabbing the mouse capture.
// dismissing.
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
if (this->GetClientRect().Contains(pos)) {
StartTimer();
return;
}
if (this->GetClientRect().Contains(pos)) return;
#endif
Dismiss();
}
FilamentGroupPopup::~FilamentGroupPopup()
{
m_timer->Stop();
delete m_timer;
}
void FilamentGroupPopup::Dismiss() {
m_active = false;
PopupWindow::Dismiss();
@@ -415,10 +405,7 @@ void FilamentGroupPopup::OnEnterWindow(wxMouseEvent &)
// Ignore spurious ENTER synthesized by PopupWindow::OnMouseEvent2 on macOS.
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
if (!this->GetClientRect().Contains(pos)) return;
// On macOS the timer keeps running instead, and OnTimer closes the popup once the cursor has left it.
#ifndef __APPLE__
ResetTimer();
#endif
}
void FilamentGroupPopup::UpdateButtonStatus(int hover_idx)
-1
View File
@@ -27,7 +27,6 @@ class FilamentGroupPopup : public PopupWindow
{
public:
FilamentGroupPopup(wxWindow *parent);
~FilamentGroupPopup() override;
void tryPopup(Plater* plater,PartPlate* plate, bool slice_all);
void tryClose();
void Dismiss() override;
-9
View File
@@ -20,8 +20,6 @@
#include <wx/gdicmn.h>
#include <wx/dialog.h>
#include "slic3r/GUI/FilamentMapPanel.hpp"
#include "slic3r/GUI/FilamentGroupPopup.hpp"
#include "slic3r/GUI/MainFrame.hpp"
namespace Slic3r { namespace GUI {
@@ -379,13 +377,6 @@ FilamentMapMode FilamentMapDialog::get_mode()
int FilamentMapDialog::ShowModal()
{
// The Slice-plate hover popup is a transient popup that keeps grabbing the mouse
// capture while shown. Left behind this modal dialog it would starve the dialog of
// mouse events, so close it synchronously first, whichever path opened the dialog.
if (MainFrame* frame = wxGetApp().mainframe;
frame && frame->m_filament_group_popup && frame->m_filament_group_popup->IsShown())
frame->m_filament_group_popup->Dismiss();
update_panel_status(m_page_type);
return wxDialog::ShowModal();
}
+3 -4
View File
@@ -2654,10 +2654,9 @@ void GUI_App::init_webview_runtime()
BOOST_LOG_TRIVIAL(info) << "WebView2 runtime installed successfully.";
} else {
BOOST_LOG_TRIVIAL(error) << "WebView2 runtime installation failed or still not detected.";
wxMessageBox(format_wxstr(_L("The Microsoft WebView2 Runtime could not be installed.\n"
"Some features, including the setup wizard, may appear blank until it is installed.\n"
"Please install it manually from %1% and restart Orca Slicer."),
"https://developer.microsoft.com/microsoft-edge/webview2/"),
wxMessageBox(_L("The Microsoft WebView2 Runtime could not be installed.\n"
"Some features, including the setup wizard, may appear blank until it is installed.\n"
"Please install it manually from https://developer.microsoft.com/microsoft-edge/webview2/ and restart Orca Slicer."),
_L("WebView2 Runtime"), wxOK | wxICON_WARNING);
}
}
-2
View File
@@ -1,5 +1,3 @@
#pragma once
#import <Cocoa/Cocoa.h>
@interface OtherInstanceMessageHandlerMac : NSObject
+6
View File
@@ -2309,6 +2309,12 @@ wxBoxSizer* MainFrame::create_side_tools()
bool slice = true;
// The Slice-plate hover popup is a transient popup that keeps grabbing
// the mouse capture while shown. Left behind the modal grouping dialog it
// would starve that dialog of mouse events, so close it synchronously first.
if (m_filament_group_popup)
m_filament_group_popup->Dismiss();
auto curr_plate = m_plater->get_partplate_list().get_curr_plate();
#ifdef __linux__
PresetBundle* preset = wxGetApp().preset_bundle;
-2
View File
@@ -1,5 +1,3 @@
#pragma once
#include "slic3r/GUI/wxExtensions.hpp"
#include <map>
#include <cstdint>
+2 -2
View File
@@ -12820,8 +12820,8 @@ void Plater::priv::on_select_bed_type(wxCommandEvent &evt)
// update plater with new config
q->on_config_change(wxGetApp().preset_bundle->full_config());
// Rebuild the plate tab from the current selection; its cached plates may be gone after a reset.
wxGetApp().obj_list()->update_and_show_object_settings_item();
if (auto *plate_tab = dynamic_cast<TabPrintPlate *>(wxGetApp().get_plate_tab()))
plate_tab->update_model_config();
// update app_config
AppConfig* app_config = wxGetApp().app_config;
-2
View File
@@ -1,5 +1,3 @@
#pragma once
#import <Cocoa/Cocoa.h>
@interface RemovableDriveManagerMM : NSObject
+1 -1
View File
@@ -5957,7 +5957,7 @@ if (is_marlin_flavor)
{
// In the configuration group rather than a group of its own: a full-width widget line
// records no mode, so a group holding only this line would show in every mode.
auto line = Line{ L("Modes"), "" };
auto line = Line{ L("Modes"), L("") };
line.full_width = 1;
line.widget = [this](wxWindow* parent) -> wxSizer* {
int n_cols = 0, n_rows = 0, layout = 0;
-15
View File
@@ -13,10 +13,6 @@
#include <wx/gdicmn.h>
#include <wx/webview.h>
#ifdef __WXGTK__
#include <gtk/gtk.h>
#endif
namespace Slic3r { namespace GUI {
WebDialog::WebDialog(wxWindow* parent,
@@ -56,17 +52,6 @@ WebDialog::WebDialog(wxWindow* parent,
Bind(wxEVT_CLOSE_WINDOW, &WebDialog::on_close_window, this);
}
void WebDialog::use_normal_window_type()
{
#ifdef __WXGTK__
// wxGTK types every wxDialog as a dialog, and Mutter offers no maximize for anything but a
// normal window. Mutter also stops hiding a normal window from the taskbar, so keep it hidden
// as a dialog with a parent is everywhere else.
gtk_window_set_type_hint(GTK_WINDOW(m_widget), GDK_WINDOW_TYPE_HINT_NORMAL);
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(m_widget), TRUE);
#endif
}
void WebDialog::add_user_scripts()
{
if (wxWebView* wv = browser()) {
-4
View File
@@ -62,10 +62,6 @@ public:
bool is_open() const { return m_open; }
// Lets a modeless window be maximized on X11; call before Show(). Modal ones stay dialogs so the
// window manager keeps routing focus from the parent to them.
void use_normal_window_type();
// The payload submitted via window.orca.submit() (modal use), if any.
const std::optional<nlohmann::json>& result() const { return m_result; }
-2
View File
@@ -1,5 +1,3 @@
#pragma once
#include <wx/textctrl.h>
#include <wx/colour.h>
-1
View File
@@ -197,7 +197,6 @@ bool CloudPluginService::download_cloud_plugin(PluginDescriptor& entry,
Http http = Http::get(download_url);
http.timeout_connect(30)
.timeout_max(300)
.tls_verify(true)
.on_complete([&body, &http_status](std::string response_body, unsigned status) {
body = std::move(response_body);
http_status = status;
-1
View File
@@ -399,7 +399,6 @@ py::object ui_create_window(const std::string& html, const std::string& title, i
if (UiRegistry::instance().is_open(new_id))
dlg->Destroy();
} else {
dlg->use_normal_window_type();
dlg->Show();
}
});
@@ -6,8 +6,6 @@
#include <algorithm>
#include <boost/filesystem.hpp>
#include <boost/nowide/convert.hpp>
#include <boost/nowide/fstream.hpp>
#include <cstddef>
#include <fstream>
@@ -24,7 +22,6 @@
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/miniz_extension.hpp"
#include "libslic3r/PrinterBedAssets.hpp"
#include "test_utils.hpp"
@@ -5856,609 +5853,6 @@ TEST_CASE("Config import confines zip entries, preset names and bundle ids to th
}
}
namespace {
const std::string kTextureBytes("\x89PNG\x00tex", 8);
const std::string kModelBytes("stl\x00model", 9);
const std::string kOtherBytes("\x89PNG\x00other", 10);
void write_bytes(const std::string &utf8_path, const std::string &bytes)
{
const auto slash = utf8_path.find_last_of("/\\");
if (slash != std::string::npos) {
#ifdef _WIN32
fs::create_directories(fs::path(boost::nowide::widen(utf8_path.substr(0, slash))));
#else
fs::create_directories(utf8_path.substr(0, slash));
#endif
}
boost::nowide::ofstream out(utf8_path, std::ios::binary | std::ios::trunc);
REQUIRE(out);
out.write(bytes.data(), static_cast<std::streamsize>(bytes.size()));
REQUIRE(out);
}
fs::path write_printer_json(const DynamicPrintConfig &defaults, const fs::path &file, const std::string &name,
const std::string &texture, const std::string &model, const std::string &inherits = {})
{
DynamicPrintConfig config(defaults);
config.option<ConfigOptionString>("printer_settings_id", true)->value = name;
config.option<ConfigOptionString>("inherits", true)->value = inherits;
if (texture.empty())
config.erase("bed_custom_texture");
else
config.option<ConfigOptionString>("bed_custom_texture", true)->value = texture;
if (model.empty())
config.erase("bed_custom_model");
else
config.option<ConfigOptionString>("bed_custom_model", true)->value = model;
fs::create_directories(file.parent_path());
config.save_to_json(file.string(), name, "User", "1.0.0");
return file;
}
nlohmann::json bed_manifest(const std::string &bundle_id)
{
nlohmann::json structure = nlohmann::json::object();
structure["id"] = bundle_id;
structure["bundle_type"] = "printer config bundle";
structure["printer_config"] = nlohmann::json::array({"printer/BedPrinter.json"});
return structure;
}
void set_printer_bed_asset(nlohmann::json &structure, const std::string &option, const std::string &zip_name,
const std::string &printer_entry = "printer/BedPrinter.json")
{
structure["printer_asset"][printer_entry][option] = zip_name;
}
nlohmann::json pack_bed_zip(const fs::path &zip_file, const fs::path &printer_json, const DynamicPrintConfig &defaults,
const std::string &texture, const std::string &model, const std::string &bundle_id,
bool include_bed_assets = true)
{
DynamicPrintConfig config(defaults);
if (!texture.empty())
config.option<ConfigOptionString>("bed_custom_texture", true)->value = texture;
if (!model.empty())
config.option<ConfigOptionString>("bed_custom_model", true)->value = model;
nlohmann::json structure = bed_manifest(bundle_id);
mz_zip_archive zip;
mz_zip_zero_struct(&zip);
const std::string printer_bytes = read_file(printer_json);
REQUIRE(open_zip_writer(&zip, zip_file.string()));
REQUIRE(mz_zip_writer_add_mem(&zip, "printer/BedPrinter.json", printer_bytes.data(), printer_bytes.size(),
MZ_DEFAULT_COMPRESSION));
if (include_bed_assets)
REQUIRE(append_printer_bed_assets(zip, config, structure, "printer/BedPrinter.json", 0));
const std::string manifest = structure.dump();
REQUIRE(mz_zip_writer_add_mem(&zip, BUNDLE_STRUCTURE_JSON_NAME, manifest.data(), manifest.size(),
MZ_DEFAULT_COMPRESSION));
REQUIRE(mz_zip_writer_finalize_archive(&zip));
REQUIRE(close_zip_writer(&zip));
return structure;
}
std::vector<std::string> zip_entry_names(const fs::path &zip_file)
{
mz_zip_archive zip;
mz_zip_zero_struct(&zip);
REQUIRE(open_zip_reader(&zip, zip_file.string()));
std::vector<std::string> names;
const int n = static_cast<int>(mz_zip_reader_get_num_files(&zip));
for (int i = 0; i < n; ++i) {
mz_zip_archive_file_stat st;
REQUIRE(mz_zip_reader_file_stat(&zip, i, &st));
names.emplace_back(st.m_filename);
}
REQUIRE(close_zip_reader(&zip));
return names;
}
const Preset *import_named_printer(PresetBundle &bundle, const fs::path &zip_file, const fs::path &data_root,
const std::string &bare_name, int confirm = 1)
{
ScopedDataDir scoped(data_root);
AppConfig config;
std::vector<std::string> files{zip_file.string()};
bundle.import_presets(files, [confirm](std::string const &) { return confirm; },
ForwardCompatibilitySubstitutionRule::Disable, config);
for (const Preset &preset : bundle.printers.get_presets())
if (get_preset_bare_name(preset.name) == bare_name && !preset.file.empty())
return &preset;
return nullptr;
}
const Preset *import_bed(PresetBundle &bundle, const fs::path &zip_file, const fs::path &data_root, int confirm = 1)
{
return import_named_printer(bundle, zip_file, data_root, "BedPrinter", confirm);
}
struct BedRoots {
ScopedTemporaryDir temp_dir;
fs::path src;
fs::path data_root;
PresetBundle bundle;
BedRoots()
: src(temp_dir.path() / "src")
, data_root(temp_dir.path() / "datadir")
{}
};
} // namespace
TEST_CASE("Printer bundle round trip packs bed texture and model and rewrites both keys", "[Preset][Bundle]")
{
// tex_rel "*" builds a non-ASCII source path under the temp directory.
const auto pack_import = [](const std::string &bundle_id, const std::string &tex_rel, const std::string &mod_rel,
const std::string &tex_bytes, const std::string &mod_bytes, bool tex_exists,
bool mod_exists, int imports) {
ScopedTemporaryDir temp_dir;
const fs::path src = temp_dir.path() / "src";
const fs::path data_root = temp_dir.path() / "datadir";
std::string texture = tex_rel.empty() ? std::string() : (src / tex_rel).make_preferred().string();
std::string model = mod_rel.empty() ? std::string() : (src / mod_rel).make_preferred().string();
if (tex_rel == "*") {
const fs::path dir = fs::path(src.wstring()) / fs::path(boost::nowide::widen("\xE5\xBA\x8A"));
texture = boost::nowide::narrow((dir / fs::path(boost::nowide::widen("\xE7\xBA\xB9\xE7\x90\x86.png"))).wstring());
}
if (tex_exists)
write_bytes(texture, tex_bytes);
if (mod_exists)
write_bytes(model, mod_bytes);
PresetBundle bundle;
const fs::path printer_json = write_printer_json(bundle.printers.default_preset().config, src / "BedPrinter.json",
"BedPrinter", texture, model);
const fs::path zip_file = src / "bundle.orca_printer";
const nlohmann::json structure = pack_bed_zip(zip_file, printer_json, bundle.printers.default_preset().config,
texture, model, bundle_id);
const Preset *saved = nullptr;
for (int i = 0; i < imports; ++i)
saved = import_bed(bundle, zip_file, data_root);
REQUIRE(saved != nullptr);
const std::string got[] = {saved->config.opt_string("bed_custom_texture"), saved->config.opt_string("bed_custom_model")};
const std::string rel[] = {tex_rel, mod_rel};
const std::string bytes[] = {tex_bytes, mod_bytes};
const std::string path[] = {texture, model};
const bool exists[] = {tex_exists, mod_exists};
const char *option[] = {"bed_custom_texture", "bed_custom_model"};
const char *stem[] = {"texture", "model"};
for (int slot = 0; slot < 2; ++slot) {
if (exists[slot]) {
const std::string ext = fs::path(rel[slot] == "*" ? "x.png" : rel[slot]).extension().string();
const std::string zip_name = std::string("bed/0/") + stem[slot] + ext;
REQUIRE(structure["printer_asset"]["printer/BedPrinter.json"][option[slot]] == zip_name);
REQUIRE(fs::path(got[slot]).filename().string() == std::string(stem[slot]) + fs::path(zip_name).extension().string());
REQUIRE(fs::path(got[slot]).parent_path().filename() == "0");
REQUIRE(fs::path(got[slot]).parent_path().parent_path().filename() == "bed");
REQUIRE(got[slot].find(bundle_id) != std::string::npos);
REQUIRE(read_file(got[slot]) == bytes[slot]);
REQUIRE(got[slot] != path[slot]);
} else if (!rel[slot].empty() && rel[slot] != "*") {
REQUIRE_FALSE(structure.value("printer_asset", nlohmann::json::object())
.value("printer/BedPrinter.json", nlohmann::json::object())
.contains(option[slot]));
REQUIRE(got[slot] == path[slot]);
} else if (rel[slot].empty()) {
REQUIRE(got[slot].empty());
}
}
if (imports > 1) {
int copies = 0;
for (fs::recursive_directory_iterator it(data_root), end; it != end; ++it)
if (it->path().filename() == "texture.png" || it->path().filename() == "model.stl")
++copies;
REQUIRE(copies == (tex_exists ? 1 : 0) + (mod_exists ? 1 : 0));
}
};
SECTION("both assets are packed from the preset config and rewritten on import") {
pack_import("bed-roundtrip", "fixture/baseline_bed_texture.png", "fixture/baseline_bed_model.stl",
kTextureBytes, kModelBytes, true, true, 1);
}
SECTION("texture only") {
pack_import("texture-only", "only.png", "", kTextureBytes, "", true, false, 1);
}
SECTION("model only") {
pack_import("model-only", "", "only.stl", "", kModelBytes, false, true, 1);
}
SECTION("texture and model share a source basename") {
pack_import("shared-basename", "a/plate.png", "b/plate.stl", kTextureBytes, kOtherBytes, true, true, 1);
}
SECTION("importing the same bundle twice keeps one copy of the assets") {
// First import installs kTextureBytes / kModelBytes. The second pack uses different bytes so
// the Yes-overwrite path (copy_file overwrite_existing) is actually proven.
BedRoots bed;
const std::string texture = (bed.src / "twice.png").make_preferred().string();
const std::string model = (bed.src / "twice.stl").make_preferred().string();
write_bytes(texture, kTextureBytes);
write_bytes(model, kModelBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config,
bed.src / "BedPrinter.json", "BedPrinter", texture, model);
const fs::path zip_file = bed.src / "bundle.orca_printer";
pack_bed_zip(zip_file, printer_json, bed.bundle.printers.default_preset().config, texture, model, "reimport");
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
const std::string got_tex = saved->config.opt_string("bed_custom_texture");
const std::string got_mod = saved->config.opt_string("bed_custom_model");
REQUIRE(read_file(got_tex) == kTextureBytes);
REQUIRE(read_file(got_mod) == kModelBytes);
write_bytes(texture, kOtherBytes);
write_bytes(model, std::string("stl\x00other", 9));
pack_bed_zip(zip_file, printer_json, bed.bundle.printers.default_preset().config, texture, model, "reimport");
saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == got_tex);
REQUIRE(saved->config.opt_string("bed_custom_model") == got_mod);
REQUIRE(read_file(got_tex) == kOtherBytes);
REQUIRE(read_file(got_mod) == std::string("stl\x00other", 9));
}
SECTION("a non-ASCII source path is packed") {
pack_import("non-ascii", "*", "", kTextureBytes, "", true, false, 1);
}
}
TEST_CASE("An old printer bundle without printer_asset imports unchanged", "[Preset][Bundle]")
{
BedRoots bed;
const std::string texture = (bed.src / "old.png").make_preferred().string();
const std::string model = (bed.src / "old.stl").make_preferred().string();
write_bytes(texture, kTextureBytes);
write_bytes(model, kModelBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", texture, model);
nlohmann::json structure = bed_manifest("old-bundle");
REQUIRE_FALSE(structure.contains("printer_asset"));
const fs::path zip_file = bed.src / "old.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()}});
// A bed/ folder left by an earlier import into the same bundle folder must survive an asset-less import.
const fs::path old_bed = bed.data_root / "user" / "default" / "_local" / "old-bundle" / "bed";
write_bytes((old_bed / "texture.png").string(), kTextureBytes);
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == texture);
REQUIRE(saved->config.opt_string("bed_custom_model") == model);
CHECK(fs::exists(old_bed / "texture.png"));
}
TEST_CASE("Printer bundle asset names that escape the bundle directory are rejected", "[Preset][Bundle]")
{
const char *bad_names[] = {"../../pwned.png", "bed/../../pwned.png", "..\\..\\pwned.png", "C:/Windows/pwned.png",
"machine/texture.png", "/bed/texture.png"};
const std::string marker = "PWNED-BED-ASSET-MARKER";
for (const char *name : bad_names) {
DYNAMIC_SECTION("rejects " << name) {
BedRoots bed;
const std::string texture = (bed.src / "kept.png").make_preferred().string();
const std::string model = (bed.src / "kept.stl").make_preferred().string();
write_bytes(texture, kTextureBytes);
write_bytes(model, kModelBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config,
bed.src / "BedPrinter.json", "BedPrinter", texture, model);
nlohmann::json structure = bed_manifest("traverse");
set_printer_bed_asset(structure, "bed_custom_texture", name);
std::vector<std::pair<std::string, std::string>> entries = {
{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()}};
if (name[0] != '/' && name[0] != '\\')
entries.emplace_back(name, marker);
const fs::path zip_file = bed.src / "bad.orca_printer";
write_zip(zip_file, entries);
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == texture);
REQUIRE(saved->config.opt_string("bed_custom_model") == model);
CHECK_FALSE(any_filename_contains(bed.data_root, fs::path(name).filename().string()));
if (fs::exists(bed.data_root))
for (fs::recursive_directory_iterator it(bed.data_root), end; it != end; ++it)
if (fs::is_regular_file(*it))
CHECK(read_file(*it).find(marker) == std::string::npos);
}
}
}
TEST_CASE("A printer bundle asset that is missing is skipped", "[Preset][Bundle]")
{
SECTION("a manifest entry with no zip bytes leaves the original path") {
BedRoots bed;
const std::string texture = (bed.src / "gone.png").make_preferred().string();
write_bytes(texture, kTextureBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", texture, {});
nlohmann::json structure = bed_manifest("missing-zip");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/texture.png");
const fs::path zip_file = bed.src / "missing.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()}});
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == texture);
CHECK_FALSE(any_filename_contains(bed.data_root, "texture.png"));
}
SECTION("a missing file at export is omitted and the export still succeeds") {
BedRoots bed;
const std::string missing = (bed.src / "missing.png").make_preferred().string();
const std::string model = (bed.src / "present.stl").make_preferred().string();
write_bytes(model, kModelBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", missing, model);
const fs::path zip_file = bed.src / "partial.orca_printer";
const nlohmann::json structure = pack_bed_zip(zip_file, printer_json, bed.bundle.printers.default_preset().config,
missing, model, "missing-export");
REQUIRE_FALSE(structure["printer_asset"]["printer/BedPrinter.json"].contains("bed_custom_texture"));
REQUIRE(structure["printer_asset"]["printer/BedPrinter.json"]["bed_custom_model"] == "bed/0/model.stl");
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == missing);
REQUIRE(read_file(saved->config.opt_string("bed_custom_model")) == kModelBytes);
REQUIRE(fs::path(saved->config.opt_string("bed_custom_model")).filename() == "model.stl");
CHECK_FALSE(any_filename_contains(bed.data_root, "texture.png"));
}
}
TEST_CASE("An inherited printer bundle rewrites bed paths taken from the parent", "[Preset][Bundle]")
{
BedRoots bed;
const std::string texture = (bed.src / "parent.png").make_preferred().string();
const std::string model = (bed.src / "parent.stl").make_preferred().string();
write_bytes(texture, kTextureBytes);
write_bytes(model, kModelBytes);
DynamicPrintConfig parent(bed.bundle.printers.default_preset().config);
parent.option<ConfigOptionString>("printer_settings_id", true)->value = "ParentPrinter";
parent.option<ConfigOptionString>("inherits", true)->value.clear();
parent.option<ConfigOptionString>("bed_custom_texture", true)->value = texture;
parent.option<ConfigOptionString>("bed_custom_model", true)->value = model;
bed.bundle.printers.load_preset((bed.src / "ParentPrinter.json").string(), "ParentPrinter", std::move(parent), false);
const fs::path child_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", {}, {}, "ParentPrinter");
const nlohmann::json written = nlohmann::json::parse(read_file(child_json));
REQUIRE_FALSE(written.contains("bed_custom_texture"));
REQUIRE_FALSE(written.contains("bed_custom_model"));
nlohmann::json structure = bed_manifest("inherit-bed");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/texture.png");
set_printer_bed_asset(structure, "bed_custom_model", "bed/0/model.stl");
const fs::path zip_file = bed.src / "inherit.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(child_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()},
{"bed/0/texture.png", kTextureBytes}, {"bed/0/model.stl", kModelBytes}});
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") != texture);
REQUIRE(saved->config.opt_string("bed_custom_model") != model);
REQUIRE(read_file(saved->config.opt_string("bed_custom_texture")) == kTextureBytes);
REQUIRE(read_file(saved->config.opt_string("bed_custom_model")) == kModelBytes);
REQUIRE(fs::path(saved->config.opt_string("bed_custom_texture")).filename() == "texture.png");
REQUIRE(fs::path(saved->config.opt_string("bed_custom_model")).filename() == "model.stl");
}
TEST_CASE("A printer bundle rejects bed assets whose extension the bed dialog does not allow", "[Preset][Bundle]")
{
BedRoots bed;
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", {}, {});
nlohmann::json structure = bed_manifest("bad-ext");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/texture.stl");
set_printer_bed_asset(structure, "bed_custom_model", "bed/0/model.exe");
const fs::path zip_file = bed.src / "bad-ext.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()},
{"bed/0/texture.stl", kTextureBytes}, {"bed/0/model.exe", std::string("MZ")}});
REQUIRE(import_bed(bed.bundle, zip_file, bed.data_root) != nullptr);
CHECK_FALSE(any_filename_contains(bed.data_root, "model.exe"));
CHECK_FALSE(any_filename_contains(bed.data_root, "texture.stl"));
}
TEST_CASE("A manifest asset name that points at a preset does not drop that preset", "[Preset][Bundle]")
{
BedRoots bed;
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", {}, {});
nlohmann::json structure = bed_manifest("name-clash");
set_printer_bed_asset(structure, "bed_custom_texture", "printer/BedPrinter.json");
const fs::path zip_file = bed.src / "clash.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()}});
REQUIRE(import_bed(bed.bundle, zip_file, bed.data_root) != nullptr);
CHECK_FALSE(any_filename_contains(bed.data_root, "texture.png"));
}
TEST_CASE("A declined printer bundle import leaves existing bed files alone", "[Preset][Bundle]")
{
BedRoots bed;
const fs::path kept = bed.data_root / "user" / "default" / "_local" / "keep-bed" / "bed" / "texture.png";
const std::string original("kept-texture");
write_bytes(kept.string(), original);
DynamicPrintConfig existing(bed.bundle.printers.default_preset().config);
existing.option<ConfigOptionString>("printer_settings_id", true)->value = "BedPrinter";
existing.option<ConfigOptionString>("inherits", true)->value.clear();
bed.bundle.printers.load_preset((bed.src / "existing.json").string(), "_local/keep-bed/BedPrinter", std::move(existing),
false);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", {}, {});
nlohmann::json structure = bed_manifest("keep-bed");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/texture.png");
set_printer_bed_asset(structure, "bed_custom_model", "bed/0/model.stl");
const fs::path zip_file = bed.src / "keep.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()},
{"bed/0/texture.png", kTextureBytes}, {"bed/0/model.stl", kModelBytes}});
import_bed(bed.bundle, zip_file, bed.data_root, 0);
// This import wrote nothing: the existing texture is unchanged and model.stl was not added.
REQUIRE(fs::exists(kept));
REQUIRE(read_file(kept) == original);
CHECK_FALSE(fs::exists(kept.parent_path() / "model.stl"));
CHECK_FALSE(fs::exists(kept.parent_path() / "0" / "model.stl"));
}
TEST_CASE("A declined re-import does not replace bed bytes an earlier import wrote", "[Preset][Bundle]")
{
BedRoots bed;
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", {}, {});
nlohmann::json structure = bed_manifest("reimport-no");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/texture.png");
const std::string manifest = structure.dump();
const std::string printer_bytes = read_file(printer_json);
const fs::path first_zip = bed.src / "first.orca_printer";
const fs::path second_zip = bed.src / "second.orca_printer";
write_zip(first_zip, {{"printer/BedPrinter.json", printer_bytes}, {BUNDLE_STRUCTURE_JSON_NAME, manifest},
{"bed/0/texture.png", kTextureBytes}});
write_zip(second_zip, {{"printer/BedPrinter.json", printer_bytes}, {BUNDLE_STRUCTURE_JSON_NAME, manifest},
{"bed/0/texture.png", kOtherBytes}});
const Preset *saved = import_bed(bed.bundle, first_zip, bed.data_root);
REQUIRE(saved != nullptr);
const std::string installed = saved->config.opt_string("bed_custom_texture");
REQUIRE(read_file(installed) == kTextureBytes);
import_bed(bed.bundle, second_zip, bed.data_root, 0);
REQUIRE(fs::exists(installed));
REQUIRE(read_file(installed) == kTextureBytes);
}
TEST_CASE("Export with bed assets disabled packs no bed files and writes no printer_asset", "[Preset][Bundle]")
{
BedRoots bed;
const std::string texture = (bed.src / "off.png").make_preferred().string();
const std::string model = (bed.src / "off.stl").make_preferred().string();
write_bytes(texture, kTextureBytes);
write_bytes(model, kModelBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", texture, model);
const fs::path zip_file = bed.src / "off.orca_printer";
const nlohmann::json structure = pack_bed_zip(zip_file, printer_json, bed.bundle.printers.default_preset().config,
texture, model, "bed-off", false);
REQUIRE_FALSE(structure.contains("printer_asset"));
for (const std::string &name : zip_entry_names(zip_file))
REQUIRE(name.compare(0, 4, "bed/") != 0);
}
TEST_CASE("Two printers in one bundle keep separate bed folders", "[Preset][Bundle]")
{
BedRoots bed;
const std::string tex_a = (bed.src / "a.png").make_preferred().string();
const std::string mod_a = (bed.src / "a.stl").make_preferred().string();
const std::string tex_b = (bed.src / "b.png").make_preferred().string();
const std::string mod_b = (bed.src / "b.stl").make_preferred().string();
write_bytes(tex_a, kTextureBytes);
write_bytes(mod_a, kModelBytes);
write_bytes(tex_b, kOtherBytes);
write_bytes(mod_b, std::string("stl\x00other", 9));
const fs::path json_a = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "PrinterA.json",
"PrinterA", tex_a, mod_a);
const fs::path json_b = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "PrinterB.json",
"PrinterB", tex_b, mod_b);
nlohmann::json structure = nlohmann::json::object();
structure["id"] = "two-printers";
structure["bundle_type"] = "printer config bundle";
structure["printer_config"] = nlohmann::json::array({"printer/PrinterA.json", "printer/PrinterB.json"});
DynamicPrintConfig config_a(bed.bundle.printers.default_preset().config);
config_a.option<ConfigOptionString>("bed_custom_texture", true)->value = tex_a;
config_a.option<ConfigOptionString>("bed_custom_model", true)->value = mod_a;
DynamicPrintConfig config_b(bed.bundle.printers.default_preset().config);
config_b.option<ConfigOptionString>("bed_custom_texture", true)->value = tex_b;
config_b.option<ConfigOptionString>("bed_custom_model", true)->value = mod_b;
const fs::path zip_file = bed.src / "two.orca_printer";
mz_zip_archive zip;
mz_zip_zero_struct(&zip);
const std::string bytes_a = read_file(json_a);
const std::string bytes_b = read_file(json_b);
REQUIRE(open_zip_writer(&zip, zip_file.string()));
REQUIRE(mz_zip_writer_add_mem(&zip, "printer/PrinterA.json", bytes_a.data(), bytes_a.size(), MZ_DEFAULT_COMPRESSION));
REQUIRE(mz_zip_writer_add_mem(&zip, "printer/PrinterB.json", bytes_b.data(), bytes_b.size(), MZ_DEFAULT_COMPRESSION));
REQUIRE(append_printer_bed_assets(zip, config_a, structure, "printer/PrinterA.json", 0));
REQUIRE(append_printer_bed_assets(zip, config_b, structure, "printer/PrinterB.json", 1));
const std::string manifest = structure.dump();
REQUIRE(mz_zip_writer_add_mem(&zip, BUNDLE_STRUCTURE_JSON_NAME, manifest.data(), manifest.size(),
MZ_DEFAULT_COMPRESSION));
REQUIRE(mz_zip_writer_finalize_archive(&zip));
REQUIRE(close_zip_writer(&zip));
REQUIRE(structure["printer_asset"]["printer/PrinterA.json"]["bed_custom_texture"] == "bed/0/texture.png");
REQUIRE(structure["printer_asset"]["printer/PrinterB.json"]["bed_custom_texture"] == "bed/1/texture.png");
ScopedDataDir scoped(bed.data_root);
AppConfig app_config;
std::vector<std::string> files{zip_file.string()};
bed.bundle.import_presets(files, [](std::string const &) { return 1; },
ForwardCompatibilitySubstitutionRule::Disable, app_config);
const Preset *saved_a = nullptr;
const Preset *saved_b = nullptr;
for (const Preset &preset : bed.bundle.printers.get_presets()) {
if (preset.file.empty())
continue;
if (get_preset_bare_name(preset.name) == "PrinterA")
saved_a = &preset;
if (get_preset_bare_name(preset.name) == "PrinterB")
saved_b = &preset;
}
REQUIRE(saved_a != nullptr);
REQUIRE(saved_b != nullptr);
const std::string got_tex_a = saved_a->config.opt_string("bed_custom_texture");
const std::string got_tex_b = saved_b->config.opt_string("bed_custom_texture");
REQUIRE(fs::path(got_tex_a).parent_path().filename() == "0");
REQUIRE(fs::path(got_tex_b).parent_path().filename() == "1");
REQUIRE(got_tex_a != got_tex_b);
REQUIRE(read_file(got_tex_a) == kTextureBytes);
REQUIRE(read_file(got_tex_b) == kOtherBytes);
REQUIRE(read_file(saved_a->config.opt_string("bed_custom_model")) == kModelBytes);
REQUIRE(read_file(saved_b->config.opt_string("bed_custom_model")) == std::string("stl\x00other", 9));
}
TEST_CASE("A printer_asset entry keyed to a printer not in the zip is ignored", "[Preset][Bundle]")
{
BedRoots bed;
const std::string texture = (bed.src / "kept.png").make_preferred().string();
write_bytes(texture, kTextureBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", texture, {});
nlohmann::json structure = bed_manifest("ghost-key");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/texture.png", "printer/Ghost.json");
const fs::path zip_file = bed.src / "ghost.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()},
{"bed/0/texture.png", kOtherBytes}});
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == texture);
CHECK_FALSE(any_filename_contains(bed.data_root, "texture.png"));
}
TEST_CASE("Keyed printer_asset rejects malformed bed paths", "[Preset][Bundle]")
{
const char *bad_names[] = {"bed/texture.png", "bed/x/texture.png", "bed/0/../texture.png", "bed/0/model.png"};
const std::string marker = "PWNED-BED-ASSET-MARKER";
for (const char *name : bad_names) {
DYNAMIC_SECTION("rejects " << name) {
BedRoots bed;
const std::string texture = (bed.src / "kept.png").make_preferred().string();
write_bytes(texture, kTextureBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config,
bed.src / "BedPrinter.json", "BedPrinter", texture, {});
nlohmann::json structure = bed_manifest("bad-keyed");
set_printer_bed_asset(structure, "bed_custom_texture", name);
std::vector<std::pair<std::string, std::string>> entries = {
{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()},
{name, marker}};
const fs::path zip_file = bed.src / "bad-keyed.orca_printer";
write_zip(zip_file, entries);
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == texture);
if (fs::exists(bed.data_root))
for (fs::recursive_directory_iterator it(bed.data_root), end; it != end; ++it)
if (fs::is_regular_file(*it))
CHECK(read_file(*it).find(marker) == std::string::npos);
}
}
SECTION("field name does not match file kind") {
BedRoots bed;
const std::string texture = (bed.src / "kept.png").make_preferred().string();
write_bytes(texture, kTextureBytes);
const fs::path printer_json = write_printer_json(bed.bundle.printers.default_preset().config, bed.src / "BedPrinter.json",
"BedPrinter", texture, {});
nlohmann::json structure = bed_manifest("kind-mismatch");
set_printer_bed_asset(structure, "bed_custom_texture", "bed/0/model.stl");
const fs::path zip_file = bed.src / "kind.orca_printer";
write_zip(zip_file, {{"printer/BedPrinter.json", read_file(printer_json)}, {BUNDLE_STRUCTURE_JSON_NAME, structure.dump()},
{"bed/0/model.stl", kModelBytes}});
const Preset *saved = import_bed(bed.bundle, zip_file, bed.data_root);
REQUIRE(saved != nullptr);
REQUIRE(saved->config.opt_string("bed_custom_texture") == texture);
CHECK_FALSE(any_filename_contains(bed.data_root, "model.stl"));
}
}
TEST_CASE("A saved printer preset reloads the tool layout it was saved with", "[Preset][Bundle][IMEX]")
{
ScopedTemporaryDir temp_dir;