diff --git a/resources/profiles/Snapmaker/Snapmaker U1_texture.svg b/resources/profiles/Snapmaker/Snapmaker U1_bed.svg similarity index 100% rename from resources/profiles/Snapmaker/Snapmaker U1_texture.svg rename to resources/profiles/Snapmaker/Snapmaker U1_bed.svg diff --git a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json index 3c7d6fa7aa..6422735955 100644 --- a/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json +++ b/resources/profiles/Snapmaker/machine/Snapmaker U1 (0.4 nozzle).json @@ -1,14 +1,14 @@ { "type": "machine", + "setting_id": "SM_U1", "name": "Snapmaker U1 (0.4 nozzle)", - "inherits": "fdm_U1", "from": "system", - "setting_id": "1591507869", "instantiation": "true", + "inherits": "fdm_U1", "printer_model": "Snapmaker U1", "printer_variant": "0.4", "auxiliary_fan": "1", - "change_filament_gcode": "; Change Tool[previous_extruder] -> Tool[next_extruder] (layer [layer_num])\n{\nlocal max_speed_toolchange = 350.0;\nlocal wait_for_extruder_temp = true;\nposition[2] = position[2] + 2.0;\n\nlocal speed_toolchange = max_speed_toolchange;\nif travel_speed < max_speed_toolchange then\n speed_toolchange = travel_speed;\nendif\n\"G91\nG0 Z1.5 F600\nG90\n\";\n\"G1 F\" + (speed_toolchange * 60) + \"\n\";\nif wait_for_extruder_temp and not((layer_num < 0) and (next_extruder == initial_tool)) then\n \"\n\";\n \"; \" + layer_num + \"\n\";\n if layer_num == 0 then\n \"M109 S\" + first_layer_temperature[next_extruder] + \" T\" + next_extruder + \"\n\";\n else\n \"M109 S\" + temperature[next_extruder] + \" T\" + next_extruder + \"\n\";\n endif\nendif\n\"T\" + next_extruder + \"\n\";\n}\nM400\n{if filament_type[next_extruder] == \"PVA\"}\nSET_VELOCITY_LIMIT ACCEL=3000\n{else}\n{endif}", + "change_filament_gcode": ";===== date: 20251213=====================\n; Change Tool[previous_extruder] -> Tool[next_extruder] (layer [layer_num])\n{\nlocal max_speed_toolchange = 350.0;\nlocal wait_for_extruder_temp = true;\nposition[2] = position[2] + 2.0;\nlocal speed_toolchange = max_speed_toolchange;\nif travel_speed < max_speed_toolchange then\n speed_toolchange = travel_speed;\nendif\n\"G91\nG1 Z1.5 F1800\nG90\n\";\n\"G1 F\" + (speed_toolchange * 60) + \"\n\";\nif wait_for_extruder_temp and not((layer_num < 0) and (next_extruder == initial_tool)) then\n \"\n\";\n \"; \" + layer_num + \"\n\";\n if layer_num == 0 then\n \"M109 S\" + first_layer_temperature[next_extruder] + \" T\" + next_extruder + \"\n\";\n else\n \"M109 S\" + temperature[next_extruder] + \" T\" + next_extruder + \"\n\";\n endif\nendif\n\"M400\" + \"\n\";\n\"T\" + next_extruder + \"\n\";\nif filament_type[next_extruder] == \"PVA\" then\n\"SET_VELOCITY_LIMIT ACCEL=3000\n\";\nelse\nendif\nif previous_extruder != next_extruder and initial_extruder != next_extruder then\n\"SM_PRINT_PREEXTRUDE_FILAMENT INDEX=\" + next_extruder + \"\n\";\nendif\n\"G90\n\";\n}\n", "extruder_colour": [ "#FCE94F", "#FCE94F", @@ -41,6 +41,7 @@ "20", "12" ], + "machine_start_gcode": "SET_PRINT_AUTO_BED_LEVELING ENABLE=1\nSET_TIME_LAPSE_CAMERA ENABLE=1\n;===== date: 20251222 =====================\n\nPRINT_START\nDEFECT_DETECTION_START\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count}\nSET_PRINT_STATS_INFO CURRENT_LAYER=0\nTIMELAPSE_START\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\nM204 S10000\n\nG28 X Y\n;===== 床面异物检测 ========\nT{initial_extruder}\nG90\nDEFECT_DETECTION_DETECT_BED\n;===== 取放头检测 =================\nSM_PRINT_CHECK_SWITCH_EXTRUDER\n\n;===== 自动进料 & 挤出流量 & 预挤出 ======================\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=1 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=0\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=2 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=1\nSM_PRINT_EXTRUDER_PREHEAT EXTRUDER=3 TEMP=140\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\nSM_PRINT_FLOW_CALIBRATE EXTRUDER=3\nM104 S0 T0 A0\nM104 S0 T1 A0\nM104 S0 T2 A0\nM104 S0 T3 A0\nM104 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\n\n;===== 粗回零 =================\nT{initial_extruder}\nM106 S255\nM106 P2 S0\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 T{initial_extruder} S{nozzle_temperature[initial_extruder] - 90}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nG28 Z I140 J140\n\n;===== 检测钢板 =================\nDETECT_BED_PLATE\n\n;===== 深度清洁喷嘴 =================\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_1\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\nFINELY_CLEAN_NOZZLE_STAGE_2\n\n;===== 精回零 =================\nM106 S255\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM107 P2\nG90\nG0 Z5 F10000\nG28 Z\n\n;===== 热床调平 =================\n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0\n; Original upstream: BED_MESH_CALIBRATE PROBE_COUNT=11,11\n\n;===== 画起始线 =================\nG90\nG1 Z1.5\nG0 X10 Y3 Z2 F18000\nM109 S{nozzle_temperature_initial_layer[initial_extruder]}\nG1 Z0.2\nM83\nG1 X110 E15 F360\nG1 Z1.5\n\nG90\nM106 S0", "machine_tool_change_time": "5", "max_layer_height": [ "0.32", @@ -60,14 +61,14 @@ "0.4", "0.4" ], - "nozzle_type": "hardened_steel", + "nozzle_type": "stainless_steel", "printable_area": [ - "-0.5x-1", - "270.5x-1", + "0.5x1", + "270.5x1", "270.5x271", - "-0.5x271" + "0.5x271" ], - "printable_height": "270", + "printable_height": "270.05", "printer_settings_id": "MyToolChanger 0.4 nozzle - Copy", "retract_before_wipe": [ "0%", @@ -183,7 +184,7 @@ "extruder_clearance_radius": "72.5", "machine_load_filament_time": "0", "machine_unload_filament_time": "0", - "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME", + "before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\nTIMELAPSE_TAKE_FRAME\nDEFECT_DETECTION_DETECT", "z_hop_when_prime": [ "0", "0", @@ -192,6 +193,9 @@ ], "ramming_pressure_advance_value": "0.02", "tool_change_temprature_wait": "0", - "printer_notes": "1、修改幅面坐标,原点坐标\n2、修改换头时间,5S", - "machine_pause_gcode": "M600" + "printer_notes": "", + "machine_pause_gcode": "M600", + "default_bed_type": "Textured PEI Plate", + "layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]\nSET_PRINT_STATS_INFO TOTAL_LAYER={total_layer_count}\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num+1}", + "nozzle_volume": "143" } \ No newline at end of file diff --git a/resources/profiles/Snapmaker/machine/fdm_U1.json b/resources/profiles/Snapmaker/machine/fdm_U1.json index fca1592792..ab6170bf60 100644 --- a/resources/profiles/Snapmaker/machine/fdm_U1.json +++ b/resources/profiles/Snapmaker/machine/fdm_U1.json @@ -7,7 +7,7 @@ "gcode_flavor": "klipper", "single_extruder_multi_material": "0", "bed_model": "Snapmaker U1_bed.stl", - "bed_texture": "Snapmaker U1_texture.svg", + "bed_texture": "Snapmaker U1_bed.svg", "max_layer_height": [ "0.32", "0.32", @@ -180,9 +180,10 @@ "bed_mesh_min": "3,3", "purge_in_prime_tower": "0", "machine_pause_gcode": "M601", - "change_filament_gcode": "", - "machine_start_gcode": ";===== machine: PR2 ========================\n;===== date: 20250717 =====================\nPRINT_START\n;===== 预热热床和第一个挤出头 =================\nM140 S{bed_temperature_initial_layer_single}\nM104 T{initial_extruder} S140\n\n;===== 粗回零 =================\nG28 X Y\nT{initial_extruder}\nM109 T{initial_extruder} S140\nG28 Z\nG90\nG0 Z10 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nM109 S{nozzle_temperature[initial_extruder] - 50}\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nM104 S{nozzle_temperature[initial_extruder] - 90}\nG4 P2000\nROUGHLY_CLEAN_NOZZLE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\n\n;===== 检测钢板 =================\nDETECT_BED_PLATE\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\n\n;===== 自动进料 ======================\nSM_PRINT_AUTO_FEED EXTRUDER=0\nSM_PRINT_AUTO_FEED EXTRUDER=1\nSM_PRINT_AUTO_FEED EXTRUDER=2\nSM_PRINT_AUTO_FEED EXTRUDER=3\n\n;===== 挤出流量 ======================\n{if (is_extruder_used[0])}\nSM_PRINT_FLOW_CALIBRATE INDEX=0 TARGET_TEMP={nozzle_temperature[0]}\n{endif}\n{if (is_extruder_used[1])}\nSM_PRINT_FLOW_CALIBRATE INDEX=1 TARGET_TEMP={nozzle_temperature[1]}\n{endif}\n{if (is_extruder_used[2])}\nSM_PRINT_FLOW_CALIBRATE INDEX=2 TARGET_TEMP={nozzle_temperature[2]}\n{endif}\n{if (is_extruder_used[3])}\nSM_PRINT_FLOW_CALIBRATE INDEX=3 TARGET_TEMP={nozzle_temperature[3]}\n{endif}\n\n;===== 取出第一个挤出头 =================\nT{initial_extruder}\nSET_VELOCITY_LIMIT ACCEL=10000\nM204 S10000\n\n;===== 深度清洁喷嘴 =================\nG90\nG0 Z10 F10000\nROUGHLY_CLEAN_NOZZLE_WITH_DISCARD\nG0 Z5 F10000\nFINELY_CLEAN_NOZZLE_STAGE_1\nG0 Z5 F10000\nROUGHLY_CLEAN_NOZZLE\nG0 Z5 F10000\nFINELY_CLEAN_NOZZLE_STAGE_2\nM83\n\n;===== 第一个挤出头降温 =================\nM109 S{nozzle_temperature[initial_extruder] - 90}\nM190 S{bed_temperature_initial_layer_single}\nM106 S0\nG90\nG0 Z5 F10000\nMOVE_TO_DISCARD_FILAMENT_POSITION\nINNER_CUTOFF_BASE_DISCARD\nINNER_ROUGHLY_CLEAN_NOZZLE_BASE_DISCARD\nINNER_ROUGHLY_CLEAN_NOZZLE_BASE_DISCARD\nMOVE_TO_XY_IDLE_POSITION_EXTRUDER\n\n;===== 精回零 =================\nG28 Z\n;===== 热床调平 =================\n; Always pass `ADAPTIVE_MARGIN=0` because Orca has already handled `adaptive_bed_mesh_margin` internally\n; Make sure to set ADAPTIVE to 0 otherwise Klipper will use it's own adaptive bed mesh logic\nBED_MESH_CALIBRATE mesh_min={adaptive_bed_mesh_min[0]},{adaptive_bed_mesh_min[1]} mesh_max={adaptive_bed_mesh_max[0]},{adaptive_bed_mesh_max[1]} ALGORITHM=[bed_mesh_algo] PROBE_COUNT={bed_mesh_probe_count[0]},{bed_mesh_probe_count[1]} ADAPTIVE=0 ADAPTIVE_MARGIN=0\n\n;BED_MESH_CALIBRATE PROBE_COUNT=7,7\n\n\n;======== 预挤出/划线 ================\n{if (is_extruder_used[0]) and 0 != initial_extruder}\nSM_PRINT_START_LINE INDEX=0 TARGET_TEMP={nozzle_temperature_initial_layer[0]}\nM83\nM104 S{nozzle_temperature[0] - 90}\n{endif}\n\n{if (is_extruder_used[1]) and 1 != initial_extruder}\nSM_PRINT_START_LINE INDEX=1 TARGET_TEMP={nozzle_temperature_initial_layer[1]}\nM83\nM104 S{nozzle_temperature[1] - 90}\n{endif}\n\n{if (is_extruder_used[2]) and 2 != initial_extruder}\nSM_PRINT_START_LINE INDEX=2 TARGET_TEMP={nozzle_temperature_initial_layer[2]}\nM83\nM104 S{nozzle_temperature[2] - 90}\n{endif}\n\n{if (is_extruder_used[3]) and 3 != initial_extruder}\nSM_PRINT_START_LINE INDEX=3 TARGET_TEMP={nozzle_temperature_initial_layer[3]}\nM83\nM104 S{nozzle_temperature[3] - 90}\n{endif}\n\n{if (is_extruder_used[initial_extruder])}\nSM_PRINT_START_LINE INDEX={initial_extruder} TARGET_TEMP={nozzle_temperature_initial_layer[initial_extruder]}\n{endif}\nM109 S{nozzle_temperature_initial_layer[initial_extruder]} T{initial_extruder}\nM106 S0\n\nTIMELAPSE_START", + "change_filament_gcode": "", + "machine_start_gcode": "PRINT_START TOOL_TEMP={first_layer_temperature[initial_tool]} {if is_extruder_used[0]}T0_TEMP={first_layer_temperature[0]}{endif} {if is_extruder_used[1]}T1_TEMP={first_layer_temperature[1]}{endif} {if is_extruder_used[2]}T2_TEMP={first_layer_temperature[2]}{endif} {if is_extruder_used[3]}T3_TEMP={first_layer_temperature[3]}{endif} {if is_extruder_used[4]}T4_TEMP={first_layer_temperature[4]}{endif} {if is_extruder_used[5]}T5_TEMP={first_layer_temperature[5]}{endif} BED_TEMP=[first_layer_bed_temperature] TOOL=[initial_tool]\n\nM83\n; set extruder temp\n{if first_layer_temperature[0] > 0 and (is_extruder_used[0])}M104 T0 S{first_layer_temperature[0]}{endif}\n{if first_layer_temperature[1] > 0 and (is_extruder_used[1])}M104 T1 S{first_layer_temperature[1]}{endif}\n{if first_layer_temperature[2] > 0 and (is_extruder_used[2])}M104 T2 S{first_layer_temperature[2]}{endif}\n{if first_layer_temperature[3] > 0 and (is_extruder_used[3])}M104 T3 S{first_layer_temperature[3]}{endif}\n{if first_layer_temperature[4] > 0 and (is_extruder_used[4])}M104 T4 S{first_layer_temperature[4]}{endif}\n{if (is_extruder_used[0]) and initial_tool != 0}\n;\n; purge first tool\n;\nG1 F{travel_speed * 60}\nM109 T0 S{first_layer_temperature[0]}\nT0; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(0 == 0 ? 0 : (0 == 1 ? 120 : (0 == 2 ? 180 : 300)))} Y{(0 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[0]}10{else}30{endif} X40 Z0.2 F{if filament_multitool_ramming[0]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X40 E9 F800 ; continue purging and wipe the nozzle\nG0 X{40 + 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{40 + 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[0]} F2400 ; retract\n{e_retracted[0] = 1.5 * retract_length[0]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[0] == 0 ? (first_layer_temperature[0] + standby_temperature_delta) : (idle_temperature[0]))} T0\n{endif}\n{if (is_extruder_used[1]) and initial_tool != 1}\n;\n; purge second tool\n;\nG1 F{travel_speed * 60}\nM109 T1 S{first_layer_temperature[1]}\nT1; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(1 == 0 ? 0 : (1 == 1 ? 120 : (1 == 2 ? 180 : 300)))} Y{(1 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[1]}10{else}30{endif} X120 Z0.2 F{if filament_multitool_ramming[1]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X80 E9 F800 ; continue purging and wipe the nozzle\nG0 X{80 - 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{80 - 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[1]} F2400 ; retract\n{e_retracted[1] = 1.5 * retract_length[1]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[1] == 0 ? (first_layer_temperature[1] + standby_temperature_delta) : (idle_temperature[1]))} T1\n{endif}\n{if (is_extruder_used[2]) and initial_tool != 2}\n;\n; purge third tool\n;\nG1 F{travel_speed * 60}\nM109 T2 S{first_layer_temperature[2]}\nT2; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(2 == 0 ? 0 : (2 == 1 ? 120 : (2 == 2 ? 180 : 300)))} Y{(2 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[2]}10{else}30{endif} X220 Z0.2 F{if filament_multitool_ramming[2]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X220 E9 F800 ; continue purging and wipe the nozzle\nG0 X{220 + 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{220 + 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[2]} F2400 ; retract\n{e_retracted[2] = 1.5 * retract_length[2]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[2] == 0 ? (first_layer_temperature[2] + standby_temperature_delta) : (idle_temperature[2]))} T2\n{endif}\n{if (is_extruder_used[3]) and initial_tool != 3}\n;\n; purge fourth tool\n;\nG1 F{travel_speed * 60}\nM109 T3 S{first_layer_temperature[3]}\nT3; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(3 == 0 ? 0 : (3 == 1 ? 120 : (3 == 2 ? 180 : 300)))} Y{(3 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[3]}10{else}30{endif} X290 Z0.2 F{if filament_multitool_ramming[3]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X260 E9 F800 ; continue purging and wipe the nozzle\nG0 X{260 - 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{260 - 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[3]} F2400 ; retract\n{e_retracted[3] = 1.5 * retract_length[3]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[3] == 0 ? (first_layer_temperature[3] + standby_temperature_delta) : (idle_temperature[3]))} T3\n{endif}\n{if (is_extruder_used[4]) and initial_tool != 4}\n;\n; purge fifth tool\n;\nG1 F{travel_speed * 60}\nM109 T4 S{first_layer_temperature[4]}\nT4; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(4 == 0 ? 0 : (4 == 1 ? 120 : (4 == 2 ? 180 : 300)))} Y{(4 < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[4]}10{else}30{endif} X290 Z0.2 F{if filament_multitool_ramming[4]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X260 E9 F800 ; continue purging and wipe the nozzle\nG0 X{260 - 3} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{260 - 3 * 2} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[4]} F2400 ; retract\n{e_retracted[4] = 1.5 * retract_length[4]} ; update slicer internal retract variable\nG92 E0 ; reset extruder position\n\nM104 S{(idle_temperature[4] == 0 ? (first_layer_temperature[4] + standby_temperature_delta) : (idle_temperature[4]))} T4\n{endif}\n;\n; purge initial tool\n;\nG1 F{travel_speed * 60}\nM109 T{initial_tool} S{first_layer_temperature[initial_tool]}\nT{initial_tool}; pick the tool\nG92 E0 ; reset extruder position\n\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300)))} Y{(initial_tool < 4 ? 0 : 3)} Z10 F{(travel_speed * 60)} ; move close to the sheet's edge\nG0 E{if filament_multitool_ramming[initial_tool]}10{else}30{endif} X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 10)} Z0.2 F{if filament_multitool_ramming[initial_tool]}500{else}170{endif} ; purge while moving towards the sheet\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 40)} E9 F800 ; continue purging and wipe the nozzle\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 40) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 3)} Z{0.05} F{8000} ; wipe, move close to the bed\nG0 X{(initial_tool == 0 ? 0 : (initial_tool == 1 ? 120 : (initial_tool == 2 ? 180 : 300))) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 40) + ((initial_tool == 0 or initial_tool == 2 ? 1 : -1) * 3 * 2)} Z0.2 F{8000} ; wipe, move quickly away from the bed\nG1 E{- 1.5 * retract_length[initial_tool]} F2400 ; retract\n{e_retracted[initial_tool] = 1.5 * retract_length[initial_tool]}\nG92 E0 ; reset extruder position\n", "scan_first_layer": "0", - "nozzle_type": "hardened_steel", - "auxiliary_fan": "0" + "nozzle_type": "undefine", + "auxiliary_fan": "0", + "default_bed_type": "Textured PEI Plate" } \ No newline at end of file diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index a3ab6450d8..397cd66d38 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -1316,14 +1316,14 @@ int CLI::run(int argc, char **argv) return (argc == 0) ? 0 : 1; #endif // SLIC3R_GUI } + + // Setup logging for CLI + const ConfigOptionInt* opt_loglevel = m_config.opt("debug"); + if (opt_loglevel) { + set_logging_level(opt_loglevel->value); + } else { - const ConfigOptionInt *opt_loglevel = m_config.opt("debug"); - if (opt_loglevel) { - set_logging_level(opt_loglevel->value); - } - else { - set_logging_level(2); - } + set_logging_level(2); } global_begin_time = (long long)Slic3r::Utils::get_current_time_utc(); @@ -6401,8 +6401,9 @@ int CLI::run(int argc, char **argv) glfwSetErrorCallback(glfw_callback); int ret = glfwInit(); if (ret == GLFW_FALSE) { - int code = glfwGetError(NULL); - BOOST_LOG_TRIVIAL(error) << "glfwInit return error, code " <enable_prime_tower) + return false; + if (m_print_config_ptr->wipe_tower_filament == 0) + return false; + + bool changed = false; + const unsigned int wipe_extruder = (unsigned int)(m_print_config_ptr->wipe_tower_filament - 1); + for (LayerTools < : m_layer_tools) { + if (lt.wipe_tower_partitions > 0) { + if (std::find(lt.extruders.begin(), lt.extruders.end(), wipe_extruder) == lt.extruders.end()) { + lt.extruders.emplace_back(wipe_extruder); + changed = true; + } + } + } + return changed; +} + void ToolOrdering::sort_and_build_data(const Print& print, unsigned int first_extruder, bool prime_multi_material) { // if first extruder is -1, we can decide the first layer tool order before doing reorder function @@ -328,9 +348,13 @@ void ToolOrdering::sort_and_build_data(const Print& print, unsigned int first_ex max_layer_height = calc_max_layer_height(print.config(), max_layer_height); - this->collect_extruder_statistics(prime_multi_material); - this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height); + if (this->insert_wipe_tower_extruder()) { + reorder_extruders_for_minimum_flush_volume(reorder_first_layer); + this->fill_wipe_tower_partitions(print.config(), object_bottom_z, max_layer_height); + } + + this->collect_extruder_statistics(prime_multi_material); } void ToolOrdering::sort_and_build_data(const PrintObject& object , unsigned int first_extruder, bool prime_multi_material) @@ -343,9 +367,13 @@ void ToolOrdering::sort_and_build_data(const PrintObject& object , unsigned int double max_layer_height = calc_max_layer_height(object.print()->config(), object.config().layer_height); - this->collect_extruder_statistics(prime_multi_material); - this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, max_layer_height); + if (this->insert_wipe_tower_extruder()) { + reorder_extruders_for_minimum_flush_volume(reorder_first_layer); + this->fill_wipe_tower_partitions(object.print()->config(), object.layers().front()->print_z - object.layers().front()->height, max_layer_height); + } + + this->collect_extruder_statistics(prime_multi_material); } diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index 7f7fc6a6ce..7bbfa2da1f 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -258,6 +258,7 @@ private: void initialize_layers(std::vector &zs); void collect_extruders(const PrintObject &object, const std::vector> &per_layer_extruder_switches); void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height); + bool insert_wipe_tower_extruder(); void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height); void collect_extruder_statistics(bool prime_multi_material); void reorder_extruders_for_minimum_flush_volume(bool reorder_first_layer); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 0be6748594..4c6ed404b5 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -1540,7 +1540,7 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config) m_filpar.push_back(FilamentParameters()); m_filpar[idx].material = config.filament_type.get_at(idx); - m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx); + m_filpar[idx].is_soluble = config.wipe_tower_filament == 0 ? config.filament_soluble.get_at(idx) : (idx != size_t(config.wipe_tower_filament - 1)); // BBS m_filpar[idx].is_support = config.filament_is_support.get_at(idx); m_filpar[idx].nozzle_temperature = config.nozzle_temperature.get_at(idx); diff --git a/src/libslic3r/GCode/WipeTower2.cpp b/src/libslic3r/GCode/WipeTower2.cpp index 19e98e4a09..ba22338eba 100644 --- a/src/libslic3r/GCode/WipeTower2.cpp +++ b/src/libslic3r/GCode/WipeTower2.cpp @@ -1227,6 +1227,7 @@ WipeTower::ToolChangeResult WipeTower2::construct_tcr(WipeTowerWriter2& writer, WipeTower2::WipeTower2(const PrintConfig& config, const PrintRegionConfig& default_region_config,int plate_idx, Vec3d plate_origin, const std::vector>& wiping_matrix, size_t initial_tool) : m_semm(config.single_extruder_multi_material.value), m_enable_filament_ramming(config.enable_filament_ramming.value), + m_wipe_tower_filament(config.wipe_tower_filament.value), m_wipe_tower_pos(config.wipe_tower_x.get_at(plate_idx), config.wipe_tower_y.get_at(plate_idx)), m_wipe_tower_width(float(config.prime_tower_width)), m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)), @@ -1309,7 +1310,10 @@ void WipeTower2::set_extruder(size_t idx, const PrintConfig& config) m_filpar.push_back(FilamentParameters()); m_filpar[idx].material = config.filament_type.get_at(idx); - m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx); + if (m_wipe_tower_filament > 0) + m_filpar[idx].is_soluble = (idx != size_t(m_wipe_tower_filament - 1)); + else + m_filpar[idx].is_soluble = config.filament_soluble.get_at(idx); m_filpar[idx].temperature = config.nozzle_temperature.get_at(idx); m_filpar[idx].first_layer_temperature = config.nozzle_temperature_initial_layer.get_at(idx); m_filpar[idx].filament_minimal_purge_on_wipe_tower = config.filament_minimal_purge_on_wipe_tower.get_at(idx); @@ -2224,14 +2228,16 @@ void WipeTower2::save_on_last_wipe() int WipeTower2::first_toolchange_to_nonsoluble( const std::vector& tool_changes) const { - // Orca: allow calculation of the required depth and wipe volume for soluable toolchanges as well - // NOTE: it's not clear if this is the right way, technically we should disable wipe tower if soluble filament is used as it - // will will make the wipe tower unstable. Need to revist this in the future. + // If a specific wipe tower filament is forced, use it to decide where to finish the layer. + if (m_wipe_tower_filament > 0) { + for (size_t idx = 0; idx < tool_changes.size(); ++idx) { + if (!m_filpar[tool_changes[idx].new_tool].is_soluble) + return idx; + } + return -1; + } + // Orca: allow calculation of the required depth and wipe volume for soluble toolchanges as well. return tool_changes.empty() ? -1 : 0; - //for (size_t idx=0; idx> &unknowns, bool use_map, std::map &maps,bool enable_append, MergeFilamentInfo &merge_info) +unsigned int PresetBundle::sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "use_map:" << use_map << " enable_append:" << enable_append; std::vector ams_filament_presets; @@ -2489,7 +2489,71 @@ unsigned int PresetBundle::sync_ams_list(std::vector("filament_colour"); ConfigOptionStrings *filament_color_type = project_config.option("filament_colour_type"); ConfigOptionInts * filament_map = project_config.option("filament_map"); - if (use_map) { + if (color_only) { + auto get_map_index = [&ams_infos](const std::vector &infos, const AMSMapInfo &temp) { + for (int i = 0; i < infos.size(); i++) { + if (infos[i].slot_id == temp.slot_id && infos[i].ams_id == temp.ams_id) { + ams_infos[i].is_map = true; + return i; + } + } + return -1; + }; + + auto exist_colors = filament_color->values; + std::vector> exist_multi_color_filment(exist_colors.size()); + for (size_t i = 0; i < exist_colors.size(); i++) { + exist_multi_color_filment[i] = {exist_colors[i]}; + } + + ConfigOptionStrings *project_multi_color = project_config.option("filament_multi_colour"); + if (project_multi_color) { + for (size_t i = 0; i < std::min(exist_multi_color_filment.size(), project_multi_color->values.size()); i++) { + std::vector colors = split_string(project_multi_color->values[i], ' '); + if (!colors.empty()) { + exist_multi_color_filment[i] = colors; + } + } + } + + bool mapped_any = false; + if (use_map && !maps.empty()) { + for (size_t i = 0; i < exist_colors.size(); i++) { + if (maps.find(i) == maps.end()) { + continue; + } + int valid_index = get_map_index(ams_array_maps, maps[i]); + if (valid_index >= 0 && valid_index < int(ams_filament_colors.size()) && !ams_filament_colors[valid_index].empty()) { + exist_colors[i] = ams_filament_colors[valid_index]; + mapped_any = true; + if (valid_index < int(ams_multi_color_filment.size()) && !ams_multi_color_filment[valid_index].empty()) { + exist_multi_color_filment[i] = ams_multi_color_filment[valid_index]; + } else { + exist_multi_color_filment[i] = {ams_filament_colors[valid_index]}; + } + } + } + } + // Fallback to index-based color sync if no mapping was applied. + if (!use_map || maps.empty() || !mapped_any) { + size_t sync_count = std::min(exist_colors.size(), ams_filament_colors.size()); + for (size_t i = 0; i < sync_count; i++) { + if (ams_filament_colors[i].empty()) { + continue; + } + exist_colors[i] = ams_filament_colors[i]; + if (i < ams_multi_color_filment.size() && !ams_multi_color_filment[i].empty()) { + exist_multi_color_filment[i] = ams_multi_color_filment[i]; + } else { + exist_multi_color_filment[i] = {ams_filament_colors[i]}; + } + } + } + + filament_color->values = exist_colors; + ams_multi_color_filment = exist_multi_color_filment; + merge_info.merges.clear(); + } else if (use_map) { auto check_has_merge_info = [](std::map &maps, MergeFilamentInfo &merge_info, int exist_colors_size) { std::set done; for (auto it_i = maps.begin(); it_i != maps.end(); ++it_i) { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 3c6aa9e6e6..51eed5646f 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -173,7 +173,7 @@ public: void update_num_filaments(unsigned int to_del_flament_id); void get_ams_cobox_infos(AMSComboInfo &combox_info); - unsigned int sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps,bool enable_append, MergeFilamentInfo& merge_info); + unsigned int sync_ams_list(std::vector> &unknowns, bool use_map, std::map &maps, bool enable_append, MergeFilamentInfo &merge_info, bool color_only = false); //BBS: check whether this is the only edited filament bool is_the_only_edited_filament(unsigned int filament_index); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 88119e4983..588b236fa3 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -520,6 +520,12 @@ std::vector Print::extruders(bool conside_custom_gcode) const } } + // If a wipe tower filament is explicitly set, ensure it participates in tool ordering. + if (has_wipe_tower() && config().wipe_tower_filament != 0 && extruders.size() > 1) { + assert(config().wipe_tower_filament > 0 && config().wipe_tower_filament < int(config().nozzle_diameter.size())); + extruders.emplace_back(config().wipe_tower_filament - 1); // config value is 1-based + } + sort_remove_duplicates(extruders); return extruders; } diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 52ba10ab03..7ec3215940 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -736,7 +736,7 @@ else() set(_opengl_link_lib OpenGL::GL) endif() -target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise) +target_link_libraries(libslic3r_gui libslic3r cereal::cereal imgui imguizmo minilzo libvgcode md4c-html GLEW::GLEW OpenGL::GL hidapi ${wxWidgets_LIBRARIES} glfw libcurl OpenSSL::SSL OpenSSL::Crypto noise::noise) if (MSVC) diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 716056049d..7db7391dff 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -462,9 +462,9 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size) } glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); if (tverts_range == std::make_pair(0, -1)) - model.render(); + model.render(shader); else - model.render(this->tverts_range); + model.render(this->tverts_range, shader); glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); // 2nd. render pass, just a normal render with the depth buffer passed as a texture @@ -576,15 +576,15 @@ void GLVolume::simple_render(GLShaderProgram* shader, ModelObjectPtrs& model_obj } } if (tverts_range == std::make_pair(0, -1)) - m.render(); + m.render(shader); else - m.render(this->tverts_range); + m.render(this->tverts_range, shader); } } else { if (tverts_range == std::make_pair(0, -1)) - model.render(); + model.render(shader); else - model.render(this->tverts_range); + model.render(this->tverts_range, shader); } if (this->is_left_handed()) glFrontFace(GL_CCW); diff --git a/src/slic3r/GUI/Camera.cpp b/src/slic3r/GUI/Camera.cpp index efd9bad0b0..3bde13f91d 100644 --- a/src/slic3r/GUI/Camera.cpp +++ b/src/slic3r/GUI/Camera.cpp @@ -55,7 +55,10 @@ void Camera::select_next_type() void Camera::auto_type(EType preferred_type) { - if (!wxGetApp().app_config->get_bool("auto_perspective")) return; + if (wxApp::GetInstance() == nullptr || wxGetApp().app_config == nullptr) + return; + if (!wxGetApp().app_config->get_bool("auto_perspective")) + return; if (preferred_type == EType::Perspective) { if (!m_prevent_auto_type) { set_type(preferred_type); @@ -758,4 +761,3 @@ void Camera::update_target() { } } // GUI } // Slic3r - diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index 507768ad64..523db38c25 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -596,12 +596,12 @@ static GLenum get_index_type(const GLModel::Geometry& data) } } -void GLModel::render() +void GLModel::render(GLShaderProgram* shader) { - render(std::make_pair(0, indices_count())); + render(std::make_pair(0, indices_count()), shader); } -void GLModel::render(const std::pair& range) +void GLModel::render(const std::pair& range, GLShaderProgram* shader) { if (m_render_disabled) return; @@ -609,7 +609,9 @@ void GLModel::render(const std::pair& range) if (range.second == range.first) return; - GLShaderProgram* shader = wxGetApp().get_current_shader(); + if (shader == nullptr && wxApp::GetInstance() != nullptr) + shader = wxGetApp().get_current_shader(); + if (shader == nullptr) return; diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 13729f5a9e..d007b31371 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -13,6 +13,7 @@ namespace Slic3r { class TriangleMesh; class Polygon; +class GLShaderProgram; using Polygons = std::vector>; class BuildVolume; @@ -177,8 +178,8 @@ namespace GUI { const ColorRGBA& get_color() const { return m_render_data.geometry.color; } void reset(); - void render(); - void render(const std::pair& range); + void render(GLShaderProgram* shader = nullptr); + void render(const std::pair& range, GLShaderProgram* shader = nullptr); void render_instanced(unsigned int instances_vbo, unsigned int instances_count); bool is_initialized() const { return vertices_count() > 0 && indices_count() > 0; } @@ -260,4 +261,3 @@ namespace GUI { } // namespace Slic3r #endif // slic3r_GLModel_hpp_ - diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index cbf930155a..22f0418e29 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -5450,7 +5450,7 @@ void GUI_App::check_new_version_sf(bool show_tips, int by_user) } version_info.url = prefer_release ? best_release_url : best_pre_url; - version_info.version_str = prefer_release ? best_release.to_string_sf() : best_pre.to_string(); + version_info.version_str = prefer_release ? best_release.to_string_sf() : best_pre.to_string_sf(); version_info.description = prefer_release ? best_release_content : best_pre_content; version_info.force_upgrade = false; diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 3bbc8927b6..39860ab9a8 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -253,7 +253,7 @@ bool OpenGLManager::init_gl(bool popup_error) glewExperimental = true; GLenum result = glewInit(); if (result != GLEW_OK) { - BOOST_LOG_TRIVIAL(error) << "Unable to init glew library"; + BOOST_LOG_TRIVIAL(error) << "Unable to init glew library, Error: " << glewGetErrorString(result); return false; } //BOOST_LOG_TRIVIAL(info) << "glewInit Success."<< std::endl; diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index acb8240523..33efc32507 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -3110,8 +3110,11 @@ bool PartPlate::set_shape(const Pointfs& shape, const Pointfs& exclude_areas, co calc_vertex_for_icons(3, m_lock_icon); calc_vertex_for_icons(4, m_plate_settings_icon); // ORCA also change bed_icon_count number in calc_vertex_for_icons() after adding or removing icons for circular shaped beds that uses vertical alingment for icons - PresetBundle* preset = wxGetApp().preset_bundle; - bool dual_bbl = (preset->is_bbl_vendor() && preset->get_printer_extruder_count() == 2); + bool dual_bbl = false; + if (m_plater) { + PresetBundle* preset = wxGetApp().preset_bundle; + dual_bbl = (preset->is_bbl_vendor() && preset->get_printer_extruder_count() == 2); + } calc_vertex_for_icons(dual_bbl ? 5 : 6, m_plate_filament_map_icon); calc_vertex_for_icons(dual_bbl ? 6 : 5, m_move_front_icon); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f12eb94983..c08a77f6b7 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3464,8 +3464,9 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) } MergeFilamentInfo merge_info; std::vector> unknowns; - auto enable_append = wxGetApp().app_config->get_bool("enable_append_color_by_sync_ams"); - auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns, !sync_result.direct_sync, sync_result.sync_maps, enable_append, merge_info); + auto enable_append = wxGetApp().app_config->get_bool("enable_append_color_by_sync_ams"); + auto sync_color_only = wxGetApp().app_config->get("sync_ams_filament_mode") == "1"; + auto n = wxGetApp().preset_bundle->sync_ams_list(unknowns, !sync_result.direct_sync, sync_result.sync_maps, enable_append, merge_info, sync_color_only); wxString detail; for (auto & uk : unknowns) { auto tray_name = uk.first->opt_string("tray_name", 0u); @@ -3497,9 +3498,11 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) _L("Sync filaments with AMS"), wxOK); dlg.ShowModal(); } - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "on_filament_count_change"; - wxGetApp().plater()->on_filament_count_change(n); - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "finish on_filament_count_change"; + if (!sync_color_only) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "on_filament_count_change"; + wxGetApp().plater()->on_filament_count_change(n); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "finish on_filament_count_change"; + } for (auto& c : p->combos_filament) c->update(); // Expand filament list @@ -3523,14 +3526,23 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) } Layout(); - // Perform preset selection and list update first — these may rebuild combo widgets, - // which clears any badge state. Badges must be set AFTER these calls to persist. - wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]); - wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); - update_dynamic_filament_list(); + // For full sync, preset selection/list update may rebuild combo widgets. + // For color-only, keep current presets untouched and refresh colors only. + if (!sync_color_only) { + wxGetApp().get_tab(Preset::TYPE_FILAMENT)->select_preset(wxGetApp().preset_bundle->filament_presets[0]); + wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + update_dynamic_filament_list(); + } else { + wxGetApp().plater()->update_filament_colors_in_full_config(); + for (auto &c : p->combos_filament) + c->update(); + obj_list()->update_filament_colors(); + update_dynamic_filament_list(); + } - auto badge_combox_filament = [](PlaterPresetComboBox *c) { - auto tip = _L("Filament type and color information have been synchronized, but slot information is not included."); + auto badge_combox_filament = [sync_color_only](PlaterPresetComboBox *c) { + auto tip = sync_color_only ? _L("Only filament color information has been synchronized from printer.") : + _L("Filament type and color information have been synchronized, but slot information is not included."); c->SetToolTip(tip); c->ShowBadge(true); }; diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 28868d3ac5..98ec6e0707 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -1492,6 +1492,16 @@ void PreferencesDialog::create_items() SETTING_USE_ENCRYPTED_TOKEN_FILE); g_sizer->Add(item_token_storage); + //// ONLINE > Filament Sync Options + g_sizer->Add(create_item_title(_L("Filament Sync Options")), 1, wxEXPAND); + + auto item_filament_sync_mode = create_item_combobox( + _L("Filament sync mode"), + _L("Choose whether sync updates both filament preset and color, or only color."), + "sync_ams_filament_mode", + {_L("Filament & Color"), _L("Color only")}); + g_sizer->Add(item_filament_sync_mode); + //// ONLINE > Network plugin g_sizer->Add(create_item_title(_L("Network plugin")), 1, wxEXPAND); diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 4af803d17d..20126bf254 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -27,6 +27,7 @@ #include "DeviceCore/DevManager.h" #include "DeviceCore/DevStorage.h" +#include "md4c/src/md4c-html.h" namespace Slic3r { namespace GUI { @@ -268,32 +269,31 @@ UpdateVersionDialog::UpdateVersionDialog(wxWindow *parent) //webview m_vebview_release_note = CreateTipView(m_simplebook_release_note); - m_vebview_release_note->SetBackgroundColour(wxColour(0xF8, 0xF8, 0xF8)); m_vebview_release_note->SetSize(wxSize(FromDIP(560), FromDIP(430))); m_vebview_release_note->SetMinSize(wxSize(FromDIP(560), FromDIP(430))); //m_vebview_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430))); - m_vebview_release_note->Bind(wxEVT_WEBVIEW_NAVIGATING,[=](wxWebViewEvent& event){ - static bool load_url_first = false; - if(load_url_first){ - // Orca: not used in Orca Slicer - // wxLaunchDefaultBrowser(url_line); + + m_vebview_release_note->Bind(wxEVT_WEBVIEW_NAVIGATING,[=, count = 0](wxWebViewEvent& event) mutable { + count++; + if (count == 1) { + m_vebview_release_note->SetPage(wxString::FromUTF8(html_source), ""); + } else if (count >= 3) { + // Launch the default browser for links clicked by the user + wxLaunchDefaultBrowser(event.GetURL()); event.Veto(); - }else{ - load_url_first = true; } - }); - fs::path ph(data_dir()); - ph /= "resources/tooltip/releasenote.html"; - if (!fs::exists(ph)) { - ph = resources_dir(); - ph /= "tooltip/releasenote.html"; - } - auto url = ph.string(); - std::replace(url.begin(), url.end(), '\\', '/'); - url = "file:///" + url; - m_vebview_release_note->LoadURL(from_u8(url)); + // fs::path ph(data_dir()); + // ph /= "resources/tooltip/releasenote.html"; + // if (!fs::exists(ph)) { + // ph = resources_dir(); + // ph /= "tooltip/releasenote.html"; + // } + // auto url = ph.string(); + // std::replace(url.begin(), url.end(), '\\', '/'); + // url = "file:///" + url; + // m_vebview_release_note->LoadURL(from_u8(url)); m_simplebook_release_note->AddPage(m_scrollwindows_release_note, wxEmptyString, false); m_simplebook_release_note->AddPage(m_vebview_release_note, wxEmptyString, false); @@ -470,27 +470,31 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve // } // } - if (use_web_link) { - m_brand->Hide(); - m_text_up_info->Hide(); - m_simplebook_release_note->SetSelection(1); - m_vebview_release_note->LoadURL(from_u8(url_line)); - } - else { - m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430))); - m_simplebook_release_note->SetSelection(0); - m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version)); - wxBoxSizer* sizer_text_release_note = new wxBoxSizer(wxVERTICAL); - auto m_staticText_release_note = new ::Label(m_scrollwindows_release_note, release_note, LB_AUTO_WRAP); - m_staticText_release_note->SetMinSize(wxSize(FromDIP(560), -1)); - m_staticText_release_note->SetMaxSize(wxSize(FromDIP(560), -1)); - sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5); - m_scrollwindows_release_note->SetSizer(sizer_text_release_note); - m_scrollwindows_release_note->Layout(); - m_scrollwindows_release_note->Fit(); - SetMinSize(GetSize()); - SetMaxSize(GetSize()); - } + // if (use_web_link) { + // m_brand->Hide(); + // m_text_up_info->Hide(); + // m_simplebook_release_note->SetSelection(1); + // m_vebview_release_note->LoadURL(from_u8(url_line)); + // } + // else { + m_simplebook_release_note->SetMaxSize(wxSize(FromDIP(560), FromDIP(430))); + m_simplebook_release_note->SetSelection(1); + m_text_up_info->SetLabel(wxString::Format(_L("Click to download new version in default browser: %s"), version)); + auto data_buf_in = release_note.utf8_str(); + auto bg_color = StateColor::darkModeColorFor(*wxWHITE).GetAsString(); + auto fg_color = StateColor::darkModeColorFor(*wxBLACK).GetAsString(); + html_source = (boost::format("") + % fg_color % bg_color).str(); + md_html(data_buf_in.data(), data_buf_in.length(), [](const MD_CHAR* text, MD_SIZE size, void* userdata) { + std::string* out_buf = (std::string*)userdata; + out_buf->append(text, size); + }, (void*) &html_source, MD_DIALECT_GITHUB | MD_FLAG_STRIKETHROUGH | MD_FLAG_WIKILINKS, 0); + html_source.append(""); + m_vebview_release_note->LoadURL("file://" + (boost::filesystem::path (resources_dir()) / "web/guide/0/index.html").string()); + + SetMinSize(GetSize()); + SetMaxSize(GetSize()); + // } wxGetApp().UpdateDlgDarkUI(this); Layout(); diff --git a/src/slic3r/GUI/ReleaseNote.hpp b/src/slic3r/GUI/ReleaseNote.hpp index 37b7c58935..0c11dc2f58 100644 --- a/src/slic3r/GUI/ReleaseNote.hpp +++ b/src/slic3r/GUI/ReleaseNote.hpp @@ -107,6 +107,7 @@ public: Button* m_button_download; Button* m_button_cancel; std::string url_line; + std::string html_source; }; class SecondaryCheckDialog : public DPIFrame diff --git a/src/slic3r/GUI/SyncAmsInfoDialog.cpp b/src/slic3r/GUI/SyncAmsInfoDialog.cpp index 49f75d23d1..1e6f2256fe 100644 --- a/src/slic3r/GUI/SyncAmsInfoDialog.cpp +++ b/src/slic3r/GUI/SyncAmsInfoDialog.cpp @@ -3337,7 +3337,9 @@ FinishSyncAmsDialog::FinishSyncAmsDialog(InputInfo &input_info) 310, input_info.dialog_pos, 68, - _L("Successfully synchronized color and type of filament from printer."), + wxGetApp().app_config->get("sync_ams_filament_mode") == "1" ? + _L("Successfully synchronized filament color from printer.") : + _L("Successfully synchronized color and type of filament from printer."), _CTX(L_CONTEXT("OK", "FinishSyncAms"), "FinishSyncAms"), "", DisappearanceMode::TimedDisappearance)