diff --git a/bundled_deps/admesh/admesh/stlinit.cpp b/bundled_deps/admesh/admesh/stlinit.cpp index 3e1886b..f2a5184 100644 --- a/bundled_deps/admesh/admesh/stlinit.cpp +++ b/bundled_deps/admesh/admesh/stlinit.cpp @@ -222,6 +222,15 @@ static bool stl_read(stl_file *stl, FILE *fp, int first_facet, bool first) } #endif + for (int j = 0; j < 3; ++j) { + for (int u = 0; u < 3; ++u) { + if (std::isnan(facet.vertex[j](u)) || std::isinf(facet.vertex[j](u))) { + BOOST_LOG_TRIVIAL(error) << "stl_read: facet " << i << ": vertex " << j << "contains invalid coordinate"; + return false; + } + } + } + // Write the facet into memory. stl->facet_start[i] = facet; stl_facet_stats(stl, facet, first); diff --git a/deps/+Eigen/Eigen.cmake b/deps/+Eigen/Eigen.cmake index e14b0f8..2b01637 100644 --- a/deps/+Eigen/Eigen.cmake +++ b/deps/+Eigen/Eigen.cmake @@ -1,4 +1,4 @@ add_cmake_project(Eigen URL "https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip" - URL_HASH SHA256=e09b89aae054e9778ee3f606192ee76d645eec82c402c01c648b1fe46b6b9857 + URL_HASH SHA256=4815118c085ff1d5a21f62218a3b2ac62555e9b8d7bacd5093892398e7a92c4b ) diff --git a/deps/+MPFR/MPFR.cmake b/deps/+MPFR/MPFR.cmake index e04ce28..000ef3e 100644 --- a/deps/+MPFR/MPFR.cmake +++ b/deps/+MPFR/MPFR.cmake @@ -31,7 +31,7 @@ else () EXCLUDE_FROM_ALL ON #URL http://ftp.vim.org/ftp/gnu/mpfr/mpfr-3.1.6.tar.bz2 https://www.mpfr.org/mpfr-3.1.6/mpfr-3.1.6.tar.bz2 # mirrors are allowed #URL_HASH SHA256=cf4f4b2d80abb79e820e78c8077b6725bbbb4e8f41896783c899087be0e94068 - URL https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.bz2 + URL https://www.mpfr.org/mpfr-4.2.1/mpfr-4.2.1.tar.bz2 URL_HASH SHA256=b9df93635b20e4089c29623b19420c4ac848a1b29df1cfd59f26cab0d2666aa0 DOWNLOAD_DIR ${${PROJECT_NAME}_DEP_DOWNLOAD_DIR}/MPFR BUILD_IN_SOURCE ON diff --git a/resources/localization/list.txt b/resources/localization/list.txt index f5c0035..fe4f554 100644 --- a/resources/localization/list.txt +++ b/resources/localization/list.txt @@ -114,6 +114,8 @@ src/slic3r/GUI/SendSystemInfoDialog.cpp src/slic3r/GUI/Sidebar.cpp src/slic3r/GUI/SurfaceDrag.cpp src/slic3r/GUI/SysInfoDialog.cpp +src/slic3r/GUI/SyncBoxInfoDialog.cpp +src/slic3r/GUI/SyncBoxInfoDialog.cpp src/slic3r/GUI/Tab.cpp src/slic3r/GUI/Tab.hpp src/slic3r/GUI/TickCodesManager.cpp diff --git a/resources/profiles/QIDITechnology.idx b/resources/profiles/QIDITechnology.idx index 91a3d05..5001d1b 100644 --- a/resources/profiles/QIDITechnology.idx +++ b/resources/profiles/QIDITechnology.idx @@ -1,3 +1,5 @@ +min_slic3r_version = 1.2.4 +1.2.4 Optimize parameters min_slic3r_version = 1.2.3 1.2.3 Optimize parameters min_slic3r_version = 1.2.2 diff --git a/resources/profiles/QIDITechnology.ini b/resources/profiles/QIDITechnology.ini index f6d51bf..80b158d 100644 --- a/resources/profiles/QIDITechnology.ini +++ b/resources/profiles/QIDITechnology.ini @@ -5,7 +5,7 @@ name = QIDI Technology # Configuration version of this file. Config file will only be installed, if the config_version differs. # This means, the server may force the QIDISlicer configuration to be downgraded. -config_version = 1.2.3 +config_version = 1.2.4 # Where to get the updates from? config_update_url = https://github.com/QIDITECH/QIDISlicer/releases/download/QIDITechnology/ changelog_url = https://wiki.qidi3d.com/en/software/qidi-slicer/release-notes @@ -251,16 +251,14 @@ wipe_tower_extra_flow = 100% wipe_tower_extra_spacing = 100% wipe_tower_extruder = 0 wipe_tower_no_sparse_layers = 0 -wipe_tower_rotation_angle = 0 wipe_tower_width = 35 -wipe_tower_x = 180 -wipe_tower_y = 140 xy_contour_compensation = 0 xy_hole_compensation = 0 # Machine Print preset [print:*X-Plus 4*] inherits = *common* +wipe_tower = 1 [print:*Q1 Pro*] inherits = *common* @@ -711,6 +709,7 @@ compatible_printers_condition = printer_model=="X-smart 3" and nozzle_diameter[0 [filament:*common*] advance_pressure = 0.031 bed_temperature = 60 +box_temperature = 0 bridge_fan_speed = 100 chamber_minimal_temperature = 0 chamber_temperature = 0 @@ -734,11 +733,12 @@ fan_below_layer_time = 60 filament_colour = #3399FF filament_cooling_final_speed = 3.4 filament_cooling_initial_speed = 2.2 -filament_cooling_moves = 4 +filament_cooling_moves = 0 filament_cost = 0 filament_density = 1.24 filament_deretract_speed = nil filament_diameter = 1.75 +filament_flush_temp = 240 filament_infill_max_crossing_speed = 0 filament_infill_max_speed = 0 filament_load_time = 0 @@ -751,7 +751,7 @@ filament_multitool_ramming_flow = 10 filament_multitool_ramming_volume = 10 filament_notes = "" filament_purge_multiplier = 100 -filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" +filament_ramming_parameters = "120 100| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" filament_retract_before_travel = nil filament_retract_before_wipe = nil filament_retract_layer_change = nil @@ -796,6 +796,7 @@ slowdown_below_layer_time = 8 smooth_time = 0.03 start_filament_gcode = "; Filament gcode\n{if (enable_advance_pressure[0] == true)}M900 K[advance_pressure]{else}M900 K0{endif} T[smooth_time]\n" temperature = 220 +filament_id = # QIDI filament preset [filament:*QIDI ABS Odorless*] @@ -809,6 +810,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.92 filament_colour = #FFFACD filament_density = 1.02 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS first_layer_bed_temperature = 90 @@ -832,6 +834,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #FFC800 filament_density = 1.05 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS first_layer_bed_temperature = 90 @@ -855,6 +858,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #FFC800 filament_density = 1.06 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS first_layer_bed_temperature = 90 @@ -878,6 +882,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #282828 filament_density = 1.15 +filament_flush_temp = 280 filament_max_volumetric_speed = 12 filament_type = ABS-GF first_layer_bed_temperature = 100 @@ -903,6 +908,7 @@ extrusion_multiplier = 0.92 fan_below_layer_time = 40 filament_colour = #F0E68C filament_density = 1.07 +filament_flush_temp = 280 filament_max_volumetric_speed = 16 filament_type = ASA first_layer_bed_temperature = 90 @@ -928,6 +934,7 @@ extrusion_multiplier = 0.7 fan_below_layer_time = 40 filament_colour = #DCDCDC filament_density = 1.03 +filament_flush_temp = 280 filament_max_volumetric_speed = 12 filament_retract_before_travel = 0 filament_retract_layer_change = 0 @@ -958,6 +965,7 @@ extrusion_multiplier = 0.96 fan_below_layer_time = 10 filament_colour = #696969 filament_density = 1.09 +filament_flush_temp = 300 filament_max_volumetric_speed = 8 filament_type = PA12-CF first_layer_bed_temperature = 80 @@ -982,6 +990,7 @@ extrusion_multiplier = 0.96 fan_below_layer_time = 10 filament_colour = #4F4F4F filament_density = 1.20 +filament_flush_temp = 320 filament_max_volumetric_speed = 8 filament_type = PAHT-CF first_layer_bed_temperature = 80 @@ -1002,6 +1011,7 @@ extrusion_multiplier = 0.96 fan_below_layer_time = 10 filament_colour = #4F4F4F filament_density = 1.27 +filament_flush_temp = 320 filament_max_volumetric_speed = 10 filament_type = PAHT-GF first_layer_bed_temperature = 80 @@ -1025,6 +1035,7 @@ extrusion_multiplier = 0.92 fan_below_layer_time = 30 filament_colour = #FFF5EE filament_density = 1.19 +filament_flush_temp = 280 filament_max_volumetric_speed = 8 filament_type = PC/ABS-FR first_layer_bed_temperature = 100 @@ -1049,6 +1060,7 @@ extrusion_multiplier = 1 fan_below_layer_time = 10 filament_colour = #323232 filament_density = 1.30 +filament_flush_temp = 320 filament_max_volumetric_speed = 8 filament_type = PET-CF first_layer_bed_temperature = 80 @@ -1073,6 +1085,7 @@ extrusion_multiplier = 0.95 fan_below_layer_time = 30 filament_colour = #00FF40 filament_density = 1.24 +filament_flush_temp = 260 filament_max_volumetric_speed = 16 filament_type = PETG first_layer_bed_temperature = 80 @@ -1095,6 +1108,7 @@ extrusion_multiplier = 0.97 fan_below_layer_time = 10 filament_colour = #323232 filament_density = 1.38 +filament_flush_temp = 320 filament_max_volumetric_speed = 10 filament_type = PET-GF first_layer_bed_temperature = 80 @@ -1140,6 +1154,7 @@ enable_auxiliary_fan = 0 extrusion_multiplier = 0.96 filament_colour = #27408B filament_density = 1.25 +filament_flush_temp = 250 filament_max_volumetric_speed = 9 filament_type = PLA-CF first_layer_temperature = 230 @@ -1156,6 +1171,7 @@ extrusion_multiplier = 0.97 fan_below_layer_time = 5 filament_colour = #4F4F4F filament_density = 1.3 +filament_flush_temp = 350 filament_max_volumetric_speed = 6 filament_type = PPS-CF first_layer_bed_temperature = 110 @@ -1169,13 +1185,15 @@ chamber_temperature = 60 [filament:*QIDI TPU 95A-HF*] inherits = *common* advance_pressure = 0.1 +bed_temperature = 35 enable_auxiliary_fan = 0 extrusion_multiplier = 1 filament_colour = #8000FF filament_density = 1.15 +filament_flush_temp = 250 filament_max_volumetric_speed = 4 filament_type = TPU -filament_vendor = Generic +first_layer_bed_temperature = 35 first_layer_temperature = 230 temperature = 230 @@ -1191,6 +1209,7 @@ extrusion_multiplier = 0.94 fan_below_layer_time = 5 filament_colour = #696969 filament_density = 1.23 +filament_flush_temp = 320 filament_max_volumetric_speed = 8 filament_type = UltraPA-CF25 first_layer_bed_temperature = 80 @@ -1213,6 +1232,7 @@ enable_auxiliary_fan = 0 extrusion_multiplier = 0.96 filament_colour = #FFEBCD filament_density = 1.21 +filament_flush_temp = 290 filament_max_volumetric_speed = 3 filament_type = UltraPA first_layer_bed_temperature = 80 @@ -1228,8 +1248,81 @@ advance_pressure = 0.03 extrusion_multiplier = 0.95 filament_colour = #0073E6 filament_density = 1.23 +filament_flush_temp = 220 filament_max_volumetric_speed = 16 +[filament:*QIDI TPU-Aero*] +inherits = *common* +advance_pressure = 0.03 +bed_temperature = 35 +enable_auxiliary_fan = 0 +enable_dynamic_fan_speeds = 1 +extrusion_multiplier = 0.5 +fan_below_layer_time = 100 +filament_colour = #323232 +filament_density = 1.15 +filament_flush_temp = 270 +filament_max_volumetric_speed = 6 +filament_type = TPU +first_layer_bed_temperature = 35 +first_layer_temperature = 250 +overhang_fan_speed_0 = 100 +overhang_fan_speed_1 = 100 +slowdown_below_layer_time = 14 +temperature = 250 + +[filament:*QIDI Support For PET/PA*] +inherits = *common* +advance_pressure = 0.02 +bed_temperature = 80 +bridge_fan_speed = 50 +disable_fan_first_layers = 3 +enable_auxiliary_fan = 0 +enable_dynamic_fan_speeds = 1 +extrusion_multiplier = 0.91 +fan_below_layer_time = 10 +filament_colour = #323232 +filament_density = 1.16 +filament_flush_temp = 280 +filament_max_volumetric_speed = 8 +filament_type = Support For PET/PA +first_layer_bed_temperature = 80 +first_layer_temperature = 280 +max_fan_speed = 60 +min_fan_speed = 0 +overhang_fan_speed_0 = 100 +overhang_fan_speed_1 = 100 +overhang_fan_speed_2 = 100 +overhang_fan_speed_3 = 100 +slowdown_below_layer_time = 6 +temperature = 280 + +[filament:*QIDI Support For PAHT*] +inherits = *common* +advance_pressure = 0.02 +bed_temperature = 80 +bridge_fan_speed = 50 +disable_fan_first_layers = 3 +enable_auxiliary_fan = 0 +enable_dynamic_fan_speeds = 1 +extrusion_multiplier = 0.94 +fan_below_layer_time = 10 +filament_colour = #323232 +filament_density = 1.26 +filament_flush_temp = 280 +filament_max_volumetric_speed = 8 +filament_type = Support For PAHT +first_layer_bed_temperature = 80 +first_layer_temperature = 280 +max_fan_speed = 60 +min_fan_speed = 0 +overhang_fan_speed_0 = 100 +overhang_fan_speed_1 = 100 +overhang_fan_speed_2 = 100 +overhang_fan_speed_3 = 100 +slowdown_below_layer_time = 6 +temperature = 280 + # Generic filament preset [filament:*Generic ABS*] inherits = *common* @@ -1243,6 +1336,7 @@ extrusion_multiplier = 0.95 fan_below_layer_time = 30 filament_colour = #FFFF00 filament_density = 1.04 +filament_flush_temp = 280 filament_max_volumetric_speed = 17 filament_type = ABS filament_vendor = Generic @@ -1266,6 +1360,7 @@ extrusion_multiplier = 0.95 fan_below_layer_time = 30 filament_colour = #00FF00 filament_density = 1.27 +filament_flush_temp = 260 filament_max_volumetric_speed = 12 filament_type = PETG filament_vendor = Generic @@ -1316,6 +1411,7 @@ enable_auxiliary_fan = 0 extrusion_multiplier = 1 filament_colour = #8000FF filament_density = 1.21 +filament_flush_temp = 250 filament_max_volumetric_speed = 4 filament_type = TPU filament_vendor = Generic @@ -1334,6 +1430,7 @@ extrusion_multiplier = 0.95 fan_below_layer_time = 30 filament_colour = #FFEBCD filament_density = 1.04 +filament_flush_temp = 290 filament_max_volumetric_speed = 10 filament_type = PC filament_vendor = Generic @@ -1359,6 +1456,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #FFC800 filament_density = 1.12 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS filament_vendor = Polymaker @@ -1389,6 +1487,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #FFC800 filament_density = 1.12 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS filament_vendor = Overture @@ -1418,6 +1517,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #FFC800 filament_density = 1.05 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS filament_vendor = Bambu Lab @@ -1442,6 +1542,7 @@ extrusion_multiplier = 0.95 fan_below_layer_time = 30 filament_colour = #00FF40 filament_density = 1.24 +filament_flush_temp = 260 filament_max_volumetric_speed = 16 filament_type = PETG filament_vendor = Bambu Lab @@ -1468,6 +1569,7 @@ enable_volume_fan = 0 extrusion_multiplier = 0.95 filament_colour = #FFC800 filament_density = 1.05 +filament_flush_temp = 280 filament_max_volumetric_speed = 22 filament_type = ABS filament_vendor = HATCHBOX @@ -1492,6 +1594,7 @@ extrusion_multiplier = 0.95 fan_below_layer_time = 30 filament_colour = #00FF40 filament_density = 1.24 +filament_flush_temp = 260 filament_max_volumetric_speed = 16 filament_type = PETG filament_vendor = HATCHBOX @@ -1513,6 +1616,7 @@ inherits = *QIDI ABS Odorless* filament_max_volumetric_speed = 2 temperature = 260 chamber_temperature = 0 +filament_id = QD_0_1_14 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI ABS Rapido @X-Plus 4 0.2 nozzle] @@ -1520,6 +1624,7 @@ inherits = *QIDI ABS Rapido* filament_max_volumetric_speed = 2 temperature = 260 chamber_temperature = 0 +filament_id = QD_0_1_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI ABS Rapido Metal @X-Plus 4 0.2 nozzle] @@ -1528,6 +1633,7 @@ advance_pressure = 0.03 filament_max_volumetric_speed = 2 temperature = 260 chamber_temperature = 0 +filament_id = QD_0_1_13 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI ASA @X-Plus 4 0.2 nozzle] @@ -1535,23 +1641,27 @@ inherits = *QIDI ASA* filament_max_volumetric_speed = 2 temperature = 255 chamber_temperature = 0 +filament_id = QD_0_1_18 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI PETG-Tough @X-Plus 4 0.2 nozzle] inherits = *QIDI PETG-Tough* filament_max_volumetric_speed = 1 +filament_id = QD_0_1_40 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI PLA Rapido @X-Plus 4 0.2 nozzle] inherits = *QIDI PLA Rapido* filament_max_volumetric_speed = 2 temperature = 210 +filament_id = QD_0_1_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI PLA Rapido Matte @X-Plus 4 0.2 nozzle] inherits = *QIDI PLA Rapido Matte* filament_max_volumetric_speed = 2 temperature = 210 +filament_id = QD_0_1_2 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:QIDI PLA Rapido Metal @X-Plus 4 0.2 nozzle] @@ -1559,6 +1669,7 @@ inherits = *QIDI PLA Rapido Metal* advance_pressure = 0.038 filament_max_volumetric_speed = 2 temperature = 210 +filament_id = QD_0_1_3 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 # X-Plus 4 0.2 nozzle Generic filament preset @@ -1566,12 +1677,14 @@ compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0] inherits = *Generic ABS* filament_max_volumetric_speed = 2 temperature = 250 +filament_id = QD_0_0_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:Generic PETG @X-Plus 4 0.2 nozzle] inherits = *Generic PETG* filament_max_volumetric_speed = 1 first_layer_temperature = 245 +filament_id = QD_0_0_41 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:Generic PLA @X-Plus 4 0.2 nozzle] @@ -1579,6 +1692,7 @@ inherits = *Generic PLA* first_layer_temperature = 220 filament_max_volumetric_speed = 2 temperature = 220 +filament_id = QD_0_0_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.2 [filament:Generic PLA+ @X-Plus 4 0.2 nozzle] @@ -1676,6 +1790,7 @@ inherits = *QIDI ABS Odorless* advance_pressure = 0.03 chamber_minimal_temperature = 55 temperature = 260 +filament_id = QD_0_1_14 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI ABS Rapido @X-Plus 4 0.4 nozzle] @@ -1684,6 +1799,7 @@ advance_pressure = 0.03 chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 temperature = 260 +filament_id = QD_0_1_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI ABS Rapido Metal @X-Plus 4 0.4 nozzle] @@ -1692,6 +1808,7 @@ advance_pressure = 0.03 chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 temperature = 260 +filament_id = QD_0_1_13 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI ABS-GF @X-Plus 4 0.4 nozzle] @@ -1701,6 +1818,7 @@ chamber_minimal_temperature = 0 filament_max_volumetric_speed = 12 first_layer_temperature = 260 temperature = 270 +filament_id = QD_0_1_12 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI ASA @X-Plus 4 0.4 nozzle] @@ -1708,12 +1826,14 @@ inherits = *QIDI ASA* advance_pressure = 0.03 chamber_minimal_temperature = 55 temperature = 255 +filament_id = QD_0_1_18 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI ASA-Aero @X-Plus 4 0.4 nozzle] inherits = *QIDI ASA-Aero* chamber_minimal_temperature = 60 temperature = 260 +filament_id = QD_0_1_19 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PA12-CF @X-Plus 4 0.4 nozzle] @@ -1722,6 +1842,7 @@ advance_pressure = 0.035 filament_max_volumetric_speed = 8 first_layer_temperature = 280 temperature = 280 +filament_id = QD_0_1_25 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PAHT-CF @X-Plus 4 0.4 nozzle] @@ -1729,6 +1850,7 @@ inherits = *QIDI PAHT-CF* advance_pressure = 0.032 first_layer_temperature = 300 temperature = 300 +filament_id = QD_0_1_30 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PAHT-GF @X-Plus 4 0.4 nozzle] @@ -1736,12 +1858,14 @@ inherits = *QIDI PAHT-GF* advance_pressure = 0.027 first_layer_temperature = 300 temperature = 300 +filament_id = QD_0_1_31 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PC/ABS-FR @X-Plus 4 0.4 nozzle] inherits = *QIDI PC/ABS-FR* advance_pressure = 0.042 chamber_minimal_temperature = 55 +filament_id = QD_0_1_34 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PET-CF @X-Plus 4 0.4 nozzle] @@ -1750,12 +1874,14 @@ advance_pressure = 0.032 filament_max_volumetric_speed = 8 first_layer_temperature = 280 temperature = 280 +filament_id = QD_0_1_37 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PETG-Tough @X-Plus 4 0.4 nozzle] inherits = *QIDI PETG-Tough* advance_pressure = 0.056 filament_max_volumetric_speed = 13 +filament_id = QD_0_1_40 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PET-GF @X-Plus 4 0.4 nozzle] @@ -1764,6 +1890,7 @@ advance_pressure = 0.022 filament_max_volumetric_speed = 10 first_layer_temperature = 310 temperature = 310 +filament_id = QD_0_1_38 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PLA Rapido @X-Plus 4 0.4 nozzle] @@ -1771,6 +1898,7 @@ inherits = *QIDI PLA Rapido* advance_pressure = 0.034 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PLA Rapido Matte @X-Plus 4 0.4 nozzle] @@ -1778,6 +1906,7 @@ inherits = *QIDI PLA Rapido Matte* advance_pressure = 0.034 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_2 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PLA Rapido Metal @X-Plus 4 0.4 nozzle] @@ -1785,6 +1914,7 @@ inherits = *QIDI PLA Rapido Metal* advance_pressure = 0.038 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_3 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PLA Rapido Silk @X-Plus 4 0.4 nozzle] @@ -1792,6 +1922,7 @@ inherits = *QIDI PLA Rapido Silk* advance_pressure = 0.034 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_1_4 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PLA-CF @X-Plus 4 0.4 nozzle] @@ -1801,26 +1932,31 @@ extrusion_multiplier = 0.93 filament_max_volumetric_speed = 15 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_1_5 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI PPS-CF @X-Plus 4 0.4 nozzle] inherits = *QIDI PPS-CF* advance_pressure = 0.03 chamber_minimal_temperature = 60 +filament_id = QD_0_1_44 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI TPU 95A-HF @X-Plus 4 0.4 nozzle] inherits = *QIDI TPU 95A-HF* +filament_id = QD_0_1_50 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI UltraPA @X-Plus 4 0.4 nozzle] inherits = *QIDI UltraPA* filament_max_volumetric_speed = 4 +filament_id = QD_0_1_24 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI UltraPA-CF25 @X-Plus 4 0.4 nozzle] inherits = *QIDI UltraPA-CF25* advance_pressure = 0.026 +filament_id = QD_0_1_26 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:QIDI WOOD Rapido @X-Plus 4 0.4 nozzle] @@ -1828,6 +1964,22 @@ inherits = *QIDI WOOD Rapido* advance_pressure = 0.044 filament_max_volumetric_speed = 18 temperature = 210 +filament_id = QD_0_1_6 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 + +[filament:QIDI TPU-Aero @X-Plus 4 0.4 nozzle] +inherits = *QIDI TPU-Aero* +filament_id = QD_0_1_49 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 + +[filament:QIDI Support For PET/PA @X-Plus 4 0.4 nozzle] +inherits = *QIDI Support For PET/PA* +filament_id = QD_0_1_33 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 + +[filament:QIDI Support For PAHT @X-Plus 4 0.4 nozzle] +inherits = *QIDI Support For PAHT* +filament_id = QD_0_1_32 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 # X-Plus 4 0.4 nozzle Generic filament preset @@ -1835,12 +1987,14 @@ compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0] inherits = *Generic ABS* advance_pressure = 0.03 temperature = 250 +filament_id = QD_0_0_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:Generic PETG @X-Plus 4 0.4 nozzle] inherits = *Generic PETG* advance_pressure = 0.056 first_layer_temperature = 245 +filament_id = QD_0_0_41 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:Generic PLA @X-Plus 4 0.4 nozzle] @@ -1848,6 +2002,7 @@ inherits = *Generic PLA* advance_pressure = 0.034 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_0_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:Generic PLA+ @X-Plus 4 0.4 nozzle] @@ -1860,10 +2015,12 @@ compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0] [filament:Generic PLA Silk @X-Plus 4 0.4 nozzle] inherits = *Generic PLA Silk* advance_pressure = 0.032 +filament_id = QD_0_0_4 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:Generic TPU 95A @X-Plus 4 0.4 nozzle] inherits = *Generic TPU 95A* +filament_id = QD_0_0_50 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.4 [filament:Generic PC @X-Plus 4 0.4 nozzle] @@ -1957,6 +2114,7 @@ advance_pressure = 0.014 chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 temperature = 250 +filament_id = QD_0_1_14 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI ABS Rapido @X-Plus 4 0.6 nozzle] @@ -1965,6 +2123,7 @@ advance_pressure = 0.014 chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 temperature = 250 +filament_id = QD_0_1_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI ABS Rapido Metal @X-Plus 4 0.6 nozzle] @@ -1973,6 +2132,7 @@ advance_pressure = 0.016 chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 temperature = 250 +filament_id = QD_0_1_13 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI ABS-GF @X-Plus 4 0.6 nozzle] @@ -1981,6 +2141,7 @@ chamber_minimal_temperature = 0 filament_max_volumetric_speed = 12 first_layer_temperature = 260 temperature = 270 +filament_id = QD_0_1_12 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI ASA @X-Plus 4 0.6 nozzle] @@ -1989,6 +2150,7 @@ advance_pressure = 0.014 chamber_minimal_temperature = 55 filament_max_volumetric_speed = 13 temperature = 255 +filament_id = QD_0_1_18 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PA12-CF @X-Plus 4 0.6 nozzle] @@ -1997,6 +2159,7 @@ advance_pressure = 0.035 filament_max_volumetric_speed = 8 first_layer_temperature = 280 temperature = 280 +filament_id = QD_0_1_25 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PAHT-CF @X-Plus 4 0.6 nozzle] @@ -2004,6 +2167,7 @@ inherits = *QIDI PAHT-CF* advance_pressure = 0.032 first_layer_temperature = 300 temperature = 300 +filament_id = QD_0_1_30 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PAHT-GF @X-Plus 4 0.6 nozzle] @@ -2011,12 +2175,14 @@ inherits = *QIDI PAHT-GF* advance_pressure = 0.015 first_layer_temperature = 300 temperature = 300 +filament_id = QD_0_1_31 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PC/ABS-FR @X-Plus 4 0.6 nozzle] inherits = *QIDI PC/ABS-FR* advance_pressure = 0.031 chamber_minimal_temperature = 55 +filament_id = QD_0_1_34 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PET-CF @X-Plus 4 0.6 nozzle] @@ -2025,11 +2191,13 @@ advance_pressure = 0.025 filament_max_volumetric_speed = 8 first_layer_temperature = 280 temperature = 280 +filament_id = QD_0_1_37 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PETG-Tough @X-Plus 4 0.6 nozzle] inherits = *QIDI PETG-Tough* filament_max_volumetric_speed = 13 +filament_id = QD_0_1_40 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PET-GF @X-Plus 4 0.6 nozzle] @@ -2038,6 +2206,7 @@ advance_pressure = 0.014 filament_max_volumetric_speed = 10 first_layer_temperature = 310 temperature = 310 +filament_id = QD_0_1_38 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PLA Rapido @X-Plus 4 0.6 nozzle] @@ -2045,6 +2214,7 @@ inherits = *QIDI PLA Rapido* advance_pressure = 0.016 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PLA Rapido Matte @X-Plus 4 0.6 nozzle] @@ -2052,6 +2222,7 @@ inherits = *QIDI PLA Rapido Matte* advance_pressure = 0.016 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_2 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PLA Rapido Metal @X-Plus 4 0.6 nozzle] @@ -2059,6 +2230,7 @@ inherits = *QIDI PLA Rapido Metal* advance_pressure = 0.020 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_3 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PLA Rapido Silk @X-Plus 4 0.6 nozzle] @@ -2066,6 +2238,7 @@ inherits = *QIDI PLA Rapido Silk* advance_pressure = 0.021 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_1_4 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PLA-CF @X-Plus 4 0.6 nozzle] @@ -2075,26 +2248,31 @@ extrusion_multiplier = 0.93 filament_max_volumetric_speed = 15 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_1_5 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI PPS-CF @X-Plus 4 0.6 nozzle] inherits = *QIDI PPS-CF* advance_pressure = 0.021 chamber_minimal_temperature = 60 +filament_id = QD_0_1_44 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI TPU 95A-HF @X-Plus 4 0.6 nozzle] inherits = *QIDI TPU 95A-HF* +filament_id = QD_0_1_50 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI UltraPA @X-Plus 4 0.6 nozzle] inherits = *QIDI UltraPA* filament_max_volumetric_speed = 4 +filament_id = QD_0_1_24 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI UltraPA-CF25 @X-Plus 4 0.6 nozzle] inherits = *QIDI UltraPA-CF25* advance_pressure = 0.022 +filament_id = QD_0_1_26 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:QIDI WOOD Rapido @X-Plus 4 0.6 nozzle] @@ -2102,6 +2280,22 @@ inherits = *QIDI WOOD Rapido* advance_pressure = 0.024 filament_max_volumetric_speed = 18 temperature = 210 +filament_id = QD_0_1_6 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 + +[filament:QIDI TPU-Aero @X-Plus 4 0.6 nozzle] +inherits = *QIDI TPU-Aero* +filament_id = QD_0_1_49 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 + +[filament:QIDI Support For PET/PA @X-Plus 4 0.6 nozzle] +inherits = *QIDI Support For PET/PA* +filament_id = QD_0_1_33 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 + +[filament:QIDI Support For PAHT @X-Plus 4 0.6 nozzle] +inherits = *QIDI Support For PAHT* +filament_id = QD_0_1_32 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 # X-Plus 4 0.6 nozzle Generic filament preset @@ -2110,11 +2304,13 @@ inherits = *Generic ABS* advance_pressure = 0.014 filament_max_volumetric_speed = 24.5 temperature = 250 +filament_id = QD_0_0_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:Generic PETG @X-Plus 4 0.6 nozzle] inherits = *Generic PETG* first_layer_temperature = 245 +filament_id = QD_0_0_41 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:Generic PLA @X-Plus 4 0.6 nozzle] @@ -2122,6 +2318,7 @@ inherits = *Generic PLA* advance_pressure = 0.016 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_0_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:Generic PLA+ @X-Plus 4 0.6 nozzle] @@ -2134,10 +2331,12 @@ compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0] [filament:Generic PLA Silk @X-Plus 4 0.6 nozzle] inherits = *Generic PLA Silk* advance_pressure = 0.014 +filament_id = QD_0_0_4 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:Generic TPU 95A @X-Plus 4 0.6 nozzle] inherits = *Generic TPU 95A* +filament_id = QD_0_0_50 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.6 [filament:Generic PC @X-Plus 4 0.6 nozzle] @@ -2231,6 +2430,7 @@ chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 min_print_speed = 10 temperature = 250 +filament_id = QD_0_1_14 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI ABS Rapido @X-Plus 4 0.8 nozzle] @@ -2240,6 +2440,7 @@ chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 min_print_speed = 10 temperature = 250 +filament_id = QD_0_1_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI ABS Rapido Metal @X-Plus 4 0.8 nozzle] @@ -2249,6 +2450,7 @@ chamber_minimal_temperature = 55 filament_max_volumetric_speed = 24.5 min_print_speed = 10 temperature = 250 +filament_id = QD_0_1_13 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI ABS-GF @X-Plus 4 0.8 nozzle] @@ -2257,6 +2459,7 @@ chamber_minimal_temperature = 0 filament_max_volumetric_speed = 12 first_layer_temperature = 260 temperature = 270 +filament_id = QD_0_1_12 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI ASA @X-Plus 4 0.8 nozzle] @@ -2266,6 +2469,7 @@ chamber_minimal_temperature = 55 filament_max_volumetric_speed = 13 min_print_speed = 10 temperature = 255 +filament_id = QD_0_1_18 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PA12-CF @X-Plus 4 0.8 nozzle] @@ -2274,6 +2478,7 @@ advance_pressure = 0.035 filament_max_volumetric_speed = 8 first_layer_temperature = 280 temperature = 280 +filament_id = QD_0_1_25 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PAHT-CF @X-Plus 4 0.8 nozzle] @@ -2281,6 +2486,7 @@ inherits = *QIDI PAHT-CF* advance_pressure = 0.032 first_layer_temperature = 300 temperature = 300 +filament_id = QD_0_1_30 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PAHT-GF @X-Plus 4 0.8 nozzle] @@ -2288,12 +2494,14 @@ inherits = *QIDI PAHT-GF* advance_pressure = 0.01 first_layer_temperature = 300 temperature = 300 +filament_id = QD_0_1_31 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PC/ABS-FR @X-Plus 4 0.8 nozzle] inherits = *QIDI PC/ABS-FR* advance_pressure = 0.024 chamber_minimal_temperature = 55 +filament_id = QD_0_1_34 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PET-CF @X-Plus 4 0.8 nozzle] @@ -2302,11 +2510,13 @@ advance_pressure = 0.025 filament_max_volumetric_speed = 8 first_layer_temperature = 280 temperature = 280 +filament_id = QD_0_1_37 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PETG-Tough @X-Plus 4 0.8 nozzle] inherits = *QIDI PETG-Tough* filament_max_volumetric_speed = 13 +filament_id = QD_0_1_40 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PET-GF @X-Plus 4 0.8 nozzle] @@ -2315,6 +2525,7 @@ advance_pressure = 0.01 filament_max_volumetric_speed = 10 first_layer_temperature = 310 temperature = 310 +filament_id = QD_0_1_38 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PLA Rapido @X-Plus 4 0.8 nozzle] @@ -2322,6 +2533,7 @@ inherits = *QIDI PLA Rapido* advance_pressure = 0.008 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PLA Rapido Matte @X-Plus 4 0.8 nozzle] @@ -2329,6 +2541,7 @@ inherits = *QIDI PLA Rapido Matte* advance_pressure = 0.008 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_2 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PLA Rapido Metal @X-Plus 4 0.8 nozzle] @@ -2336,6 +2549,7 @@ inherits = *QIDI PLA Rapido Metal* advance_pressure = 0.01 filament_max_volumetric_speed = 24.5 temperature = 210 +filament_id = QD_0_1_3 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PLA-CF @X-Plus 4 0.8 nozzle] @@ -2345,27 +2559,32 @@ extrusion_multiplier = 0.93 filament_max_volumetric_speed = 18 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_1_5 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI PPS-CF @X-Plus 4 0.8 nozzle] inherits = *QIDI PPS-CF* advance_pressure = 0.008 chamber_minimal_temperature = 60 +filament_id = QD_0_1_44 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI TPU 95A-HF @X-Plus 4 0.8 nozzle] inherits = *QIDI TPU 95A-HF* temperature = 220 +filament_id = QD_0_1_50 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI UltraPA @X-Plus 4 0.8 nozzle] inherits = *QIDI UltraPA* filament_max_volumetric_speed = 4 +filament_id = QD_0_1_24 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI UltraPA-CF25 @X-Plus 4 0.8 nozzle] inherits = *QIDI UltraPA-CF25* advance_pressure = 0.02 +filament_id = QD_0_1_26 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:QIDI WOOD Rapido @X-Plus 4 0.8 nozzle] @@ -2373,6 +2592,17 @@ inherits = *QIDI WOOD Rapido* advance_pressure = 0.012 filament_max_volumetric_speed = 18 temperature = 210 +filament_id = QD_0_1_6 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 + +[filament:QIDI Support For PET/PA @X-Plus 4 0.8 nozzle] +inherits = *QIDI Support For PET/PA* +filament_id = QD_0_1_33 +compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 + +[filament:QIDI Support For PAHT @X-Plus 4 0.8 nozzle] +inherits = *QIDI Support For PAHT* +filament_id = QD_0_1_32 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 # X-Plus 4 0.8 nozzle Generic filament preset @@ -2381,11 +2611,13 @@ inherits = *Generic ABS* advance_pressure = 0.011 filament_max_volumetric_speed = 24.5 temperature = 250 +filament_id = QD_0_0_11 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:Generic PETG @X-Plus 4 0.8 nozzle] inherits = *Generic PETG* first_layer_temperature = 245 +filament_id = QD_0_0_41 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:Generic PLA @X-Plus 4 0.8 nozzle] @@ -2393,6 +2625,7 @@ inherits = *Generic PLA* advance_pressure = 0.008 first_layer_temperature = 220 temperature = 220 +filament_id = QD_0_0_1 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:Generic PLA+ @X-Plus 4 0.8 nozzle] @@ -2405,6 +2638,7 @@ compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0] [filament:Generic TPU 95A @X-Plus 4 0.8 nozzle] inherits = *Generic TPU 95A* temperature = 220 +filament_id = QD_0_0_50 compatible_printers_condition = printer_model=="X-Plus 4" and nozzle_diameter[0]==0.8 [filament:Generic PC @X-Plus 4 0.8 nozzle] @@ -2823,6 +3057,10 @@ filament_max_volumetric_speed = 18 temperature = 210 compatible_printers_condition = printer_model=="Q1 Pro" and nozzle_diameter[0]==0.4 +[filament:QIDI TPU-Aero @Q1 Pro 0.4 nozzle] +inherits = *QIDI TPU-Aero* +compatible_printers_condition = printer_model=="Q1 Pro" and nozzle_diameter[0]==0.4 + # Q1 Pro 0.4 nozzle Generic filament preset [filament:Generic ABS @Q1 Pro 0.4 nozzle] inherits = *Generic ABS* @@ -3094,6 +3332,10 @@ filament_max_volumetric_speed = 18 temperature = 210 compatible_printers_condition = printer_model=="Q1 Pro" and nozzle_diameter[0]==0.6 +[filament:QIDI TPU-Aero @Q1 Pro 0.6 nozzle] +inherits = *QIDI TPU-Aero* +compatible_printers_condition = printer_model=="Q1 Pro" and nozzle_diameter[0]==0.6 + # Q1 Pro 0.6 nozzle Generic filament preset [filament:Generic ABS @Q1 Pro 0.6 nozzle] inherits = *Generic ABS* @@ -3733,6 +3975,10 @@ compatible_printers_condition = printer_model=="X-MAX 3" and nozzle_diameter[0]= inherits = *QIDI WOOD Rapido* compatible_printers_condition = printer_model=="X-MAX 3" and nozzle_diameter[0]==0.4 +[filament:QIDI TPU-Aero @X-MAX 3 0.4 nozzle] +inherits = *QIDI TPU-Aero* +compatible_printers_condition = printer_model=="X-MAX 3" and nozzle_diameter[0]==0.4 + # X-MAX 3 0.4 nozzle Generic filament preset [filament:Generic ABS @X-MAX 3 0.4 nozzle] inherits = *Generic ABS* @@ -3938,6 +4184,12 @@ inherits = *QIDI WOOD Rapido* advance_pressure = 0.02 compatible_printers_condition = printer_model=="X-MAX 3" and nozzle_diameter[0]==0.6 +[filament:QIDI TPU-Aero @X-MAX 3 0.6 nozzle] +inherits = *QIDI TPU-Aero* +advance_pressure = 0.033 +extrusion_multiplier = 0.55 +compatible_printers_condition = printer_model=="X-MAX 3" and nozzle_diameter[0]==0.6 + # X-MAX 3 0.6 nozzle Generic filament preset [filament:Generic ABS @X-MAX 3 0.6 nozzle] inherits = *Generic ABS* @@ -4524,6 +4776,10 @@ compatible_printers_condition = printer_model=="X-Plus 3" and nozzle_diameter[0] inherits = *QIDI WOOD Rapido* compatible_printers_condition = printer_model=="X-Plus 3" and nozzle_diameter[0]==0.4 +[filament:QIDI TPU-Aero @X-Plus 3 0.4 nozzle] +inherits = *QIDI TPU-Aero* +compatible_printers_condition = printer_model=="X-Plus 3" and nozzle_diameter[0]==0.4 + # X-Plus 3 0.4 nozzle Generic filament preset [filament:Generic ABS @X-Plus 3 0.4 nozzle] inherits = *Generic ABS* @@ -4730,6 +4986,12 @@ inherits = *QIDI WOOD Rapido* advance_pressure = 0.02 compatible_printers_condition = printer_model=="X-Plus 3" and nozzle_diameter[0]==0.6 +[filament:QIDI TPU-Aero @X-Plus 3 0.6 nozzle] +inherits = *QIDI TPU-Aero* +advance_pressure = 0.033 +extrusion_multiplier = 0.55 +compatible_printers_condition = printer_model=="X-Plus 3" and nozzle_diameter[0]==0.6 + # X-Plus 3 0.6 nozzle Generic filament preset [filament:Generic ABS @X-Plus 3 0.6 nozzle] inherits = *Generic ABS* @@ -5333,6 +5595,10 @@ inherits = *QIDI WOOD Rapido* slowdown_below_layer_time = 8 compatible_printers_condition = printer_model=="X-smart 3" and nozzle_diameter[0]==0.4 +[filament:QIDI TPU-Aero @X-smart 3 0.4 nozzle] +inherits = *QIDI TPU-Aero* +compatible_printers_condition = printer_model=="X-smart 3" and nozzle_diameter[0]==0.4 + # X-smart 3 0.4 nozzle Generic filament preset [filament:Generic ABS @X-smart 3 0.4 nozzle] inherits = *Generic ABS* @@ -5560,6 +5826,12 @@ advance_pressure = 0.02 slowdown_below_layer_time = 8 compatible_printers_condition = printer_model=="X-smart 3" and nozzle_diameter[0]==0.6 +[filament:QIDI TPU-Aero @X-smart 3 0.6 nozzle] +inherits = *QIDI TPU-Aero* +advance_pressure = 0.033 +extrusion_multiplier = 0.55 +compatible_printers_condition = printer_model=="X-smart 3" and nozzle_diameter[0]==0.6 + # X-smart 3 0.6 nozzle Generic filament preset [filament:Generic ABS @X-smart 3 0.6 nozzle] inherits = *Generic ABS* @@ -5911,16 +6183,17 @@ bed_shape = 0x0,325x0,325x325,0x325 before_layer_gcode = between_objects_gcode = binary_gcode = 0 +box_temperature_control = 0 chamber_fan = 1 chamber_temperature_control = 0 color_change_gcode = M0 -cooling_tube_length = 5 -cooling_tube_retraction = 91.5 +cooling_tube_length = 0 +cooling_tube_retraction = 0 default_filament_profile = default_print_profile = deretract_speed = 0 end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 X0 Y0 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} -extra_loading_move = -2 +extra_loading_move = 0 extruder_colour = "" extruder_offset = 0x0 gcode_flavor = klipper @@ -5951,7 +6224,7 @@ max_print_height = 315 min_layer_height = 0.08 multimaterial_purging = 45 nozzle_diameter = 0.4 -parking_pos_retraction = 92 +parking_pos_retraction = 0 pause_print_gcode = M0 print_host = printer_model = @@ -5980,11 +6253,11 @@ start_gcode = PRINT_START\nG28\nM141 S[chamber_minimal_temperature]\nG0 Z50 F600 template_custom_gcode = thumbnails = thumbnails_format = PNG +toolchange_gcode = travel_lift_before_obstacle = 0 travel_max_lift = 0.4 travel_ramping_lift = 1 travel_slope = 3 -toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 use_volumetric_e = 0 @@ -5993,6 +6266,7 @@ wipe = 1 wipe_device = 0 wipe_distance = 2 z_offset = 0 +box_id = # X-Plus 4 preset [printer:*X-Plus 4*] @@ -6003,15 +6277,20 @@ auxiliary_fan = 1 bed_exclude_area = 0x0,0x0,0x302,0x305,35x302,35x302,0x302,0x0,0x0,293x0,293x20,305x20,305x0,293x0,0x0 bed_shape = 0x0,305x0,305x305,0x305 before_layer_gcode = TIMELAPSE_TAKE_FRAME +box_temperature_control = 1 chamber_temperature_control = 1 -end_gcode = M141 S0\nM104 S0\nM140 S0\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nG0 Y290 F12000\nG0 X90 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif} +end_gcode = DISABLE_BOX_HEATER\nM141 S0\nM140 S0\nDISABLE_ALL_SENSOR\nG1 E-3 F1800\nG0 Z{min(max_print_height, max_layer_z + 3)} F600\nUNLOAD_FILAMENT T=[current_extruder]\nG0 Y290 F12000\nG0 X90 F12000\n{if max_layer_z < max_print_height / 2}G1 Z{max_print_height / 2 + 10} F600{else}G1 Z{min(max_print_height, max_layer_z + 3)}{endif}\nM104 S0 layer_gcode = G92 E0\nSET_PRINT_STATS_INFO CURRENT_LAYER={layer_num + 1} machine_max_feedrate_z = 20 max_print_height = 280 retract_lift_below = 279 -start_gcode = PRINT_START BED=[first_layer_bed_temperature] HOTEND=[first_layer_temperature] CHAMBER=[chamber_minimal_temperature]\nSET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nM83\nM140 S[first_layer_bed_temperature]\nM104 S[first_layer_temperature]\nM141 S[chamber_minimal_temperature]\nG4 P3000\nT[initial_tool]\n{position[0] = max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0)}\n{position[1] = max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85), 0)}\n{position[2] = 0.5 * first_layer_height * nozzle_diameter[0]}\n{if position[0] <= 35 and position[1] >= 217} {position[1] = 217} {endif}\n{if position[0] >= 208 and position[1] <= 20} {position[0] = 208} {endif}\nG0 X{position[0]} Y{position[1]} Z5 F6000\nG0 Z[first_layer_height] F600\nG1 E3 F1800\nG1 X{position[0] + 85} E{85 * position[2]} F3000\nG1 Y{position[1] + 2} E{2 * position[2]}\nG1 X{position[0]} E{85 * position[2]}\nG1 Y{position[1] + 85} E{83 * position[2]}\nG1 X{position[0] + 2} E{2 * position[2]}\nG1 Y{position[1] + 3} E{82 * position[2]}\nG1 X{position[0] + 3} Z0\nG1 X{position[0] + 6}\nG1 Z1 F600\nSET_PRINT_STATS_INFO CURRENT_LAYER=1\n +single_extruder_multi_material = 1 +start_gcode = PRINT_START BED=[first_layer_bed_temperature] HOTEND=[first_layer_temperature] CHAMBER=[chamber_minimal_temperature] EXTRUDER=[initial_extruder]\nSET_PRINT_STATS_INFO TOTAL_LAYER=[total_layer_count]\nM83\nM140 S[first_layer_bed_temperature]\nM104 S[first_layer_temperature]\nM141 S[chamber_minimal_temperature]\nG4 P3000\nT[initial_tool]\n{position[0] = max((min(print_bed_max[0], first_layer_print_min[0] + 80) - 85), 0)}\n{position[1] = max((min(print_bed_max[1], first_layer_print_min[1] + 80) - 85), 0)}\n{position[2] = 0.5 * first_layer_height * nozzle_diameter[0]}\n{if position[0] <= 35 and position[1] >= 217} {position[1] = 217} {endif}\n{if position[0] >= 208 and position[1] <= 20} {position[0] = 208} {endif}\nG0 X{position[0]} Y{position[1]} Z5 F6000\nG0 Z[first_layer_height] F600\nG1 E3 F1800\nG1 X{position[0] + 85} E{85 * position[2]} F3000\nG1 Y{position[1] + 2} E{2 * position[2]}\nG1 X{position[0]} E{85 * position[2]}\nG1 Y{position[1] + 85} E{83 * position[2]}\nG1 X{position[0] + 2} E{2 * position[2]}\nG1 Y{position[1] + 3} E{82 * position[2]}\nG1 X{position[0] + 3} Z0\nG1 X{position[0] + 6}\nG1 Z1 F600\nSET_PRINT_STATS_INFO CURRENT_LAYER=1\n thumbnails = 272x272/PNG, 96x96/PNG +toolchange_gcode = {if max_layer_z < 12}\nG1 Z15 F1200\n{else}\nG1 Z{max_layer_z + 3.0} F1200\n{endif}\nTOOL_CHANGE_START F=[current_extruder] T=[next_extruder]\nDISABLE_ALL_SENSOR\nG1 E-5 F611\nCUT_FILAMENT T=[current_extruder]\nMOVE_TO_TRASH\n{if filament_flush_temp[current_extruder] >= filament_flush_temp[next_extruder]}\nM104 S{filament_flush_temp[current_extruder]}\n{else}\nM104 S{filament_flush_temp[next_extruder]}\n{endif}\nM106 S0\nM106 P2 S0\nUNLOAD_T[current_extruder]\nG92 E0\nM83\nG1 E2 F50\nT[next_extruder]\n{if filament_flush_temp[current_extruder] >= filament_flush_temp[next_extruder]}\nSET_HEATER_TEMPERATURE HEATER=extruder TARGET={filament_flush_temp[current_extruder]} WAIT=1\n{else}\nSET_HEATER_TEMPERATURE HEATER=extruder TARGET={filament_flush_temp[next_extruder]} WAIT=1\n{endif}\nM400\nM106 S60\n; FLUSH_START\nG1 E{65.5 * 0.58} F611\nG1 E{65.5 * 0.02} F50\nG1 E{65.5 * 0.18} F611\nG1 E{65.5 * 0.02} F50\nG1 E{65.5 * 0.18} F611\nG1 E{65.5 * 0.02} F50\nG1 E-2 F1800\n; FLUSH_END\nM400\nM106 S255\nG91\nG1 X-5 F60\nG1 X5 F60\nG90\nCLEAR_FLUSH\nM400\nM106 S60\n; FLUSH_START\nG1 E2 F300\nG1 E{75 * 0.58} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E-2 F1800\n; FLUSH_END\nM400\nM106 S255\nG91\nG1 X-5 F60\nG1 X5 F60\nG90\nCLEAR_FLUSH\nM400\nM106 S60\n; FLUSH_START\nG1 E2 F300\nG1 E{75 * 0.58} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E{75 * 0.18} F611\nG1 E{75 * 0.02} F50\nG1 E-2 F1800\n; FLUSH_END\nM104 S{temperature[next_extruder]}\nM400\nM106 S255\nG91\nG1 X-5 F60\nG1 X5 F60\nG90\nM109 S{temperature[next_extruder]}\nG92 E0\nM400\nCLEAR_FLUSH\nCLEAR_OOZE\nM400\n{if layer_num > disable_fan_first_layers[next_extruder]}\nM106 S{max_fan_speed[next_extruder]}\n{if seal_print}\nM106 P2 S{enable_auxiliary_fan[next_extruder]}\n{else}\nM106 P2 S{enable_auxiliary_fan_unseal[next_extruder]}\n{endif}\n{else}\nM106 S0\nM106 P2 S0\n{endif}\nTOOL_CHANGE_END\nG1 Y305 F9000\nENABLE_ALL_SENSOR\n wipe_device = 1 +box_id = 0 +nozzle_volume = 122 [printer:X-Plus 4 0.2 nozzle] inherits = *X-Plus 4* diff --git a/resources/profiles/QIDITechnology/X-Plus 4_bed.STL b/resources/profiles/QIDITechnology/X-Plus 4_bed.STL index be0ce9b..706816a 100644 Binary files a/resources/profiles/QIDITechnology/X-Plus 4_bed.STL and b/resources/profiles/QIDITechnology/X-Plus 4_bed.STL differ diff --git a/resources/web/guide/filament_table.html b/resources/web/guide/filament_table.html index e576f4e..a640a49 100644 --- a/resources/web/guide/filament_table.html +++ b/resources/web/guide/filament_table.html @@ -43,7 +43,7 @@ border: none; } - tr:nth-child(2) td, tr:nth-child(3) td, tr:nth-child(4) td, tr:nth-child(5) td, tr:nth-child(6) td, tr:nth-child(9) td, tr:nth-child(13) td, tr:nth-child(14) td, tr:nth-child(15) td, tr:nth-child(16) td, tr:nth-child(17) td, tr:nth-child(18) td, tr:nth-child(19) td { + tr:nth-child(2) td, tr:nth-child(3) td, tr:nth-child(4) td, tr:nth-child(5) td, tr:nth-child(6) td, tr:nth-child(9) td, tr:nth-child(13) td, tr:nth-child(14) td, tr:nth-child(15) td, tr:nth-child(16) td, tr:nth-child(17) td, tr:nth-child(18) td, tr:nth-child(19),tr:nth-child(20) td { height: 20px; } @@ -146,6 +146,9 @@ tr:nth-child(18),tr:nth-child(18) td:nth-child(1) { border-bottom: 1px solid #ccc; } + tr:nth-child(19),tr:nth-child(19) td:nth-child(1) { + border-bottom: 1px solid #ccc; + } .unselected { @@ -263,6 +266,9 @@ + + + @@ -296,6 +302,9 @@ UltraPA UltraPA-CF25 WOOD Rapido + TPU-Aero + Support For PET/PA + Support For PAHT @@ -354,6 +363,8 @@ "Print speed": "Print speed", "Post processing": "Post processing", "Anneal": "Anneal", + "QIDI BOX settings": "QIDI BOX settings", + "Is QIDI BOX applicable": "Is QIDI BOX applicable", "Compare filaments": "Compare filaments:" }, zh_CN: { @@ -376,9 +387,11 @@ "Sealed box": "是否封箱", "Print settings": "打印设置", "Nozzle temperature": "喷嘴温度", - "Print speed": "打印速度d", + "Print speed": "打印速度", "Post processing": "打印后处理", "Anneal": "退火", + "QIDI BOX settings": "QIDI BOX设置", + "Is QIDI BOX applicable": "是否适用QIDI BOX", "Compare filaments": "比较耗材:" }, fr: { @@ -404,6 +417,8 @@ "Print speed": "Vitesse d'impression", "Post processing": "Post - traitement", "Anneal": "Anneal", + "QIDI BOX settings": "Paramètres QIDI BOX", + "Is QIDI BOX applicable": "Est-ce que QIDI BOX est applicable", "Compare filaments": "Comparer les filaments:" }, cs: { @@ -429,6 +444,8 @@ "Print speed": "Rychlost tisku", "Post processing": "Pozpracování", "Anneal": "Rozšíření", + "QIDI BOX settings": "Nastavení QIDI BOX", + "Is QIDI BOX applicable": "Je použitelná QIDI BOX", "Compare filaments": "Porovnat vlákna:" }, de: { @@ -454,6 +471,8 @@ "Print speed": "Druckgeschwindigkeit", "Post processing": "Nachbearbeitung", "Anneal": "Anneal", + "QIDI BOX settings": "QIDI BOX-Einstellungen", + "Is QIDI BOX applicable": "Ist QIDI BOX anwendbar", "Compare filaments": "Filamente vergleichen:" }, es: { @@ -479,6 +498,8 @@ "Print speed": "Velocidad de impresión", "Post processing": "Reprocesamiento", "Anneal": "Anneal", + "QIDI BOX settings": "Configuración de QIDI BOX", + "Is QIDI BOX applicable": "Es aplicable QIDI BOX", "Compare filaments": "Filamentos comparativos:" }, hu: { @@ -504,6 +525,8 @@ "Print speed": "Nyomtatási sebesség", "Post processing": "Utófeldolgozás", "Anneal": "Melléklet", + "QIDI BOX settings": "QIDI BOX beállítások", + "Is QIDI BOX applicable": "QIDI BOX alkalmazandó", "Compare filaments": "Szálak összehasonlítása:" }, it: { @@ -529,6 +552,8 @@ "Print speed": "Velocità di stampa", "Post processing": "Post-elaborazione", "Anneal": "Allegato", + "QIDI BOX settings": "Impostazioni QIDI BOX", + "Is QIDI BOX applicable": "È applicabile QIDI BOX", "Compare filaments": "Confronta filamenti:" }, ja: { @@ -554,6 +579,8 @@ "Print speed": "印刷速度", "Post processing": "後処理", "Anneal": "Anneal", + "QIDI BOX settings": "QIDI BOX設定", + "Is QIDI BOX applicable": "QIDIボックス適用か", "Compare filaments": "ひかくフィラメント:" }, ko: { @@ -579,6 +606,8 @@ "Print speed": "인쇄 속도", "Post processing": "후처리", "Anneal": "Anneal", + "QIDI BOX settings": "QIDI BOX 설정", + "Is QIDI BOX applicable": "QIDI BOX 적용 가능합니까", "Compare filaments": "비교적 긴 실:" }, nl: { @@ -604,6 +633,8 @@ "Print speed": "Afdruksnelheid", "Post processing": "Postverwerking", "Anneal": "Anneal", + "QIDI BOX settings": "QIDI BOX instellingen", + "Is QIDI BOX applicable": "Is QIDI BOX van toepassing", "Compare filaments": "Filamenten vergelijken:" }, pl: { @@ -629,6 +660,8 @@ "Print speed": "Szybkość drukowania", "Post processing": "Przetwarzanie po przetwarzaniu", "Anneal": "Wyżej", + "QIDI BOX settings": "Ustawienia QIDI BOX", + "Is QIDI BOX applicable": "Czy stosuje się QIDI BOX", "Compare filaments": "Porównaj filamenty:" }, ru: { @@ -654,6 +687,8 @@ "Print speed": "Velocidade de impressão", "Post processing": "Pós-processamento", "Anneal": "Anexo", + "QIDI BOX settings": "Настройки QIDI BOX", + "Is QIDI BOX applicable": "применяется ли QIDI BOX", "Compare filaments": "Более длинный шелк:" }, sv: { @@ -679,6 +714,8 @@ "Print speed": "Utskriftshastighet", "Post processing": "Efterbehandling", "Anneal": "Bilaga", + "QIDI BOX settings": "QIDI BOX-inställningar", + "Is QIDI BOX applicable": "Är QIDI BOX tillämplig", "Compare filaments": "Jämför glödtrådar:" }, tr: { @@ -704,6 +741,8 @@ "Print speed": "Bastırma hızı", "Post processing": "İşlemi", "Anneal": "Annealfrance. kgm", + "QIDI BOX settings": "QIDI BOX ayarları", + "Is QIDI BOX applicable": "QIDI BOX uygulanabilir mi", "Compare filaments": "Kıyafetleri karşılaştır:" }, uk: { @@ -729,6 +768,8 @@ "Print speed": "Швидкість друку", "Post processing": "Посля обробки", "Anneal": "Анналstar name", + "QIDI BOX settings": "Налаштування QIDI BOX", + "Is QIDI BOX applicable": "Чи застосовується QIDI BOX", "Compare filaments": "Порівняти гілки:" }, pt: { @@ -754,6 +795,8 @@ "Print speed": "Velocidade de impressão", "Post processing": "Pós-processamento", "Anneal": "Anexo", + "QIDI BOX settings": "QIDI BOX settings", + "Is QIDI BOX applicable": "É aplicável o QIDI BOX", "Compare filaments": "Comparar filamentos:" }, @@ -798,6 +841,9 @@ document.write(''+ createProgressBar(50,"#0784FF")+ '');//ultra pa document.write(''+ createProgressBar(50,"#0784FF")+ '');//ultra pa-cf25 document.write(''+ createProgressBar(25,"#0784FF")+ '');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Corrosion resistance*/ @@ -827,6 +873,9 @@ document.write(''+ createProgressBar(50,"#5cb85c")+ '');//ultra pa document.write('/');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Creep resistance*/ @@ -856,6 +905,9 @@ document.write(''+ createProgressBar(50,"#CC6B36")+ '');//ultra pa document.write('/');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*HDT 0.45*/ @@ -885,6 +937,9 @@ document.write('77.8℃');//ultra pa document.write('96.1℃');//ultra pa-cf25 document.write('57℃');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*HDT 1.80*/ @@ -914,6 +969,9 @@ document.write('77.8℃');//ultra pa document.write('83℃');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Tensile strength*/ @@ -943,6 +1001,9 @@ document.write('86.15 ± 0.56 MPa
'+ createProgressBar(86.15/150*100,"#CCB70B")+ '');//ultra pa document.write('109.68 ± 1.84 MPa
'+ createProgressBar(109.68/150*100,"#CCB70B")+ '');//ultra pa-cf25 document.write('26.5 ± 1.5 MPa
'+ createProgressBar(26.5/150*100,"#CCB70B")+ '');//wood rapido + document.write('6.81±0.11 MPa
'+ createProgressBar(6.81/150*100,"#CCB70B")+ '');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Tensile modulus*/ @@ -972,6 +1033,9 @@ document.write('3609.22 ± 153.31 MPa
'+ createProgressBar(3609.22/10000*100,"#CC0003")+ '');//ultra pa document.write('8996.26 ± 232.21 MPa
'+ createProgressBar(8996.26/10000*100,"#CC0003")+ '');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Elongation at break*/ @@ -1001,6 +1065,9 @@ document.write('11.68 ± 3.36%');//ultra pa document.write('2.18 ± 0.14%');//ultra pa-cf25 document.write('9 ± 1%');//wood rapido + document.write('576.27±8.48%');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Flexural strength*/ @@ -1030,6 +1097,9 @@ document.write('121.47 ± 3.14 MPa
'+ createProgressBar(121.47/200*100,"#16417C")+ '');//ultra pa document.write('176.24 ± 3.51 MPa
'+ createProgressBar(176.24/200*100,"#16417C")+ '');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Flexural modulus*/ @@ -1059,6 +1129,9 @@ document.write('3314.03 ± 181.88 MPa
'+ createProgressBar(3314.03/10000*100,"#EA3FF7")+ '');//ultra pa document.write('8487.47 ± 246.46 MPa
'+ createProgressBar(8487.47/10000*100,"#EA3FF7")+ '');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Notch impact strength*/ @@ -1088,6 +1161,9 @@ document.write('5.78 ± 0.30KJ/㎡
'+ createProgressBar(5.78/30*100,"#F77089")+ '');//ultra pa document.write('12.04 ± 0.94KJ/㎡
'+ createProgressBar(12.04/30*100,"#F77089")+ '');//ultra pa-cf25 document.write('3.5 ± 0.5KJ/㎡
'+ createProgressBar(3.5/30*100,"#F77089")+ '');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); /*Drying*/ @@ -1117,6 +1193,9 @@ document.write('' + getTranslation('Need to dry', lang) + '');//ultra pa document.write('' + getTranslation('Need to dry', lang) + '');//ultra pa-cf25 document.write('' + getTranslation('Recommended drying', lang) + '');//wood rapido + document.write('' + getTranslation('Need to dry', lang) + '');//tpu aero + document.write('' + getTranslation('Need to dry', lang) + '');//support for pet/pa + document.write('' + getTranslation('Need to dry', lang) + '');//support for paht document.write(''); /*Dry conditions*/ @@ -1146,6 +1225,9 @@ document.write('100-120℃ 4-6h');//ultra pa document.write('80-100℃ 4-6h');//ultra pa-cf25 document.write('/');//wood rapido + document.write('70-80℃ 4-6h');//tpu aero + document.write('80-100℃ 4-6h');//support for pet/pa + document.write('80-100℃ 4-6h');//support for paht document.write(''); /*Suitable hot bed temperature*/ @@ -1175,6 +1257,9 @@ document.write('70-80℃');//ultra pa document.write('70-80℃');//ultra pa-cf25 document.write('60℃');//wood rapido + document.write('30-45℃');//tpu aero + document.write('70-90℃');//support for pet/pa + document.write('80-90℃');//support for paht document.write(''); /*Sealed box*/ @@ -1204,6 +1289,9 @@ document.write('×');//ultra pa document.write('×');//ultra pa-cf25 document.write('×');//wood rapido + document.write('×');//tpu aero + document.write('×');//support for pet/pa + document.write('×');//support for paht document.write(''); /*Print settings*/ @@ -1233,6 +1321,9 @@ document.write('280-300℃');//ultra pa document.write('300-340℃');//ultra pa-cf25 document.write('190-220℃');//wood rapido + document.write('230-270℃');//tpu aero + document.write('260-280℃');//support for pet/pa + document.write('270-280℃');//support for paht document.write(''); /*Print speed*/ @@ -1262,6 +1353,9 @@ document.write('<90mm/s');//ultra pa document.write('<120mm/s');//ultra pa-cf25 document.write('<200mm/s');//wood rapido + document.write('<100mm/s');//tpu aero + document.write('<120mm/s');//support for pet/pa + document.write('<120mm/s');//support for paht document.write(''); /*Post processing*/ @@ -1291,9 +1385,43 @@ document.write('/');//ultra pa document.write('80-100℃');//ultra pa-cf25 document.write('/');//wood rapido + document.write('/');//tpu aero + document.write('/');//support for pet/pa + document.write('/');//support for paht document.write(''); + /*Is QIDI BOX applicable*/ + document.write(''); + document.write('' + getTranslation('QIDI BOX settings', lang) + ''); + document.write('' + getTranslation('Is QIDI BOX applicable', lang) + ''); + document.write('√');//pla + document.write('√');//pla matte + document.write('√');//pla metal + document.write('√');//pla silk + document.write('√');//pla cf + document.write('√');//abs + document.write('√');//abs odorless + document.write('√');//abs metal + document.write('√');//abs gf + document.write('√');//asa + document.write('√');//asa aero + document.write('√');//pa12 cf + document.write('√');//paht cf + document.write('√');//paht gf + document.write('√');//pc abs fr + document.write('√');//pet cf + document.write('√');//pet gf + document.write('√');//petg + document.write('√');//pps-cf + document.write('×');//tpu + document.write('√');//ultra pa + document.write('√');//ultra pa-cf25 + document.write('√');//wood rapido + document.write('×');//tpu aero + document.write('√');//support for pet/pa + document.write('√');//support for paht + document.write(''); diff --git a/src/libseqarrange/src/seq_preprocess.cpp b/src/libseqarrange/src/seq_preprocess.cpp index 1512b1c..84298d2 100644 --- a/src/libseqarrange/src/seq_preprocess.cpp +++ b/src/libseqarrange/src/seq_preprocess.cpp @@ -458,6 +458,14 @@ Slic3r::Polygon scaleUp_PolygonForSlicer(coord_t scale_factor, const Polygon &po return poly; } +Slic3r::Polygon truncate_PolygonAsSeenBySequentialSolver(coord_t scale_factor, const Slic3r::Polygon &polygon) +{ + Slic3r::Polygon scale_down_polygon = scaleDown_PolygonForSequentialSolver(scale_factor, polygon); + Slic3r::Polygon scale_up_polygon = scaleUp_PolygonForSlicer(scale_factor, scale_down_polygon); + + return scale_up_polygon; +} + void ground_PolygonByBoundingBox(Slic3r::Polygon &polygon) { @@ -599,9 +607,30 @@ void decimate_PolygonForSequentialSolver(double DP_tolerance, { if (extra_safety) { - grow_PolygonForContainedness(center_x, center_y, decimated_polygon); + Slic3r::Polygon prefinal_polygon = decimated_polygon; + + while (true) + { + grow_PolygonForContainedness(center_x, center_y, decimated_polygon); + Slic3r::Polygon truncated_polygon = truncate_PolygonAsSeenBySequentialSolver(SEQ_SLICER_SCALE_FACTOR, decimated_polygon); + + bool trunc_contains = true; + for (unsigned int i = 0; i < prefinal_polygon.points.size(); ++i) + { + if (!Slic3r::contains(truncated_polygon, prefinal_polygon.points[i], false)) + { + trunc_contains = false; + break; + } + } + + if (trunc_contains) + { + return; + } + } } - break; + return; } } } diff --git a/src/libseqarrange/src/seq_preprocess.hpp b/src/libseqarrange/src/seq_preprocess.hpp index aeb2bcf..64ac326 100644 --- a/src/libseqarrange/src/seq_preprocess.hpp +++ b/src/libseqarrange/src/seq_preprocess.hpp @@ -95,8 +95,10 @@ Slic3r::Polygon scaleUp_PolygonForSlicer(const Slic3r::Polygon &polygon); Slic3r::Polygon scaleUp_PolygonForSlicer(coord_t scale_factor, const Slic3r::Polygon &polygon); Slic3r::Polygon scaleUp_PolygonForSlicer(const Slic3r::Polygon &polygon, double x_pos, double y_pos); -Slic3r::Polygon scaleUp_PolygonForSlicer(coord_t scale_factor, const Slic3r::Polygon &polygon, double x_pos, double y_pos); - +Slic3r::Polygon scaleUp_PolygonForSlicer(coord_t scale_factor, const Slic3r::Polygon &polygon, double x_pos, double y_pos); + +Slic3r::Polygon truncate_PolygonAsSeenBySequentialSolver(coord_t scale_factor, const Slic3r::Polygon &polygon); + void ground_PolygonByBoundingBox(Slic3r::Polygon &polygon); void ground_PolygonByFirstPoint(Slic3r::Polygon &polygon); diff --git a/src/libseqarrange/src/seq_sequential.cpp b/src/libseqarrange/src/seq_sequential.cpp index c553a1e..f84bf4c 100644 --- a/src/libseqarrange/src/seq_sequential.cpp +++ b/src/libseqarrange/src/seq_sequential.cpp @@ -511,7 +511,7 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver } #endif //Solver.add(dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); - Solver.add((dec_vars_T[undecided[i]] < 0 || dec_vars_T[next_i] < 0) || dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i]); + Solver.add((dec_vars_T[undecided[i]] < 0 || dec_vars_T[next_i] < 0) || (dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i])); } /* Undecided --> missing */ else @@ -590,6 +590,167 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver #endif } +void assume_ConsequentialTemporalLepoxAgainstFixed(z3::solver &Solver, + z3::context &Context, + const z3::expr_vector &dec_vars_T, + std::vector &dec_values_T, + const std::vector &fixed, + const std::vector &undecided, + int temporal_spread, + const std::vector &SEQ_UNUSED(polygons), + const std::vector &lepox_to_next, + bool trans_bed_lepox, + z3::expr_vector &lepox_assumptions) +{ +#ifdef DEBUG +{ +if (trans_bed_lepox) +{ +printf("Trans bed lepox.\n"); +} +printf("Undecided:\n"); +for (unsigned int i = 0; i < undecided.size(); ++i) +{ +printf("%d", undecided[i]); +if (lepox_to_next[undecided[i]]) +{ +printf("-> "); +} +printf(" "); +} +printf("\n"); + +printf("Fixed:\n"); +for (unsigned int i = 0; i < fixed.size(); ++i) +{ +printf("%d", fixed[i]); +if (lepox_to_next[fixed[i]]) +{ +printf("-> "); +} +printf(" "); +} +printf("\n"); +} +#endif + +/* Bed --> Bed */ +if (trans_bed_lepox) +{ +if (is_undecided(0, undecided)) +{ +#ifdef DEBUG +{ +printf("Bed --> Bed: undecided 0 first\n"); +} +#endif +for (unsigned int j = 1; j < undecided.size(); ++j) +{ +lepox_assumptions.push_back(dec_vars_T[undecided[j]] < 0 || dec_vars_T[0] + temporal_spread < dec_vars_T[undecided[j]]); +} +} +else if (is_fixed(0, fixed)) +{ +#ifdef DEBUG +{ +printf("Bed --> Bed: fixed 0 still first\n"); +} +#endif +for (unsigned int j = 0; j < undecided.size(); ++j) +{ +lepox_assumptions.push_back(dec_vars_T[undecided[j]] < 0 || Context.real_val(dec_values_T[0].numerator, dec_values_T[0].denominator) + temporal_spread < dec_vars_T[undecided[j]]); +} +} +else +{ +// should not happen +assert(false); +} +} + +for (unsigned int i = 0; i < undecided.size(); ++i) +{ +if (lepox_to_next[undecided[i]]) +{ +int next_i = undecided[i] + 1; + +/* Undecided --> Undecided */ +if (is_undecided(next_i, undecided)) +{ +#ifdef DEBUG +{ +printf("Undecided --> Undecided: %d --> %d standard\n", undecided[i], next_i); +} +#endif +lepox_assumptions.push_back((dec_vars_T[undecided[i]] < 0 || dec_vars_T[next_i] < 0) || (dec_vars_T[undecided[i]] + temporal_spread < dec_vars_T[next_i] && dec_vars_T[undecided[i]] + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i])); +} +/* Undecided --> missing */ +else +{ +#ifdef DEBUG +{ +printf("Undecided --> Undecided: %d missing\n", undecided[i]); +} +#endif +for (unsigned int j = 0; j < undecided.size(); ++j) +{ +if (i != j) +{ +lepox_assumptions.push_back(dec_vars_T[undecided[j]] < 0 || dec_vars_T[undecided[j]] + temporal_spread < dec_vars_T[undecided[i]]); +} +} +for (unsigned int j = 0; j < fixed.size(); ++j) +{ +lepox_assumptions.push_back(dec_vars_T[undecided[i]] < 0 || Context.real_val(dec_values_T[fixed[j]].numerator, dec_values_T[fixed[j]].denominator) + temporal_spread < dec_vars_T[undecided[i]]); +} +} +} +} +for (unsigned int i = 0; i < fixed.size(); ++i) +{ +if (lepox_to_next[fixed[i]]) +{ +int next_i = fixed[i] + 1; + +/* Fixed --> Undecided */ +if (is_undecided(next_i, undecided)) +{ +#ifdef DEBUG +{ +printf("Fixed --> Undecided: %d --> %d standard\n", fixed[i], next_i); +} +#endif +lepox_assumptions.push_back(dec_vars_T[next_i] < 0 || ( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread < dec_vars_T[next_i] + && Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) + temporal_spread + temporal_spread / 2 > dec_vars_T[next_i])); +} +/* Fixed --> Fixed */ +else if (is_fixed(next_i, fixed)) +{ +#ifdef DEBUG +{ +printf("All out of the link: %d --> %d\n", fixed[i], next_i); +} +#endif +for (unsigned int j = 0; j < undecided.size(); ++j) +{ +lepox_assumptions.push_back(dec_vars_T[undecided[j]] < 0 || ( Context.real_val(dec_values_T[fixed[i]].numerator, dec_values_T[fixed[i]].denominator) > dec_vars_T[undecided[j]] + temporal_spread + || Context.real_val(dec_values_T[next_i].numerator, dec_values_T[next_i].denominator) + temporal_spread < dec_vars_T[undecided[j]])); +} +} +} +} + +#ifdef DEBUG +{ +printf("Origo\n"); +for (unsigned int i = 0; i < fixed.size(); ++i) +{ +printf("%.3f\n", dec_values_T[fixed[i]].as_double()); +} +} +#endif +} + /*----------------------------------------------------------------*/ @@ -11183,17 +11344,6 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So undecided, solver_configuration.temporal_spread, polygons); - - introduce_ConsequentialTemporalLepoxAgainstFixed(z_solver, - z_context, - local_dec_vars_T, - local_values_T, - decided_polygons, - undecided, - solver_configuration.temporal_spread, - polygons, - lepox_to_next, - trans_bed_lepox); std::vector missing; std::vector remaining_local; @@ -11201,8 +11351,20 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So while(object_group_size > 0) { z3::expr_vector presence_assumptions(z_context); + assume_ConsequentialObjectPresence(z_context, local_dec_vars_T, undecided, missing, presence_assumptions); - + assume_ConsequentialTemporalLepoxAgainstFixed(z_solver, + z_context, + local_dec_vars_T, + local_values_T, + decided_polygons, + undecided, + solver_configuration.temporal_spread, + polygons, + lepox_to_next, + trans_bed_lepox, + presence_assumptions); + #ifdef DEBUG { printf("Undecided\n"); @@ -11360,9 +11522,9 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So int progress_total_object_phases, std::function progress_callback) { - std::vector undecided; - + std::vector undecided; decided_polygons.clear(); + remaining_polygons.clear(); dec_values_X.resize(solvable_objects.size()); @@ -11408,9 +11570,10 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So unreachable_polygons.push_back(solvable_object.unreachable_polygons); lepox_to_next.push_back(solvable_object.lepox_to_next); } - - for (unsigned int curr_polygon = 0; curr_polygon < solvable_objects.size(); /* nothing */) - { + + unsigned int curr_polygon; + for (curr_polygon = 0; curr_polygon < solvable_objects.size(); /* nothing */) + { bool optimized = false; z3::set_param("timeout", solver_configuration.optimization_timeout.c_str()); @@ -11478,24 +11641,24 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So undecided, solver_configuration.temporal_spread, polygons); - - introduce_ConsequentialTemporalLepoxAgainstFixed(z_solver, - z_context, - local_dec_vars_T, - local_values_T, - decided_polygons, - undecided, - solver_configuration.temporal_spread, - polygons, - lepox_to_next, - trans_bed_lepox); - std::vector missing; - std::vector remaining_local; + + std::vector remaining_local; while(object_group_size > 0) - { + { z3::expr_vector presence_assumptions(z_context); - assume_ConsequentialObjectPresence(z_context, local_dec_vars_T, undecided, missing, presence_assumptions); + assume_ConsequentialObjectPresence(z_context, local_dec_vars_T, undecided, remaining_local, presence_assumptions); + assume_ConsequentialTemporalLepoxAgainstFixed(z_solver, + z_context, + local_dec_vars_T, + local_values_T, + decided_polygons, + undecided, + solver_configuration.temporal_spread, + polygons, + lepox_to_next, + trans_bed_lepox, + presence_assumptions); #ifdef DEBUG { @@ -11619,7 +11782,7 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So progress_callback((SEQ_PROGRESS_RANGE * progress_object_phases_done) / progress_total_object_phases); return true; } - curr_polygon += solver_configuration.object_group_size; + curr_polygon += object_group_size; progress_callback((SEQ_PROGRESS_RANGE * progress_object_phases_done) / progress_total_object_phases); break; } @@ -11635,18 +11798,30 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So ++progress_object_phases_done; } remaining_local.push_back(undecided.back()); - } - missing.push_back(undecided.back()); - undecided.pop_back(); + undecided.pop_back(); - --object_group_size; - progress_callback((SEQ_PROGRESS_RANGE * progress_object_phases_done) / progress_total_object_phases); + --object_group_size; + progress_callback((SEQ_PROGRESS_RANGE * progress_object_phases_done) / progress_total_object_phases); + } } std::reverse(remaining_local.begin(), remaining_local.end()); remaining_polygons.insert(remaining_polygons.end(), remaining_local.begin(), remaining_local.end()); - - if (!optimized) + + if (optimized) + { + if (object_group_size < solver_configuration.object_group_size) + { + int group_size_diff = solver_configuration.object_group_size - object_group_size; + if (curr_polygon + group_size_diff < solvable_objects.size()) + { + curr_polygon += group_size_diff; + break; + } + return true; + } + } + else { if (curr_polygon <= 0) { @@ -11657,17 +11832,24 @@ bool optimize_SubglobalConsequentialPolygonNonoverlappingBinaryCentered(const So if (curr_polygon + solver_configuration.object_group_size < solvable_objects.size()) { curr_polygon += solver_configuration.object_group_size; - - for (; curr_polygon < solvable_objects.size(); ++curr_polygon) - { - remaining_polygons.push_back(curr_polygon); - } + break; } return true; } } } - assert(remaining_polygons.empty()); + for (; curr_polygon < solvable_objects.size(); ++curr_polygon) + { + remaining_polygons.push_back(curr_polygon); + } + #ifdef DEBUG + { + for (unsigned int i = 0; i < remaining_polygons.size(); ++i) + { + printf("Remaining: %d\n", remaining_polygons[i]); + } + } + #endif return true; } diff --git a/src/libseqarrange/src/seq_sequential.hpp b/src/libseqarrange/src/seq_sequential.hpp index fa26597..93a0d6d 100644 --- a/src/libseqarrange/src/seq_sequential.hpp +++ b/src/libseqarrange/src/seq_sequential.hpp @@ -336,6 +336,18 @@ void introduce_ConsequentialTemporalLepoxAgainstFixed(z3::solver const std::vector &lepox_to_next, bool trans_bed_lepox); +void assume_ConsequentialTemporalLepoxAgainstFixed(z3::solver &Solver, + z3::context &Context, + const z3::expr_vector &dec_vars_T, + std::vector &dec_values_T, + const std::vector &fixed, + const std::vector &undecided, + int temporal_spread, + const std::vector &SEQ_UNUSED(polygons), + const std::vector &lepox_to_next, + bool trans_bed_lepox, + z3::expr_vector &lepox_assumptions); + /*----------------------------------------------------------------*/ void introduce_LineNonIntersection(z3::solver &Solver, diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 43d072c..3ac9ef3 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -224,6 +224,16 @@ void AppConfig::set_defaults() if (get("sys_menu_enabled").empty()) set("sys_menu_enabled", "1"); #endif // _WIN32 + + if (get("show_step_import_parameters").empty()) + set("show_step_import_parameters", "1"); + + if (get("linear_precision").empty()) + set("linear_precision", "0.005"); + + if (get("angle_precision").empty()) + set("angle_precision", "1."); + // B45 if (get("machine_list_minification").empty()) set("machine_list_minification", "1"); diff --git a/src/libslic3r/FileReader.cpp b/src/libslic3r/FileReader.cpp index cec3f10..2bb4fd5 100644 --- a/src/libslic3r/FileReader.cpp +++ b/src/libslic3r/FileReader.cpp @@ -24,7 +24,7 @@ bool is_project_file(const std::string& input_file) } // Loading model from a file, it may be a simple geometry file as STL or OBJ, however it may be a project file as well. -static Model read_model_from_file(const std::string& input_file, LoadAttributes options) +static Model read_model_from_file(const std::string& input_file, LoadAttributes options, const std::optional>& step_deflections = std::nullopt) { Model model; @@ -36,8 +36,9 @@ static Model read_model_from_file(const std::string& input_file, LoadAttributes result = load_stl(input_file.c_str(), &model); else if (boost::algorithm::iends_with(input_file, ".obj")) result = load_obj(input_file.c_str(), &model); - else if (boost::algorithm::iends_with(input_file, ".step") || boost::algorithm::iends_with(input_file, ".stp")) - result = load_step(input_file.c_str(), &model); + else if (boost::algorithm::iends_with(input_file, ".step") || boost::algorithm::iends_with(input_file, ".stp")) { + result = load_step(input_file.c_str(), &model, step_deflections); + } else if (boost::algorithm::iends_with(input_file, ".amf") || boost::algorithm::iends_with(input_file, ".amf.xml")) //? result = load_amf(input_file.c_str(), &temp_config, &temp_config_substitutions_context, &model, options & LoadAttribute::CheckVersion); //? LoadAttribute::CheckVersion is needed here, when we loading just a geometry @@ -56,7 +57,7 @@ static Model read_model_from_file(const std::string& input_file, LoadAttributes if (!result) throw Slic3r::RuntimeError(L("Loading of a model file failed.")); - if (model.objects.empty()) + if (model.objects.empty() && temp_config.empty()) throw Slic3r::RuntimeError(L("The supplied file couldn't be read because it's empty")); if (!boost::ends_with(input_file, ".printRequest")) @@ -91,7 +92,7 @@ static Model read_all_from_file(const std::string& input_file, if (!result) throw Slic3r::RuntimeError(L("Loading of a model file failed.")); - if (model.objects.empty()) + if (model.objects.empty() && config->empty()) throw Slic3r::RuntimeError(L("The supplied file couldn't be read because it's empty")); for (ModelObject* o : model.objects) @@ -203,9 +204,10 @@ static int removed_objects_with_zero_volume(Model& model) Model load_model(const std::string& input_file, LoadAttributes options/* = LoadAttribute::AddDefaultInstances*/, - LoadStats* stats/*= nullptr*/) + LoadStats* stats/*= nullptr*/, + std::optional> step_deflections/* = std::nullopt*/) { - Model model = read_model_from_file(input_file, options); + Model model = read_model_from_file(input_file, options, step_deflections); for (auto obj : model.objects) if (obj->name.empty()) diff --git a/src/libslic3r/FileReader.hpp b/src/libslic3r/FileReader.hpp index 76d9072..5e026cf 100644 --- a/src/libslic3r/FileReader.hpp +++ b/src/libslic3r/FileReader.hpp @@ -2,6 +2,8 @@ #include "PrintConfig.hpp" #include "enum_bitmask.hpp" +#include +#include namespace Slic3r { @@ -34,7 +36,8 @@ namespace FileReader // Exceptions don't catched inside Model load_model(const std::string& input_file, LoadAttributes options = LoadAttribute::AddDefaultInstances, - LoadStats* statistics = nullptr); + LoadStats* statistics = nullptr, + std::optional> step_deflections = std::nullopt); // Load model, config and config substitutions from input file and fill statistics if it's required. // Exceptions don't catched inside diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp index 2737bbb..b3d4a50 100644 --- a/src/libslic3r/Format/STEP.cpp +++ b/src/libslic3r/Format/STEP.cpp @@ -23,9 +23,12 @@ namespace Slic3r { #if __APPLE__ -extern "C" bool load_step_internal(const char *path, OCCTResult* res); +extern "C" bool load_step_internal(const char *path, OCCTResult* res, std::optional> deflections /*= std::nullopt*/); #endif +// Inside deflections pair: +// * first value is linear deflection +// * second value is angle deflection LoadStepFn get_load_step_fn() { static LoadStepFn load_step_fn = nullptr; @@ -76,7 +79,7 @@ LoadStepFn get_load_step_fn() return load_step_fn; } -bool load_step(const char *path, Model *model /*BBS:, ImportStepProgressFn proFn*/) +bool load_step(const char *path, Model *model /*BBS:, ImportStepProgressFn proFn*/, std::optional> deflections) { OCCTResult occt_object; @@ -85,7 +88,7 @@ bool load_step(const char *path, Model *model /*BBS:, ImportStepProgressFn proFn if (!load_step_fn) return false; - load_step_fn(path, &occt_object); + load_step_fn(path, &occt_object, deflections); assert(! occt_object.volumes.empty()); diff --git a/src/libslic3r/Format/STEP.hpp b/src/libslic3r/Format/STEP.hpp index 6884ac2..dbbba59 100644 --- a/src/libslic3r/Format/STEP.hpp +++ b/src/libslic3r/Format/STEP.hpp @@ -2,6 +2,9 @@ #ifndef slic3r_Format_STEP_hpp_ #define slic3r_Format_STEP_hpp_ +#include +#include + namespace Slic3r { class Model; @@ -9,7 +12,10 @@ class Model; //typedef std::function ImportStepProgressFn; // Load a step file into a provided model. -extern bool load_step(const char *path_str, Model *model /*LMBBS:, ImportStepProgressFn proFn = nullptr*/); +// Inside deflections pair: +// * first value is linear deflection +// * second value is angle deflection +extern bool load_step(const char *path_str, Model *model /*LMBBS:, ImportStepProgressFn proFn = nullptr*/, std::optional> deflections = std::nullopt); }; // namespace Slic3r diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 827eb7e..2b17772 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1234,6 +1234,16 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail // adds tags for time estimators if (print.config().remaining_times.value) file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::First_Line_M73_Placeholder).c_str()); + //Y30 + if (print.config().box_temperature_control.value) { + file.write("DISABLE_BOX_HEATER\n"); + std::string box_temps = "BOX_TEMP_SET"; + for (unsigned int extruder_id : tool_ordering.all_extruders()){ + std::string box_temperature = std::to_string(config().box_temperature.get_at(extruder_id)); + box_temps += " VT" + std::to_string(extruder_id) + "=" + box_temperature; + } + file.write(box_temps + "\n"); + } // Write the custom start G-code file.writeln(start_gcode); @@ -1292,8 +1302,8 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail file.write(this->writer().travel_to_z_force(last_z, "ensure z position")); const double travel_z = std::max(last_z, double(m_max_layer_z)); file.write(this->writer().travel_to_z_force(travel_z, "ensure z position to clear all already printed objects")); - const Vec3crd from{to_3d(*this->last_position, scaled(this->m_last_layer_z))}; - const Vec3crd to{0, 0, scaled(this->m_last_layer_z)}; + const Vec3crd from{to_3d(*this->last_position, scaled(travel_z))}; + const Vec3crd to{0, 0, scaled(travel_z)}; file.write(this->travel_to(from, to, ExtrusionRole::None, "move to origin position for next object", [](){return "";})); m_enable_cooling_markers = true; // Disable motion planner when traveling to first object point. @@ -1441,6 +1451,17 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail if (print.config().remaining_times.value) file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str()); + //y27 + auto all_extruders = tool_ordering.all_extruders(); + sort(all_extruders.begin(), all_extruders.end()); + file.write("; used_extruders = "); + for (size_t i = 0; i < all_extruders.size(); ++i) { + file.write_format("%u", all_extruders[i]); + if (i < all_extruders.size() - 1) + file.write(";"); + } + file.write("\n"); + print.throw_if_canceled(); // Get filament stats. @@ -2369,7 +2390,7 @@ std::pair split_with_seam( loop, flipped, scaled_resolution, *seam_point, seam_point_merge_distance_threshold ), 0}; - } else if (scarf != nullptr && scarf->start_point == scarf->end_point) { + } else if (scarf != nullptr && scarf->start_point == scarf->end_point && !scarf->entire_loop) { return {smooth_path_cache.resolve_or_fit_split_with_seam( loop, flipped, scaled_resolution, scarf->start_point, seam_point_merge_distance_threshold ), 0}; @@ -2785,7 +2806,11 @@ LayerResult GCodeGenerator::process_layer( if (m_current_instance != next_instance) { m_avoid_crossing_perimeters.use_external_mp_once = true; } - gcode += this->travel_to_first_position(first_point - to_3d(shift, 0), print_z, ExtrusionRole::Mixed, [this]() { + + const double writer_z{m_writer.get_position().z()}; + const double previous_z{writer_z <= std::numeric_limits::epsilon() ? print_z : writer_z}; + + gcode += this->travel_to_first_position(first_point - to_3d(shift, 0), previous_z, ExtrusionRole::Mixed, [this]() { if (m_writer.multiple_extruders) { return std::string{""}; } @@ -3997,7 +4022,7 @@ std::string GCodeGenerator::set_extruder(unsigned int extruder_id, double print_ std::string toolchange_gcode_parsed; // Process the custom toolchange_gcode. If it is empty, insert just a Tn command. - if (!toolchange_gcode.empty()) { + if (!toolchange_gcode.empty() && print_z > 0.0) { DynamicConfig config; config.set_key_value("previous_extruder", new ConfigOptionInt((int)(m_writer.extruder() != nullptr ? m_writer.extruder()->id() : -1 ))); config.set_key_value("next_extruder", new ConfigOptionInt((int)extruder_id)); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 5702dfe..a069aea 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -969,7 +969,7 @@ void WipeTower::toolchange_Unload( float old_x = writer.x(); float turning_point = (!m_left_to_right ? xl : xr ); if (m_semm && (m_cooling_tube_retraction != 0 || m_cooling_tube_length != 0)) { - float total_retraction_distance = m_cooling_tube_retraction + m_cooling_tube_length/2.f - 15.f; // the 15mm is reserved for the first part after ramming + float total_retraction_distance = m_cooling_tube_retraction + m_cooling_tube_length/2.f - 15.f; // the 15mm is reserved for the first part after ramming writer.suppress_preview() .retract(15.f, m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s .retract(0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f) @@ -1040,6 +1040,7 @@ void WipeTower::toolchange_Unload( writer.set_extruder_temp(new_temperature, false); } + float speed = initial_speed + speed_inc * 2*i; writer.load_move_x_advanced(turning_point, m_cooling_tube_length, speed); speed += speed_inc; diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 55a1f8e..6a26f9a 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -317,9 +317,9 @@ Surfaces merge_bridges( // union_safety_offset_ex(acc) for (ExPolygon &bridge_expolygon : merged_bridges) { - Surface surface{ stBottomBridge, std::move(bridge_expolygon) }; const Lines lines{to_lines(diff_pl(to_polylines(bridge_expolygon), expand(expansions, float(SCALED_EPSILON))))}; auto [bridging_dir, unsupported_dist] = detect_bridging_direction(lines, to_polygons(bridge_expolygon)); + Surface surface{ stBottomBridge, std::move(bridge_expolygon) }; surface.bridge_angle = M_PI + std::atan2(bridging_dir.y(), bridging_dir.x()); result.push_back(std::move(surface)); } diff --git a/src/libslic3r/Measure.cpp b/src/libslic3r/Measure.cpp index e503885..e4c347c 100644 --- a/src/libslic3r/Measure.cpp +++ b/src/libslic3r/Measure.cpp @@ -1129,7 +1129,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& else { ClosestInfo& info = candidates[0]; - const double N0dD = n0.dot(D); + double N0dD = n0.dot(D); const Vec3d normProj = N0dD * n0; const Vec3d compProj = D - normProj; Vec3d U = compProj; @@ -1190,6 +1190,7 @@ MeasurementResult get_measurement(const SurfaceFeature& a, const SurfaceFeature& distance = (c1 - c0).norm(); info.circle0Closest = c0; info.circle1Closest = c1; + N0dD = 0.0; } } diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index e37dea9..61a41c2 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -569,7 +569,12 @@ static std::vector s_Preset_filament_options { //Y28 "dont_slow_down_outer_wall", //w15 - "filament_wipe_distance" + "filament_wipe_distance", + //y25 + "filament_id", + //Y30 + "filament_flush_temp", + "box_temperature" }; static std::vector s_Preset_machine_limits_options { @@ -599,7 +604,12 @@ static std::vector s_Preset_printer_options { //Y25 "wipe_device", //Y16 - "chamber_temperature_control", "auxiliary_fan", "chamber_fan" + "chamber_temperature_control", "auxiliary_fan", "chamber_fan", + //y25 + "box_id", + "nozzle_volume", + //Y30 + "box_temperature_control" }; static std::vector s_Preset_sla_print_options { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 1333058..b832d67 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -199,6 +199,9 @@ public: //y3 std::set get_vendors(); + //QDS box y25 + std::map filament_box_list; + private: std::pair load_system_presets(ForwardCompatibilitySubstitutionRule compatibility_rule); // Merge one vendor's presets with the other vendor's presets, report duplicates. diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a534797..6b62911 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -77,6 +77,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "overhang_fan_speed_3", "chamber_temperature", "chamber_minimal_temperature", + //Y30 + "box_temperature", "colorprint_heights", "cooling", "default_acceleration", @@ -166,7 +168,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "wipe", "wipe_tower_acceleration", //w15 - "wipe_distance" + "wipe_distance", + //y25 + "nozzle_volume" }; static std::unordered_set steps_ignore; @@ -206,6 +210,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n opt_key == "complete_objects" || opt_key == "filament_type" || opt_key == "first_layer_temperature" + //Y30 + || opt_key == "filament_flush_temp" || opt_key == "filament_loading_speed" || opt_key == "filament_loading_speed_start" || opt_key == "filament_unloading_speed" diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index cae2455..cb0a601 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -639,6 +639,21 @@ void PrintConfigDef::init_fff_params() def->max = 1000; def->mode = comExpert; def->set_default_value(new ConfigOptionInts{ 0 }); +//Y30 + def = this->add("box_temperature", coInts); + def->label = L("BOX temperature"); + def->tooltip = L("BOX temperature."); + def->sidetext = L("°C"); + def->min = 0; + def->max = 65; + def->mode = comExpert; + def->set_default_value(new ConfigOptionInts{ 0 }); + + def = this->add("box_temperature_control", coBool); + def->label = L("BOX Temperature"); + def->tooltip = L("Enable box temperature control."); + def->mode = comExpert; + def->set_default_value(new ConfigOptionBool(false)); def = this->add("bed_temperature_extruder", coInt); def->label = L("Bed temperature by extruder"); @@ -1812,6 +1827,16 @@ void PrintConfigDef::init_fff_params() def->max = max_temp; def->set_default_value(new ConfigOptionInts { 200 }); + //Y30 + def = this->add("filament_flush_temp", coInts); + def->label = L("Flush"); + def->full_label = L("Filament flush nozzle temperature"); + def->tooltip = L("Nozzle temperature for the Filament flush."); + def->sidetext = L("°C"); + def->min = 0; + def->max = max_temp; + def->set_default_value(new ConfigOptionInts { 240 }); + def = this->add("full_fan_speed_layer", coInts); def->label = L("Full fan speed at layer"); def->tooltip = L("Fan speed will be ramped up linearly from zero at layer \"disable_fan_first_layers\" " @@ -2740,6 +2765,21 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionString()); // def->cli = ConfigOptionDef::nocli; +//y25 + def = this->add("box_id", coString); + def->label = L("Box id"); + def->tooltip = L("ID of the printer."); + def->set_default_value(new ConfigOptionString()); + + def = this->add("nozzle_volume", coFloat); + def->label = L("Nozzle volume"); + def->tooltip = L("Volume of nozzle between the cutter and the end of nozzle"); + def->set_default_value(new ConfigOptionFloat(0.0)); +//y25 + + def = this->add("filament_id", coStrings); + def->set_default_value(new ConfigOptionStrings { "" }); + def = this->add("printer_notes", coString); def->label = L("Printer notes"); def->tooltip = L("You can put your notes regarding the printer here."); @@ -3764,6 +3804,20 @@ void PrintConfigDef::init_fff_params() def->max = max_temp; def->set_default_value(new ConfigOptionInts { 200 }); + def = this->add("nozzle_temperature_range_low", coInts); + def->label = L("Min"); + def->sidetext = "°C"; + def->min = 0; + def->max = max_temp; + def->set_default_value(new ConfigOptionInts { 190 }); + + def = this->add("nozzle_temperature_range_high", coInts); + def->label = L("Max"); + def->sidetext = "°C"; + def->min = 0; + def->max = max_temp; + def->set_default_value(new ConfigOptionInts { 240 }); + def = this->add("thick_bridges", coBool); def->label = L("Thick bridges"); def->category = L("Layers and Perimeters"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index dba61c8..56cea39 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -918,6 +918,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionString, template_custom_gcode)) //w15 ((ConfigOptionFloats, wipe_distance)) + //y25 + ((ConfigOptionStrings, filament_id)) ) static inline std::string get_extrusion_axis(const GCodeConfig &cfg) @@ -952,6 +954,9 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionInts, overhang_fan_speed_3)) ((ConfigOptionInts, chamber_temperature)) ((ConfigOptionInts, chamber_minimal_temperature)) + //Y30 + ((ConfigOptionInts, box_temperature)) + ((ConfigOptionBool, box_temperature_control)) ((ConfigOptionBool, complete_objects)) ((ConfigOptionFloats, colorprint_heights)) ((ConfigOptionBools, cooling)) @@ -989,6 +994,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( //w25 ((ConfigOptionInt, slow_down_layers)) ((ConfigOptionInts, first_layer_temperature)) + //Y30 + ((ConfigOptionInts, filament_flush_temp)) ((ConfigOptionIntsNullable, idle_temperature)) //B26 ((ConfigOptionBools, enable_advance_pressure)) @@ -1047,6 +1054,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloats, wiping_volumes_matrix)) ((ConfigOptionBool, wiping_volumes_use_custom_matrix)) ((ConfigOptionFloat, z_offset)) + //y25 + ((ConfigOptionString, box_id)) ) PRINT_CONFIG_CLASS_DERIVED_DEFINE0( diff --git a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp index 0985d6e..79231c2 100644 --- a/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp +++ b/src/libslic3r/SLA/SupportIslands/UniformSupportIsland.cpp @@ -40,6 +40,7 @@ //#define SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG_PATH "C:/data/temp/align/island_<>_aligned.svg" //#define SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGN_ONCE_TO_SVG_PATH "C:/data/temp/align_once/iter_<>.svg" //#define SLA_SAMPLE_ISLAND_UTILS_DEBUG_CELL_DISTANCE_PATH "C:/data/temp/island_cell.svg" +//#define SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH "C:/data/temp/parts/part<>.svg" namespace { using namespace Slic3r; @@ -1843,14 +1844,24 @@ void merge_island_parts(IslandParts &island_parts, size_t index, size_t remove_i /// Index into island parts to merge /// Queue of future processing void merge_parts_and_fix_process(IslandParts &island_parts, - ProcessItem &item, size_t index, size_t remove_index, ProcessItems &process) { + ProcessItem &item, size_t index, size_t remove_index, ProcessItems &process, const Neighbor* neighbor) { if (remove_index == index) return; // nothing to merge, loop connect to itself - if (remove_index < index) // remove part with bigger index - std::swap(remove_index, index); // Merged parts should be the same state, it is essential for alhorithm // Only first island part changes its type, but only before first change - assert(island_parts[index].type == island_parts[remove_index].type); + IslandPart &part = island_parts[index]; + IslandPart &part_ = island_parts[remove_index]; + if (part.type != part_.type) { + part.changes.push_back(IslandPartChange{Position(neighbor, 0.), remove_index}); + const Neighbor *twin = VoronoiGraphUtils::get_twin(*neighbor); + part_.changes.push_back(IslandPartChange{Position(twin, 1.), index}); + return; + } + + // remove part with bigger index + if (remove_index < index) + std::swap(remove_index, index); + island_parts[index].sum_lengths += island_parts[remove_index].sum_lengths; merge_island_parts(island_parts, index, remove_index); @@ -2166,7 +2177,11 @@ std::pair> merge_negihbor(IslandParts &island_parts, // collect changes from neighbors for result part + indices of neighbor parts IslandPartChanges modified_changes; for (const IslandPartChange &change : changes) { - remove_indices.push_back(change.part_index); + if (auto it = std::lower_bound(remove_indices.begin(), remove_indices.end(), change.part_index); + it != remove_indices.end() && *it == change.part_index) + continue; // part already added + + VectorUtils::insert_sorted(remove_indices, change.part_index, std::less{}); // iterate neighbor changes and collect only changes to other neighbors for (const IslandPartChange &n_change : island_parts[change.part_index].changes) { if (n_change.part_index == index) @@ -2183,10 +2198,7 @@ std::pair> merge_negihbor(IslandParts &island_parts, } } - // Modified index is smallest from index or remove_indices - std::sort(remove_indices.begin(), remove_indices.end()); - remove_indices.erase( // Remove duplicit inidices - std::unique(remove_indices.begin(), remove_indices.end()), remove_indices.end()); + // Set modified index to smallest from index or remove_indices(are sorted) size_t modified_index = index; if (remove_indices.front() < index) { std::swap(remove_indices.front(), modified_index); @@ -2330,6 +2342,163 @@ std::pair convert_island_parts_to_thin_thick( return result; } +#ifdef SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH +void draw(const IslandParts &parts, const ProcessItems &queue, const ProcessItem& current, const Lines& lines) { + + static int counter = 0; + std::string svg_path = replace_first(SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH, "<>", std::to_string(counter++)); + SVG svg(svg_path.c_str(), LineUtils::create_bounding_box(lines)); + LineUtils::draw(svg, lines, "black", 0.); + + const char *thin_color = "blue"; + const char *thick_color = "green"; + const char *middle_color = "orange"; + coord_t edge_width = 3e4; + + using Neighbor = VoronoiGraph::Node::Neighbor; + std::vector queue_done; + auto get_neighbor = [](const VoronoiGraph::Node *from, const VoronoiGraph::Node* to)->const Neighbor* { + if (from == nullptr || to == nullptr) + return nullptr; + for (const Neighbor &n : from->neighbors) + if (n.node == to) + return &n; + return nullptr; + }; + for (const ProcessItem& it : queue) { + const Neighbor *n = get_neighbor(it.prev_node, it.node); + queue_done.push_back(n); + queue_done.push_back(VoronoiGraphUtils::get_twin(*n)); + } + + if (const Neighbor *n = get_neighbor(current.prev_node, current.node); + n != nullptr) { + queue_done.push_back(n); + queue_done.push_back(VoronoiGraphUtils::get_twin(*n)); + } + for (const IslandPart &part : parts){ + for (const IslandPartChange &change : part.changes) { // add changes + const Neighbor *n = change.position.neighbor; + queue_done.push_back(n); + queue_done.push_back(VoronoiGraphUtils::get_twin(*n)); + } + } + auto neighbor_sort = [](const Neighbor *a, const Neighbor *b) {return a < b;}; + std::sort(queue_done.begin(), queue_done.end(), neighbor_sort); + queue_done.erase(std::unique(queue_done.begin(), queue_done.end()), queue_done.end()); + + for (const IslandPart &part: parts){ + size_t index = &part - &parts.front(); + Positions ends; + const char *color = + part.type == IslandPartType::thin ? thin_color : + part.type == IslandPartType::thick ? thick_color : middle_color; + for (const IslandPartChange &change: part.changes){ + if (change.part_index > index) + continue; + + Point p = VoronoiGraphUtils::create_edge_point(change.position); + const auto edge = change.position.neighbor->edge; + const VD::vertex_type *v0 = edge->vertex0(); + const VD::vertex_type *v1 = edge->vertex1(); + Vec2d dir(v1->x() - v0->x(), v1->y() - v0->y()); + dir.normalize(); + dir.x() *= 0.6 / SCALING_FACTOR; + dir.y() *= 1 / SCALING_FACTOR; + Point dir_ = dir.cast(); + + auto type = parts[change.part_index].type; + const char *neighbor_color = + type == IslandPartType::thin ? thin_color : + type == IslandPartType::thick ? thick_color : middle_color; + svg.draw(p.cast(), "gray"); + VoronoiGraphUtils::draw(svg, *edge, lines, "gray", edge_width); + Point letter_offset(-.75/SCALING_FACTOR, -.7/SCALING_FACTOR); + svg.draw_text(letter_offset + p + dir_, std::to_string(change.part_index).c_str(), neighbor_color); + svg.draw_text(letter_offset + p - dir_, std::to_string(index).c_str(), color); + ends.push_back(change.position); + } + + if (part.changes.empty()) { + assert(parts.size() == 1); + continue; // only first part till first change + } + + const Neighbor *start = VoronoiGraphUtils::get_twin(*part.changes.front().position.neighbor); + auto is_start = [start](const IslandPartChange &change) { + return change.position.neighbor == start; + }; + if (std::find_if(part.changes.begin(), part.changes.end(), is_start) != part.changes.end()) + continue; // start is also end; + + std::vector done = queue_done; // copy queue + std::function draw_neighbor; // recursive function for draw + draw_neighbor = [&draw_neighbor, &done, &svg, &lines, color, neighbor_sort, edge_width, index] + (const Neighbor *neighbor) { + VectorUtils::insert_sorted(done, neighbor, neighbor_sort); + const Neighbor *twin = VoronoiGraphUtils::get_twin(*neighbor); + VectorUtils::insert_sorted(done, twin, neighbor_sort); + for (const Neighbor &n: neighbor->node->neighbors){ + if (&n == twin) + continue; + + if (auto it = std::lower_bound(done.begin(), done.end(), &n, neighbor_sort); + it != done.end() && *it == &n) + continue; // already done + + VoronoiGraphUtils::draw(svg, *n.edge, lines, color, edge_width); + auto v0 = n.edge->vertex0(); + auto v1 = n.edge->vertex1(); + Point p(v0->x() / 2 + v1->x() / 2, v0->y() / 2 + v1->y() / 2); + svg.draw_text(p, std::to_string(index).c_str(), color, 1); + draw_neighbor(&n);//recursive call + } + }; + draw_neighbor(start); + } + + for (const ProcessItem &item : queue) { + Point from = VoronoiGraphUtils::to_point(item.prev_node->vertex); + Point to = VoronoiGraphUtils::to_point(item.node->vertex); + svg.draw(Line(from, to), "darkgray"); + svg.draw(to, "darkgray"); + svg.draw_text(from / 2 + to / 2, std::to_string(item.i).c_str(), "darkgray"); + } + + if (current.prev_node == nullptr){ + if (current.node == nullptr) + return; + Point p = VoronoiGraphUtils::to_point(current.node->vertex); + svg.draw(p, "red"); + svg.draw_text(p, std::to_string(current.i).c_str(), "red"); + } else { + Point from = VoronoiGraphUtils::to_point(current.prev_node->vertex); + Point to = VoronoiGraphUtils::to_point(current.node->vertex); + svg.draw(Line(from, to), "red"); + svg.draw(to, "red"); + svg.draw_text(from / 2 + to / 2, std::to_string(current.i).c_str(), "red"); + } +} +#endif // SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH + +#ifndef NDEBUG +bool exist_twin_change_in_part(const IslandParts &parts){ + auto sort_by_neighbor = [](const IslandPartChange &c1, const IslandPartChange &c2) { + return c1.position.neighbor < c2.position.neighbor; + }; + auto is_same_neighbor = [](const IslandPartChange &c1, const IslandPartChange &c2) { + return c1.position.neighbor == c2.position.neighbor; + }; + for(const IslandPart &part: parts){ + IslandPartChanges changes = part.changes; // copy + std::sort(changes.begin(), changes.end(), sort_by_neighbor); + if (std::unique(changes.begin(), changes.end(), is_same_neighbor) != changes.end()) + return true; + } + return false; +} +#endif // DEBUG + /// /// Separate thin(narrow) and thick(wide) part of island /// @@ -2357,28 +2526,31 @@ std::pair separate_thin_thick( ProcessItem item = {/*prev_node*/ nullptr, start_node, 0}; // current processing item ProcessItems process; // queue of nodes to process do { // iterate over all nodes in graph and collect interfaces into island_parts - assert(item.node != nullptr); +//#ifdef SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH +// draw(island_parts, process, item, lines); +//#endif // SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH ProcessItem next_item = {nullptr, nullptr, std::numeric_limits::max()}; for (const Neighbor &neighbor: item.node->neighbors) { if (neighbor.node == item.prev_node) continue; // already done - if (next_item.node != nullptr) // already prepared item is stored into queue - process.push_back(next_item); - - size_t next_part_index = detect_interface(island_parts, item.i, &neighbor, lines, config); - next_item = ProcessItem{item.node, neighbor.node, next_part_index}; + if (next_item.node != nullptr) { // already prepared item is stored into queue + process.push_back(next_item); + next_item.node = nullptr; + } // exist loop back? - auto is_oposit_item = [&next_item](const ProcessItem &p) { - return p.node == next_item.prev_node && p.prev_node == next_item.node;}; + auto is_oposit_item = [prev_node = item.node, node = neighbor.node](const ProcessItem &p) { + return p.node == prev_node && p.prev_node == node;}; if (auto process_it = std::find_if(process.begin(), process.end(), is_oposit_item); process_it != process.end()) { // solve loop back - merge_parts_and_fix_process(island_parts, item, process_it->i, next_item.i, process); + merge_parts_and_fix_process(island_parts, item, item.i, process_it->i, process, &neighbor); // branch is already processed process.erase(process_it); - next_item.node = nullptr; // do not use item as next one continue; } + + size_t next_part_index = detect_interface(island_parts, item.i, &neighbor, lines, config); + next_item = ProcessItem{item.node, neighbor.node, next_part_index}; } // Select next node to process if (next_item.node != nullptr) { @@ -2390,13 +2562,19 @@ std::pair separate_thin_thick( process.pop_back(); } } while (item.node != nullptr); // loop should end by break with empty process +#ifdef SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH + draw(island_parts, process, item, lines); +#endif // SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH merge_middle_parts_into_biggest_neighbor(island_parts); if (island_parts.size() != 1) merge_same_neighbor_type_parts(island_parts); if (island_parts.size() != 1) merge_short_parts(island_parts, config.min_part_length); - + assert(!exist_twin_change_in_part(island_parts)); +#ifdef SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH + draw(island_parts, {}, {}, lines); +#endif // SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH return convert_island_parts_to_thin_thick(island_parts, path); } @@ -2663,6 +2841,9 @@ bool is_uniform_support_island_visualization_disabled() { #ifdef SLA_SAMPLE_ISLAND_UTILS_STORE_ALIGNED_TO_SVG_PATH return false; #endif +#ifdef SLA_SAMPLE_ISLAND_UTILS_DEBUG_PARTS_PATH + return false; +#endif return true; } diff --git a/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp b/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp index 5f4de94..f22565c 100644 --- a/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp +++ b/src/libslic3r/SLA/SupportIslands/VoronoiGraphUtils.cpp @@ -1320,7 +1320,7 @@ void VoronoiGraphUtils::draw(SVG & svg, std::stringstream ss; ss << prefix << std::hex << reinterpret_cast(addr); std::string s = ss.str(); - svg.draw_text(p, s.c_str(), color, 6); + svg.draw_text(p, s.c_str(), color, 1); } }; @@ -1329,19 +1329,50 @@ void VoronoiGraphUtils::draw(SVG & svg, "yellowgreen", // on way to thin (max is above thin) "limegreen", // between (inside histerezis) "forestgreen", // on way to thick (min is belove thick) - "darkgreen" // thick (min+max above thick) + "darkgreen", // thick (min+max above thick) + "brown" // cross histereze }; - auto get_color = [&](const VoronoiGraph::Node::Neighbor &n) { - if (n.min_width() > config.thin_max_width){ + std::vector color_description{ + "thin (min+max belowe thin " + std::to_string(config.thick_min_width) + ")", + "on way to thin (max is above thin)", + "between (inside histerezis)", + "on way to thick (min is belove thick)", + "thick (min+max above thick " + std::to_string(config.thin_max_width) + ")", + "cross histereze" + }; + Point legend_position = lines.front().a; + for (const Line& l: lines){ + if (legend_position.x() < l.a.x()) + legend_position.x() = l.a.x(); + if (legend_position.y() < l.a.y()) + legend_position.y() = l.a.y(); + } + for (size_t i = 0; i < 6; i++) { + Point p(legend_position.x(), legend_position.y() - static_cast(i * 1.3 / SCALING_FACTOR)); + std::string text = color_description[i] + " (" + skeleton_colors[i] + ")"; + svg.draw_text(p, text.c_str(), skeleton_colors[i], 8); + } + + auto get_color = [&skeleton_colors, + min_limit = config.thick_min_width, + max_limit = config.thin_max_width] + (const VoronoiGraph::Node::Neighbor &n) { + assert(n.min_width() <= n.max_width()); + coord_t min_width = n.min_width(); + coord_t max_width = n.max_width(); + if (min_width >= max_limit){ return skeleton_colors[4]; - } else if (n.max_width() < config.thick_min_width){ + } else if (max_width <= min_limit){ return skeleton_colors[0]; - } else if (n.min_width() < config.thin_max_width && - n.max_width() > config.thick_min_width){ + } else if (min_width >= min_limit && + max_width <= max_limit){ return skeleton_colors[2]; - } else if (n.min_width() < config.thick_min_width){ + } else if (min_width <= min_limit && + max_width >= max_limit){ + return skeleton_colors[5]; + } else if (min_width <= min_limit){ return skeleton_colors[1]; - } else if (n.max_width() > config.thin_max_width) { + } else if (max_width >= max_limit) { return skeleton_colors[3]; } assert(false); @@ -1357,17 +1388,16 @@ void VoronoiGraphUtils::draw(SVG & svg, Point to = to_point(n.edge->vertex1()); bool is_second = n.edge->vertex0() > n.edge->vertex1(); Point center = (from + to) / 2; - Point p = center + ((is_second) ? Point(0., -2e6) : - Point(0., 2e6)); + Point p = center + ((is_second) ? Point(0., -2e5) : Point(0., 2e5)); print_address(p, "neighbor ptr ", (void *) &n, "gray"); if (is_second) continue; const char *color = get_color(n); if (pointer_caption) { std::string width_str = "width min=" + std::to_string(n.min_width()) + " max=" + std::to_string(n.max_width()); - svg.draw_text(center + Point(-6e6, 0.), width_str.c_str(), color, 6); + svg.draw_text(center, width_str.c_str(), color, 3); } - draw(svg, *n.edge, lines, color, width); + draw(svg, *n.edge, lines, color, 2*width); } } } diff --git a/src/libslic3r/SLA/SupportPointGenerator.cpp b/src/libslic3r/SLA/SupportPointGenerator.cpp index fd083c7..566c6c9 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.cpp +++ b/src/libslic3r/SLA/SupportPointGenerator.cpp @@ -713,12 +713,12 @@ std::optional create_small_part( /// Recursive fast check function without storing any already searched data /// NOTE: Small part with holes could slow down checking /// - /// Index of layer with part - /// Index of part in layer.parts + /// Index of layer and part /// Recursion protection - std::function check_parts; + /// To prevent cycling calls + std::function check_parts; check_parts = [&range_bb, &check_parts, &layers, &island, radius_in_mm] - (const LayerPartIndex& check, size_t allowed_depth) -> bool { + (const LayerPartIndex& check, size_t allowed_depth, const LayerPartIndex& prev_check) -> bool { const Layer &check_layer = layers[check.layer_index]; const LayerPart &check_part = check_layer.parts[check.part_index]; for (const PartLink &link : check_part.next_parts) @@ -727,6 +727,9 @@ std::optional create_small_part( !range_bb.contains(link->shape_extent.max)) return false; // part is too large + if ((check_layer.print_z - layers[island.layer_index].print_z) > radius_in_mm) + return false; // parts is large in Z direction + --allowed_depth; if (allowed_depth == 0) return true; // break recursion @@ -735,7 +738,10 @@ std::optional create_small_part( size_t next_layer_i = check.layer_index + 1; for (const PartLink& link : check_part.next_parts) { size_t next_part_i = link - layers[next_layer_i].parts.cbegin(); - if (!check_parts({next_layer_i, next_part_i}, allowed_depth)) + if (next_layer_i == prev_check.layer_index && + next_part_i == prev_check.part_index) + continue; // checked in lambda caller contex + if (!check_parts({next_layer_i, next_part_i}, allowed_depth, check)) return false; } @@ -747,12 +753,7 @@ std::optional create_small_part( // Investigate only the first island(lower index into parts). if (check.part_index < island.part_index) return false; // part is already checked - } - - - if (float max_z = radius_in_mm + layers[island.layer_index].print_z; - check_layer.print_z > max_z) - return false; // too far in Z + } // NOTE: multiple investigation same part seems more relevant // instead of store and search for already checked parts @@ -768,20 +769,28 @@ std::optional create_small_part( for (const PartLink &link : check_part.prev_parts) { size_t prev_layer_i = check.layer_index - 1; // exist only when exist prev parts - cant be negative size_t prev_part_i = link - layers[prev_layer_i].parts.cbegin(); + + if (prev_layer_i == prev_check.layer_index && + prev_part_i == prev_check.part_index) + continue; // checked in lambda caller contex + // Improve: check only parts which are not already checked - if (!check_parts({prev_layer_i, prev_part_i}, allowed_depth)) + if (!check_parts({prev_layer_i, prev_part_i}, allowed_depth, check)) return false; } return true; }; - float layer_height = layers[1].print_z - layers[0].print_z; + float layer_height = (island.layer_index == 0) ? + layers[1].print_z - layers[0].print_z: + layers[island.layer_index].print_z - layers[island.layer_index-1].print_z; + assert(layer_height > 0.f); - float safe_multiplicator = 1.3f; // 30% more layers than radius for zigzag(up & down layer) search - size_t allowed_depth = static_cast(std::ceil(radius_in_mm / layer_height * safe_multiplicator)); + float safe_multiplicator = 1.4f; // 40% more layers than radius for zigzag(up & down layer) search + size_t allowed_depth = static_cast(std::ceil((radius_in_mm / layer_height + 1) * safe_multiplicator)); // Check Bounding boxes and do not create any data - FAST CHECK // NOTE: it could check model parts multiple times those there is allowed_depth - if (!check_parts(island, allowed_depth)) + if (!check_parts(island, allowed_depth, island)) return {}; SmallPart collected; // sorted by layer_i, part_i diff --git a/src/occt_wrapper/OCCTWrapper.cpp b/src/occt_wrapper/OCCTWrapper.cpp index 6ed3870..0ec92cd 100644 --- a/src/occt_wrapper/OCCTWrapper.cpp +++ b/src/occt_wrapper/OCCTWrapper.cpp @@ -79,7 +79,7 @@ static void getNamedSolids(const TopLoc_Location& location, const Handle(XCAFDoc } } -extern "C" OCCTWRAPPER_EXPORT bool load_step_internal(const char *path, OCCTResult* res /*BBS:, ImportStepProgressFn proFn*/) +extern "C" OCCTWRAPPER_EXPORT bool load_step_internal(const char *path, OCCTResult* res /*BBS:, ImportStepProgressFn proFn*/, std::optional> deflections /*= std::nullopt*/) { try { //bool cb_cancel = false; @@ -129,7 +129,9 @@ try { res->object_name = obj_name; for (const NamedSolid &namedSolid : namedSolids) { - BRepMesh_IncrementalMesh mesh(namedSolid.solid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true); + BRepMesh_IncrementalMesh mesh(namedSolid.solid, + deflections.has_value() ? deflections.value().first : STEP_TRANS_CHORD_ERROR, false, + deflections.has_value() ? deflections.value().second : STEP_TRANS_ANGLE_RES, true); res->volumes.emplace_back(); std::vector vertices; diff --git a/src/occt_wrapper/OCCTWrapper.hpp b/src/occt_wrapper/OCCTWrapper.hpp index 7c86998..c5895e2 100644 --- a/src/occt_wrapper/OCCTWrapper.hpp +++ b/src/occt_wrapper/OCCTWrapper.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include struct stl_facet; @@ -21,7 +23,7 @@ struct OCCTResult { std::vector volumes; }; -using LoadStepFn = bool (*)(const char *path, OCCTResult* occt_result); +using LoadStepFn = bool (*)(const char *path, OCCTResult* occt_result, std::optional> deflections); }; // namespace Slic3r diff --git a/src/platform/msw/QIDISlicer-gcodeviewer.rc.in b/src/platform/msw/QIDISlicer-gcodeviewer.rc.in index e0ea210..4b45564 100644 --- a/src/platform/msw/QIDISlicer-gcodeviewer.rc.in +++ b/src/platform/msw/QIDISlicer-gcodeviewer.rc.in @@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_RC_VERSION@ VALUE "ProductName", "@SLIC3R_APP_NAME@ G-code Viewer" VALUE "ProductVersion", "@SLIC3R_BUILD_ID@" VALUE "InternalName", "@SLIC3R_APP_NAME@ G-code Viewer" - VALUE "LegalCopyright", "Copyright \251 2023-2024 QIDI Technology, \251 2016-2024 Prusa Research, \251 2011-2018 Alessandro Ranellucci" + VALUE "LegalCopyright", "Copyright \251 2023-2025 QIDI Technology, \251 2016-2025 Prusa Research, \251 2011-2018 Alessandro Ranellucci" VALUE "OriginalFilename", "qidi-gcodeviewer.exe" } } diff --git a/src/platform/msw/QIDISlicer.rc.in b/src/platform/msw/QIDISlicer.rc.in index 2104cb6..a6d8f06 100644 --- a/src/platform/msw/QIDISlicer.rc.in +++ b/src/platform/msw/QIDISlicer.rc.in @@ -12,7 +12,7 @@ PRODUCTVERSION @SLIC3R_RC_VERSION@ VALUE "ProductName", "@SLIC3R_APP_NAME@" VALUE "ProductVersion", "@SLIC3R_BUILD_ID@" VALUE "InternalName", "@SLIC3R_APP_NAME@" - VALUE "LegalCopyright", "Copyright \251 2023-2024 QIDI Technology, \251 2016-2024 Prusa Research, \251 2011-2018 Alessandro Ranellucci" + VALUE "LegalCopyright", "Copyright \251 2023-2025 QIDI Technology, \251 2016-2025 Prusa Research, \251 2011-2018 Alessandro Ranellucci" VALUE "OriginalFilename", "qidi-slicer.exe" } } diff --git a/src/platform/osx/Info.plist.in b/src/platform/osx/Info.plist.in index 1cf6ce2..37b0bfe 100644 --- a/src/platform/osx/Info.plist.in +++ b/src/platform/osx/Info.plist.in @@ -5,7 +5,7 @@ CFBundleExecutable @SLIC3R_APP_KEY@ CFBundleGetInfoString - @SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2024 QIDI Technology + @SLIC3R_APP_NAME@ Copyright (C) 2011-2019 Alessandro Ranellucci, (C) 2016-2025 Prusa Reseach, (C) 2016-2025 QIDI Technology CFBundleIconFile QIDISlicer.icns CFBundleName diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index d2d8e72..378b027 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -136,6 +136,8 @@ set(SLIC3R_GUI_SOURCES GUI/Sidebar.hpp GUI/Plater.cpp GUI/Plater.hpp + GUI/LoadStepDialog.cpp + GUI/LoadStepDialog.hpp GUI/PresetComboBoxes.hpp GUI/PresetComboBoxes.cpp GUI/BitmapComboBox.hpp @@ -200,6 +202,8 @@ set(SLIC3R_GUI_SOURCES GUI/SendSystemInfoDialog.hpp GUI/SurfaceDrag.cpp GUI/SurfaceDrag.hpp + GUI/SyncBoxInfoDialog.cpp + GUI/SyncBoxInfoDialog.hpp GUI/TextLines.cpp GUI/TextLines.hpp GUI/BonjourDialog.cpp diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index b50f453..a966019 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -289,8 +289,8 @@ AboutDialog::AboutDialog() "%5%" "

" "%6%
" - "%11% © 2023-2024 QIDI Technology.
" - "%7% © 2016-2024 Prusa Research.
" + "%11% © 2023-2025 QIDI Technology.
" + "%7% © 2016-2025 Prusa Research.
" "%8% © 2011-2018 Alessandro Ranellucci.
" "Slic3r %9% " "%10%." diff --git a/src/slic3r/GUI/Downloader.cpp b/src/slic3r/GUI/Downloader.cpp index 0c0ff90..8afb347 100644 --- a/src/slic3r/GUI/Downloader.cpp +++ b/src/slic3r/GUI/Downloader.cpp @@ -137,6 +137,19 @@ Downloader::Downloader() Bind(EVT_DWNLDR_FILE_CANCELED, &Downloader::on_canceled, this); } +namespace { +bool is_any_subdomain(const std::string& url, const std::vector& subdomains) +{ + for (const std::string& sub : subdomains) + { + if(FileGet::is_subdomain(url, sub)) + return true; + } + return false; +} + +} + void Downloader::start_download(const std::string& full_url) { assert(m_initialized); @@ -153,14 +166,14 @@ void Downloader::start_download(const std::string& full_url) size_t id = get_next_id(); - if (!boost::starts_with(escaped_url, "https://") || !FileGet::is_subdomain(escaped_url, "printables.com")) { - std::string msg = format(_L("Download won't start. Download URL doesn't point to https://printables.com : %1%"), escaped_url); + if (!boost::starts_with(escaped_url, "https://") || !is_any_subdomain(escaped_url, {"printables.com", "thingiverse.com"})) { + std::string msg = format(_L("Download won't start. Download URL doesn't point to allowed subdomains : %1%"), escaped_url); BOOST_LOG_TRIVIAL(error) << msg; NotificationManager* ntf_mngr = wxGetApp().notification_manager(); ntf_mngr->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::RegularNotificationLevel, msg); return; } - + m_downloads.emplace_back(std::make_unique(id, std::move(escaped_url), this, m_dest_folder, true)); NotificationManager* ntf_mngr = wxGetApp().notification_manager(); ntf_mngr->push_download_URL_progress_notification(id, m_downloads.back()->get_filename(), std::bind(&Downloader::user_action_callback, this, std::placeholders::_1, std::placeholders::_2)); @@ -199,7 +212,7 @@ void Downloader::on_progress(wxCommandEvent& event) float percent = (float)std::stoi(into_u8(event.GetString())) / 100.f; //BOOST_LOG_TRIVIAL(error) << "progress " << id << ": " << percent; NotificationManager* ntf_mngr = wxGetApp().notification_manager(); - BOOST_LOG_TRIVIAL(trace) << "Download "<< id << ": " << percent; + //BOOST_LOG_TRIVIAL(trace) << "Download "<< id << ": " << percent; ntf_mngr->set_download_URL_progress(id, percent); } void Downloader::on_error(wxCommandEvent& event) @@ -247,7 +260,9 @@ bool Downloader::user_action_callback(DownloaderUserAction action, int id) void Downloader::on_name_change(wxCommandEvent& event) { - + size_t id = event.GetInt(); + NotificationManager* ntf_mngr = wxGetApp().notification_manager(); + ntf_mngr->set_download_URL_filename(id, into_u8(event.GetString())); } void Downloader::on_paused(wxCommandEvent& event) diff --git a/src/slic3r/GUI/DownloaderFileGet.cpp b/src/slic3r/GUI/DownloaderFileGet.cpp index afa08af..d2153c2 100644 --- a/src/slic3r/GUI/DownloaderFileGet.cpp +++ b/src/slic3r/GUI/DownloaderFileGet.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "format.hpp" #include "GUI.hpp" @@ -64,6 +65,26 @@ unsigned get_current_pid() return ::getpid(); #endif } + +std::string extract_filename_from_header(const std::string& headers) { + // Split the headers into lines + std::istringstream header_stream(headers); + std::string line; + + while (std::getline(header_stream, line)) { + if (line.find("content-disposition") != std::string::npos) { + // Apply regex to extract filename from the content-disposition line + std::regex filename_regex("filename\\s*=\\s*\"([^\"]+)\"", std::regex::icase); + std::smatch match; + + if (std::regex_search(line, match, filename_regex) && match.size() > 1) { + return match.str(1); + } + } + } + + return {}; +} } // int = DOWNLOAD ID; string = file path @@ -107,6 +128,8 @@ FileGet::priv::priv(int ID, std::string&& url, const std::string& filename, wxEv , m_dest_folder(dest_folder) , m_load_after(load_after) { + // Prevent ':' in filename + m_filename.erase(std::remove(m_filename.begin(), m_filename.end(), ':'), m_filename.end()); } void FileGet::priv::get_perform() @@ -125,7 +148,7 @@ void FileGet::priv::get_perform() std::string extension = dest_path.extension().string(); std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size()); std::string final_filename = just_filename; - // Find unsed filename + // Find unused filename try { size_t version = 0; while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)) || boost::filesystem::exists(m_dest_folder / (final_filename + extension + "." + std::to_string(get_current_pid()) + ".download"))) @@ -150,7 +173,6 @@ void FileGet::priv::get_perform() } m_filename = final_filename + extension; - m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download"); wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE); @@ -217,7 +239,12 @@ void FileGet::priv::get_perform() m_evt_handler->QueueEvent(evt); return; } - + wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS); + int percent_total = 100; + evt->SetString(std::to_string(percent_total)); + evt->SetInt(m_id); + m_evt_handler->QueueEvent(evt); + if (m_absolute_size < progress.dltotal) { m_absolute_size = progress.dltotal; } @@ -243,13 +270,48 @@ void FileGet::priv::get_perform() m_written = written_previously + written_this_session; } wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS); - int percent_total = (written_previously + progress.dlnow) * 100 / m_absolute_size; + int percent_total = m_absolute_size == 0 ? 0 : (written_previously + progress.dlnow) * 100 / m_absolute_size; evt->SetString(std::to_string(percent_total)); evt->SetInt(m_id); m_evt_handler->QueueEvent(evt); } }) + .on_headers([&](const std::string& headers) { + // we are looking for content-disposition header in response, to use it as correct filename + std::string new_filename = extract_filename_from_header(headers); + if (new_filename.empty()) { + return; + } + // Find unused filename + boost::filesystem::path temp_dest_path = m_dest_folder / new_filename; + std::string extension = temp_dest_path.extension().string(); + std::string just_filename = new_filename.substr(0, new_filename.size() - extension.size()); + std::string final_filename = just_filename; + try { + size_t version = 0; + while (boost::filesystem::exists(m_dest_folder / (final_filename + extension))) + { + ++version; + if (version > 999) { + BOOST_LOG_TRIVIAL(error) << GUI::format("Failed to find suitable filename. Last name: %1%." , (m_dest_folder / (final_filename + extension)).string()); + return; + } + final_filename = GUI::format("%1%(%2%)", just_filename, std::to_string(version)); + } + } catch (const boost::filesystem::filesystem_error& e) + { + BOOST_LOG_TRIVIAL(error) << "Failed to resolved filename from headers."; + return; + } + m_filename = final_filename + extension; + dest_path = m_dest_folder / m_filename; + + wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE); + evt->SetString(from_u8(m_filename)); + evt->SetInt(m_id); + m_evt_handler->QueueEvent(evt); + }) .on_error([&](std::string body, std::string error, unsigned http_status) { if (file != NULL) fclose(file); @@ -264,15 +326,21 @@ void FileGet::priv::get_perform() .on_complete([&](std::string body, unsigned /* http_status */) { try { + // If server is not sending Content-Length header, the progress function does not write all data to file. + // We need to write it now. + if (written_this_session < body.size()) { + std::string part_for_write = body.substr(written_this_session); + fwrite(part_for_write.c_str(), 1, part_for_write.size(), file); + } fclose(file); boost::filesystem::rename(m_tmp_path, dest_path); } - catch (const std::exception& /*e*/) + catch (const std::exception& e) { //TODO: report? //error_message = GUI::format("Failed to write and move %1% to %2%", tmp_path, dest_path); wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR); - evt->SetString("Failed to write and move."); + evt->SetString(GUI::format("Failed to write and move %1% to %2%", m_tmp_path, dest_path)); evt->SetInt(m_id); m_evt_handler->QueueEvent(evt); return; diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 7fadf66..55fdbf1 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -688,7 +688,7 @@ wxWindow* CheckBox::GetNewWin(wxWindow* parent, const wxString& label /*= wxEmpt if (wxGetApp().suppress_round_corners()) return new ::CheckBox(parent, label); - return new ::SwitchButton(parent, label); + return new ::DeviceSwitchButton(parent, label); //y25 } void CheckBox::SetValue(wxWindow* win, bool value) @@ -698,7 +698,7 @@ void CheckBox::SetValue(wxWindow* win, bool value) ch_b->SetValue(value); } else { - if (::SwitchButton* ch_b = dynamic_cast<::SwitchButton*>(win)) + if (::DeviceSwitchButton* ch_b = dynamic_cast<::DeviceSwitchButton*>(win)) //y25 ch_b->SetValue(value); } } @@ -708,7 +708,7 @@ bool CheckBox::GetValue(wxWindow* win) if (wxGetApp().suppress_round_corners()) return dynamic_cast<::CheckBox*>(win)->GetValue(); - return dynamic_cast<::SwitchButton*>(win)->GetValue(); + return dynamic_cast<::DeviceSwitchButton*>(win)->GetValue(); //y25 } void CheckBox::Rescale(wxWindow* win) @@ -716,13 +716,13 @@ void CheckBox::Rescale(wxWindow* win) if (wxGetApp().suppress_round_corners()) dynamic_cast<::CheckBox*>(win)->Rescale(); else - dynamic_cast<::SwitchButton*>(win)->Rescale(); + dynamic_cast<::DeviceSwitchButton*>(win)->Rescale(); //y25 } void CheckBox::SysColorChanged(wxWindow* win) { if (!wxGetApp().suppress_round_corners()) - dynamic_cast<::SwitchButton*>(win)->SysColorChange(); + dynamic_cast<::DeviceSwitchButton*>(win)->SysColorChange(); //y25 } void CheckBox::SetValue(bool value) @@ -730,7 +730,7 @@ void CheckBox::SetValue(bool value) if (wxGetApp().suppress_round_corners()) dynamic_cast<::CheckBox*>(window)->SetValue(value); else - dynamic_cast<::SwitchButton*>(window)->SetValue(value); + dynamic_cast<::DeviceSwitchButton*>(window)->SetValue(value); //y25 } bool CheckBox::GetValue() @@ -738,7 +738,7 @@ bool CheckBox::GetValue() if (wxGetApp().suppress_round_corners()) return dynamic_cast<::CheckBox*>(window)->GetValue(); - return dynamic_cast<::SwitchButton*>(window)->GetValue(); + return dynamic_cast<::DeviceSwitchButton*>(window)->GetValue(); //y25 } void CheckBox::BUILD() { @@ -831,7 +831,7 @@ void CheckBox::msw_rescale() void CheckBox::sys_color_changed() { Field::sys_color_changed(); - if (auto switch_btn = dynamic_cast<::SwitchButton*>(window)) + if (auto switch_btn = dynamic_cast<::DeviceSwitchButton*>(window)) //y25 switch_btn->SysColorChange(); } diff --git a/src/slic3r/GUI/FrequentlyChangedParameters.cpp b/src/slic3r/GUI/FrequentlyChangedParameters.cpp index 642eda3..129012b 100644 --- a/src/slic3r/GUI/FrequentlyChangedParameters.cpp +++ b/src/slic3r/GUI/FrequentlyChangedParameters.cpp @@ -16,6 +16,11 @@ #include "WipeTowerDialog.hpp" +//y25 +#include "SyncBoxInfoDialog.hpp" + +#include "Tab.hpp" + using Slic3r::Preset; using Slic3r::GUI::format_wxstr; @@ -303,12 +308,54 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) m_og_filament->append_line(line); m_og_filament->activate(); + //y25 + m_og_sync = std::make_shared(parent, ""); + DynamicPrintConfig* printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config; + + m_og_sync->set_config(printer_config); + m_og_sync->hide_labels(); + auto add_sync_btn = [this](wxWindow* parent) { + + //y26 + auto sync_btn = new wxButton(parent, wxID_ANY, _L("Syn filament info from the box"), wxDefaultPosition, wxSize(200, 30), wxBU_EXACTFIT); + wxGetApp().UpdateDarkUI(sync_btn, true); + + sync_btn->SetToolTip(_L("Click the sync button to synchronize the Box information to the filament column.")); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(sync_btn, 0, wxALIGN_CENTER_VERTICAL); + sync_btn->Bind(wxEVT_BUTTON, [parent](wxCommandEvent& e){ + //y25 + std::string ph_host = ""; + bool has_select_printer = wxGetApp().preset_bundle->physical_printers.has_selection(); + if (has_select_printer) { + PhysicalPrinter& ph_printer = wxGetApp().preset_bundle->physical_printers.get_selected_printer(); + ph_host = ph_printer.config.opt_string("print_host"); + } + + GetBoxInfoDialog dlg(wxGetApp().plater()); + if(ph_host.empty()){ + dlg.ShowModal(); + } + else{ + dlg.synchronize_by_ip(ph_host); + } + }); + return sizer; + }; + line = Line { "", "" }; + line.append_only_widget(add_sync_btn); + m_og_sync->append_line(line); + m_og_sync->activate(); + m_sizer = new wxBoxSizer(wxVERTICAL); m_sizer->Add(m_og_fff->sizer, 0, wxEXPAND); //Y26 m_sizer->Add(m_og_filament->sizer, 0, wxEXPAND); m_sizer->Add(m_og_sla->sizer, 0, wxEXPAND); + + //y25 + m_sizer->Add(m_og_sync->sizer, 0, wxEXPAND); } void FreqChangedParams::msw_rescale() @@ -339,7 +386,8 @@ void FreqChangedParams::Show(bool is_fff) const //Y26 m_og_filament->Show(is_fff); m_og_sla->Show(!is_fff); - + //y25 + m_og_sync->Show(is_fff); // correct showing of the FreqChangedParams sizer when m_wiping_dialog_button is hidden if (is_fff && !is_wdb_shown) m_wiping_dialog_button->Hide(); diff --git a/src/slic3r/GUI/FrequentlyChangedParameters.hpp b/src/slic3r/GUI/FrequentlyChangedParameters.hpp index 99de251..88f754d 100644 --- a/src/slic3r/GUI/FrequentlyChangedParameters.hpp +++ b/src/slic3r/GUI/FrequentlyChangedParameters.hpp @@ -24,6 +24,8 @@ class FreqChangedParams //Y26 std::shared_ptr m_og_filament; + //y25 + std::shared_ptr m_og_sync; std::shared_ptr m_og_fff; std::shared_ptr m_og_sla; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 3e562a5..6fb8690 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1473,7 +1473,8 @@ bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelI //B52 for (unsigned int vol_idx : volumes_idxs) { GLVolume* volume = volumes.volumes[vol_idx]; - if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (!volume->is_wipe_tower() && volume->composite_id.volume_id >= 0))) { + //y25 + if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled && (!volume->is_wipe_tower() && volume->composite_id.volume_id >= 0))) { BuildVolume::ObjectState state; int bed_idx = -1; if (volume_below(*volume)) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index d1fcbb5..8cc9acd 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -880,8 +880,21 @@ void GLGizmoSlaSupports::draw_island_config() { ImGui::SameLine(); ImGui::Text("head radius %.2f mm", unscale(sample_config.head_radius)); - bool exist_change = false; + // copied from SLAPrint::Steps::support_points() + const SLAPrintObject *po = m_c->selection_info()->print_object(); + const SLAPrintObjectConfig &cfg = po->config(); + float head_diameter = (cfg.support_tree_type == sla::SupportTreeType::Branching) ? + float(cfg.branchingsupport_head_front_diameter): + float(cfg.support_head_front_diameter); // SupportTreeType::Organic + std::string button_title = "apply " + std::to_string(head_diameter); + ImGui::SameLine(); + if (ImGui::Button(button_title.c_str())) { + float density_relative = float(cfg.support_points_density_relative / 100.f); + sample_config = sla::SampleConfigFactory::apply_density( + sla::SampleConfigFactory::create(head_diameter), density_relative); + } + bool exist_change = false; if (float max_for_one = unscale(sample_config.max_length_for_one_support_point); // [in mm] ImGui::InputFloat("One support", &max_for_one, .1f, 1.f, "%.2f mm")) { sample_config.max_length_for_one_support_point = scale_(max_for_one); @@ -1457,7 +1470,7 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog() SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); const wxString ctrl = GUI::shortkey_ctrl_prefix(); const wxString alt = GUI::shortkey_alt_prefix(); - + const wxString shift = wxString("Shift+"); // fonts const wxFont& font = wxGetApp().small_font(); @@ -1484,9 +1497,9 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog() shortcuts.push_back(std::make_pair(_L("Left click"), _L("Add point"))); shortcuts.push_back(std::make_pair(_L("Right click"), _L("Remove point"))); shortcuts.push_back(std::make_pair(_L("Drag"), _L("Move point"))); - shortcuts.push_back(std::make_pair(ctrl+_L("Left click"), _L("Add point to selection"))); + shortcuts.push_back(std::make_pair(shift+_L("Left click"), _L("Add point to selection"))); shortcuts.push_back(std::make_pair(alt+_L("Left click"), _L("Remove point from selection"))); - shortcuts.push_back(std::make_pair(wxString("Shift+")+_L("Drag"), _L("Select by rectangle"))); + shortcuts.push_back(std::make_pair(shift+_L("Drag"), _L("Select by rectangle"))); shortcuts.push_back(std::make_pair(alt+_(L("Drag")), _L("Deselect by rectangle"))); shortcuts.push_back(std::make_pair(ctrl+"A", _L("Select all points"))); shortcuts.push_back(std::make_pair("Delete", _L("Remove selected points"))); diff --git a/src/slic3r/GUI/LoadStepDialog.cpp b/src/slic3r/GUI/LoadStepDialog.cpp new file mode 100644 index 0000000..f695ee4 --- /dev/null +++ b/src/slic3r/GUI/LoadStepDialog.cpp @@ -0,0 +1,259 @@ +///|/ Copyright (c) Prusa Research 2018 - 2023 Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena, Oleksandra Iushchenko @YuSanka, Enrico Turri @enricoturri1966, Tomáš Mészáros @tamasmeszaros, David Kocík @kocikdav, Lukáš Hejl @hejllukas, Pavel Mikuš @Godrak, Filip Sykala @Jony01, Vojtěch Král @vojtechkral +///|/ Copyright (c) 2022 Michael Kirsch +///|/ Copyright (c) 2021 Boleslaw Ciesielski +///|/ Copyright (c) 2019 John Drake @foxox +///|/ +///|/ ported from lib/Slic3r/GUI/Plater.pm: +///|/ Copyright (c) Prusa Research 2016 - 2019 Vojtěch Bubník @bubnikv, Vojtěch Král @vojtechkral, Enrico Turri @enricoturri1966, Oleksandra Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Tomáš Mészáros @tamasmeszaros +///|/ Copyright (c) 2018 Martin Loidl @LoidlM +///|/ Copyright (c) 2017 Matthias Gazzari @qtux +///|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel +///|/ Copyright (c) 2017 Joseph Lenox @lordofhyphens +///|/ Copyright (c) 2015 Daren Schwenke +///|/ Copyright (c) 2014 Mark Hindess +///|/ Copyright (c) 2012 Mike Sheldrake @mesheldrake +///|/ Copyright (c) 2012 Henrik Brix Andersen @henrikbrixandersen +///|/ Copyright (c) 2012 Sam Wong +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/ + +#include "LoadStepDialog.hpp" +#include +#include +#include +#include +#include +#include +#include + +#include "GUI_App.hpp" +#include "format.hpp" +#include "MsgDialog.hpp" +#include "Widgets/CheckBox.hpp" + +namespace Slic3r::GUI { + +static std::vector> default_step_import_params = { + {"Low" , {0.005, 1. }}, + {"Medium" , {0.003, 0.5 }}, + {"High" , {0.001, 0.25}}, +}; + +LoadStepDialog::LoadStepDialog(wxWindow* parent, const std::string& filename, double linear_precision, double angle_precision, bool multiple_loading) + : DPIDialog(parent, wxID_ANY, format_wxstr(_L("STEP import quality (%1%)"), filename), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + m_params({ linear_precision, angle_precision }) +{ + +#ifdef _WIN32 + wxGetApp().UpdateDarkUI(this); +#else + //SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif + const wxFont& font = wxGetApp().normal_font(); + SetFont(font); + + // Call your custom function manually after constructing base + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); // Get the sizer + + add_params(main_sizer); + + main_sizer->Add(new StaticLine(this), 0, wxEXPAND | wxLEFT | wxRIGHT, em_unit()); + + wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); + m_remember_chb = new ::CheckBox(this, _L("Remember my choice")); + + bottom_sizer->Add(m_remember_chb, 0, wxEXPAND | wxRIGHT, 5); + bottom_sizer->AddStretchSpacer(); + + auto buttons_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); + + if (multiple_loading) { + auto apply_btn = new wxButton(this, wxID_APPLY, _L("Apply to all")); + apply_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) { + m_apply_to_all = true; + EndModal(wxID_OK); + }); + buttons_sizer->Insert(0, apply_btn, 0, wxRIGHT, 5); + } + + bottom_sizer->Add(buttons_sizer, 0, wxEXPAND | wxLEFT, 5); + main_sizer->Add(bottom_sizer, 0, wxEXPAND | wxALL, 10); + + SetSizer(main_sizer); + main_sizer->SetSizeHints(this); + + enable_customs(!m_default); + + // Update DarkUi just for buttons + wxGetApp().UpdateDlgDarkUI(this, true); + +} + +void LoadStepDialog::add_params(wxSizer* sizer) +{ + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Select requested quality of the mesh after import: "))); + + // add radio buttons for selection default parameters + + for (const auto& [name, params] : default_step_import_params) { + wxRadioButton* radio_def = new wxRadioButton(this, wxID_ANY, format_wxstr("%1%", _(name))); + radio_def->Bind(wxEVT_RADIOBUTTON, [params_copy = params, this](wxEvent&) { + m_params.linear = params_copy.linear; + m_params.angle = params_copy.angle; + + enable_customs(false); + }); + bool is_selected = m_params.linear == params.linear && m_params.angle == params.angle; + radio_def->SetValue(is_selected); + + m_default |= is_selected; + + main_sizer->Add(radio_def, 0, wxLEFT | wxTOP, em_unit()); + } + + // add radio buttons for set custom parameters + + wxRadioButton* radio_custom = new wxRadioButton(this, wxID_ANY, _L("Custom")); + radio_custom->Bind(wxEVT_RADIOBUTTON, [&, this](wxEvent&) { + enable_customs(true); +#ifdef __linux__ + this->Fit(); +#endif // __linux__ + m_params.linear = string_to_double_decimal_point(m_linear_precision_val->GetValue().ToStdString()); + m_params.angle = string_to_double_decimal_point(m_angle_precision_val->GetValue().ToStdString()); + }); + + main_sizer->Add(radio_custom, 0, wxLEFT | wxTOP, em_unit()); + radio_custom->SetValue(!m_default); + + long slyder_style = wxSL_HORIZONTAL | wxSL_TICKS; + long text_ctrl_style = wxTE_PROCESS_ENTER; +#ifdef _WIN32 + text_ctrl_style |= wxBORDER_SIMPLE; +#endif + + const wxSize def_slider_size = wxSize(15 * em_unit(), wxDefaultCoord); + const wxSize def_editor_size = wxSize(5 * em_unit(), wxDefaultCoord); + + const int hgap = 5; + wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(4, em_unit(), hgap); + grid_sizer->SetFlexibleDirection(wxBOTH); + grid_sizer->AddGrowableCol(1, 1); + grid_sizer->AddGrowableRow(0, 1); + grid_sizer->AddGrowableRow(1, 1); + + wxBoxSizer* labels_sizer = new wxBoxSizer(wxHORIZONTAL); + { + const wxString left_text = _L("Lower quality"); + const int left_text_gap = std::max(GetTextExtent(_L("Linear precision")).x, GetTextExtent(_L("Angle precision")).x) + 4 * hgap - GetTextExtent(left_text).x * 0.5; + const wxString right_text = _L("Higher quality"); + const int right_text_gap = GetTextExtent(_L("mm")).x + def_editor_size.x + 4 * hgap - GetTextExtent(right_text).x * 0.5; + labels_sizer->Add(new wxStaticText(this, wxID_ANY, left_text), 0, wxLEFT, left_text_gap); + labels_sizer->Add(new wxStaticText(this, wxID_ANY, wxEmptyString), 1, wxEXPAND); + labels_sizer->Add(new wxStaticText(this, wxID_ANY, right_text), 0, wxRIGHT, right_text_gap); + } + + auto high_vals = std::find_if(default_step_import_params.begin(), default_step_import_params.end(), + [](const std::pair& val) { return val.first == "High"; }); + auto low_vals = std::find_if(default_step_import_params.begin(), default_step_import_params.end(), + [](const std::pair& val) { return val.first == "Low"; }); + assert(high_vals != default_step_import_params.end() && low_vals != default_step_import_params.end()); + + m_linear_precision_sl.init(high_vals->second.linear, low_vals->second.linear, 0.001); + m_angle_precision_sl.init(high_vals->second.angle, low_vals->second.angle, 0.01); + + auto process_value_change = [](double& precision, wxTextCtrl* text_ctrl, wxSlider* slider, const SliderHelper& sl_helper) -> void { + wxString str_val = text_ctrl->GetValue(); + double val = string_to_double_decimal_point(str_val.ToStdString()); + precision = sl_helper.adjust_to_region(val); + slider->SetValue(sl_helper.get_pos(precision)); + + if (wxString str_precision = format_wxstr("%1%", precision); str_precision != str_val) + text_ctrl->SetValue(str_precision); + }; + + auto tooltip = [](const SliderHelper& sl_helper) -> wxString { + // TRN %n% contain min, max and step values respectively + return format_wxstr(_L("Set value from the range [%1%; %2%] with %3% step"), + sl_helper.min_val, sl_helper.max_val, sl_helper.val_step); + }; + + // Add "Linear precision" + + m_linear_precision_slider = new wxSlider(this, wxID_ANY, m_linear_precision_sl.get_pos(m_params.linear), m_linear_precision_sl.beg_sl_pos, m_linear_precision_sl.end_sl_pos, wxDefaultPosition, def_slider_size, slyder_style); + m_linear_precision_slider->SetTickFreq(1); + m_linear_precision_slider->Bind(wxEVT_SLIDER, [this](wxCommandEvent e) { + m_params.linear = m_linear_precision_sl.get_value(m_linear_precision_slider->GetValue()); + m_linear_precision_val->SetValue(format_wxstr("%1%", m_params.linear)); + }); + + m_linear_precision_val = new wxTextCtrl(this, wxID_ANY, format_wxstr("%1%", m_linear_precision_sl.adjust_to_region(m_params.linear)), wxDefaultPosition, def_editor_size, text_ctrl_style); + m_linear_precision_val->SetToolTip(tooltip(m_linear_precision_sl)); + + m_linear_precision_val->Bind(wxEVT_TEXT_ENTER, [process_value_change, this](wxCommandEvent& e) { + process_value_change(m_params.linear, m_linear_precision_val, m_linear_precision_slider, m_linear_precision_sl); + }); + m_linear_precision_val->Bind(wxEVT_KILL_FOCUS, [process_value_change, this](wxFocusEvent& e) { + process_value_change(m_params.linear, m_linear_precision_val, m_linear_precision_slider, m_linear_precision_sl); + e.Skip(); + }); + + grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Linear precision") + ": "), 0, wxALIGN_CENTER_VERTICAL); + grid_sizer->Add(m_linear_precision_slider, 1, wxEXPAND); + grid_sizer->Add(m_linear_precision_val, 0, wxALIGN_CENTER_VERTICAL); + grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("mm")), 0, wxALIGN_CENTER_VERTICAL); + + // Add "Angle precision" + + m_angle_precision_slider = new wxSlider(this, wxID_ANY, m_angle_precision_sl.get_pos(m_params.angle), m_angle_precision_sl.beg_sl_pos, m_angle_precision_sl.end_sl_pos, wxDefaultPosition, def_slider_size, slyder_style); + m_angle_precision_slider->SetTickFreq(5); + m_angle_precision_slider->Bind(wxEVT_SLIDER, [this](wxCommandEvent e) { + m_params.angle = m_angle_precision_sl.get_value(m_angle_precision_slider->GetValue()); + m_angle_precision_val->SetValue(format_wxstr("%1%", m_params.angle)); + }); + + m_angle_precision_val = new wxTextCtrl(this, wxID_ANY, format_wxstr("%1%", m_angle_precision_sl.adjust_to_region(m_params.angle)), wxDefaultPosition, def_editor_size, text_ctrl_style); + m_angle_precision_val->SetToolTip(tooltip(m_angle_precision_sl)); + + m_angle_precision_val->Bind(wxEVT_TEXT_ENTER, [process_value_change, this](wxCommandEvent& e) { + process_value_change(m_params.angle, m_angle_precision_val, m_angle_precision_slider, m_angle_precision_sl); + }); + m_angle_precision_val->Bind(wxEVT_KILL_FOCUS, [process_value_change, this](wxFocusEvent& e) { + process_value_change(m_params.angle, m_angle_precision_val, m_angle_precision_slider, m_angle_precision_sl); + e.Skip(); + }); + + grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Angle precision") + ": "), 0, wxALIGN_CENTER_VERTICAL); + grid_sizer->Add(m_angle_precision_slider, 1, wxEXPAND); + grid_sizer->Add(m_angle_precision_val, 0, wxALIGN_CENTER_VERTICAL); + grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("°")), 0, wxALIGN_CENTER_VERTICAL); + + m_custom_sizer = new wxBoxSizer(wxVERTICAL); + m_custom_sizer->Add(labels_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, em_unit()); + m_custom_sizer->Add(grid_sizer, 1, wxEXPAND); + + main_sizer->Add(m_custom_sizer, 1, wxEXPAND | wxLEFT, 3 * em_unit()); + sizer->Add(main_sizer, 1, wxEXPAND | wxALL, em_unit()); +} + +void LoadStepDialog::enable_customs(bool enable) +{ + m_linear_precision_slider->Enable(enable); + m_linear_precision_val->Enable(enable); + m_angle_precision_slider->Enable(enable); + m_angle_precision_val->Enable(enable); +} + +bool LoadStepDialog::IsCheckBoxChecked() +{ + return m_remember_chb && m_remember_chb->GetValue(); +} + +bool LoadStepDialog::IsApplyToAllClicked() +{ + return m_apply_to_all; +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/LoadStepDialog.hpp b/src/slic3r/GUI/LoadStepDialog.hpp new file mode 100644 index 0000000..779aa3d --- /dev/null +++ b/src/slic3r/GUI/LoadStepDialog.hpp @@ -0,0 +1,100 @@ +///|/ Copyright (c) Prusa Research 2018 - 2025 Oleksandra Iushchenko @YuSanka +///|/ +///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher +///|/ + +#ifndef slic3r_LoadStepDialog_hpp_ +#define slic3r_LoadStepDialog_hpp_ + +#include +#include +#include "GUI_Utils.hpp" + +class wxBoxSizer; +class wxTextCtrl; +class wxSlider; +class CheckBox; + +namespace Slic3r::GUI { + +struct PrecisionParams +{ + double linear; + double angle; +}; + +struct SliderHelper +{ + double min_val; + double max_val; + double val_step; + int beg_sl_pos; + int end_sl_pos; + + void init(double min, double max, double step, int beg_pos = 1) { + assert(val_step != 0.); + min_val = min; + max_val = max; + val_step = step; + + beg_sl_pos = beg_pos; + end_sl_pos = beg_sl_pos + int(double(max_val - min_val) / val_step); + } + + double get_value(int pos) const { + return max_val - val_step * (pos - beg_sl_pos); + } + + int get_pos(double value) const { + return beg_sl_pos + int((max_val - value) / val_step); + } + + double adjust_to_region(double value) const { + return std::max(std::min(value, max_val), min_val); + } +}; + +class LoadStepDialog : public DPIDialog +{ +public: + LoadStepDialog(wxWindow* parent, const std::string& filename, double linear_precision, double angle_precision, bool multiple_loading); + ~LoadStepDialog() = default; + + bool IsCheckBoxChecked(); + bool IsApplyToAllClicked(); + + double get_linear_precision() { return m_params.linear; } + double get_angle_precision() { return m_params.angle; } + +protected: + void on_dpi_changed(const wxRect& suggested_rect) override {} + void on_sys_color_changed() override {}; + + +private: + void add_params(wxSizer* sizer); + void enable_customs(bool enable); + +private: + PrecisionParams m_params; + + ::CheckBox* m_remember_chb { nullptr }; + + wxTextCtrl* m_linear_precision_val { nullptr }; + wxTextCtrl* m_angle_precision_val { nullptr }; + + wxSlider* m_linear_precision_slider { nullptr }; + wxSlider* m_angle_precision_slider { nullptr }; + + wxBoxSizer* m_custom_sizer { nullptr }; + + bool m_default { false }; + bool m_apply_to_all { false }; + + SliderHelper m_linear_precision_sl; + SliderHelper m_angle_precision_sl; +}; + +} // namespace Slic3r::GUI + +#endif diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 639e820..5ac7292 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -1128,6 +1128,11 @@ void NotificationManager::URLDownloadWithPrintablesLinkNotification::render_text } //------URLDownloadNotification---------------- +void NotificationManager::URLDownloadNotification::set_filename(const std::string& filename_line) +{ + m_text1 = filename_line; + init(); +} void NotificationManager::URLDownloadNotification::render_close_button(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) { @@ -2642,6 +2647,19 @@ void NotificationManager::set_download_URL_progress(size_t id, float percentage) } } } +void NotificationManager::set_download_URL_filename(size_t id, const std::string& filename) +{ + for (std::unique_ptr& notification : m_pop_notifications) { + if (notification->get_type() == NotificationType::URLDownload) { + URLDownloadNotification* ntf = dynamic_cast(notification.get()); + if (ntf->get_download_id() != id) + continue; + ntf->set_filename(_u8L("Download") + ": " + filename); + wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); + return; + } + } +} void NotificationManager::set_download_URL_paused(size_t id) { diff --git a/src/slic3r/GUI/NotificationManager.hpp b/src/slic3r/GUI/NotificationManager.hpp index 635087b..f40e14f 100644 --- a/src/slic3r/GUI/NotificationManager.hpp +++ b/src/slic3r/GUI/NotificationManager.hpp @@ -256,6 +256,7 @@ public: void set_download_URL_paused(size_t id); void set_download_URL_canceled(size_t id); void set_download_URL_error(size_t id, const std::string& text); + void set_download_URL_filename(size_t id, const std::string& filename); // slicing progress void init_slicing_progress_notification(std::function cancel_callback); void set_slicing_progress_began(); @@ -563,6 +564,7 @@ private: void set_paused(bool paused) { m_download_paused = paused; } void set_error_message(const std::string& message) { m_error_message = message; } bool compare_text(const std::string& text) const override { return false; }; + void set_filename(const std::string& filename_line); protected: void render_close_button(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y) override; diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 152dea5..814ebf5 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -405,6 +405,14 @@ void OptionsGroup::activate_line(Line& line) } } + //y25 + if (!line.get_only_widgets().empty()){ + for (auto only_widget : line.get_only_widgets()) { + sizer->Add(only_widget(this->ctrl_parent()), 0, wxEXPAND); + } + return; + } + const std::vector