mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-24 00:28:38 -07:00
Merge branch 'main' into enh-spoolman-support
This commit is contained in:
commit
9c484f2372
74 changed files with 790 additions and 245 deletions
|
|
@ -10,5 +10,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "45",
|
||||
"initial_layer_speed": "25",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25",
|
||||
"gap_infill_speed": "45",
|
||||
"small_perimeter_speed": "45",
|
||||
"outer_wall_speed": "45"
|
||||
}
|
||||
|
|
@ -10,5 +10,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "45",
|
||||
"initial_layer_speed": "25",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25",
|
||||
"gap_infill_speed": "45",
|
||||
"small_perimeter_speed": "45",
|
||||
"outer_wall_speed": "45"
|
||||
}
|
||||
|
|
@ -13,5 +13,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "100",
|
||||
"initial_layer_speed": "45",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.4"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.4",
|
||||
"small_perimeter_speed": "145",
|
||||
"inner_wall_speed": "145",
|
||||
"outer_wall_speed": "145"
|
||||
}
|
||||
|
|
@ -4,9 +4,9 @@
|
|||
"inherits": "0.10mm STRUCTURAL @MK4S 0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"inner_wall_speed": "80",
|
||||
"small_perimeter_speed": "45",
|
||||
"outer_wall_speed": "45",
|
||||
"inner_wall_speed": "70",
|
||||
"small_perimeter_speed": "50",
|
||||
"outer_wall_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -10,5 +10,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "45",
|
||||
"initial_layer_speed": "25",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25",
|
||||
"small_perimeter_speed": "150",
|
||||
"outer_wall_speed": "150",
|
||||
"inner_wall_speed": "150"
|
||||
}
|
||||
|
|
@ -10,5 +10,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "45",
|
||||
"initial_layer_speed": "25",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25",
|
||||
"gap_infill_speed": "45",
|
||||
"small_perimeter_speed": "45",
|
||||
"outer_wall_speed": "45"
|
||||
}
|
||||
|
|
@ -12,5 +12,8 @@
|
|||
"initial_layer_infill_speed": "60",
|
||||
"initial_layer_speed": "45",
|
||||
"top_surface_acceleration": "1500",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3",
|
||||
"small_perimeter_speed": "45",
|
||||
"inner_wall_speed": "70",
|
||||
"outer_wall_speed": "45"
|
||||
}
|
||||
|
|
@ -10,5 +10,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "45",
|
||||
"initial_layer_speed": "25",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25",
|
||||
"small_perimeter_speed": "150",
|
||||
"inner_wall_speed": "150",
|
||||
"outer_wall_speed": "150"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.15mm SPEED @MK4S 0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -16,5 +16,6 @@
|
|||
"internal_solid_infill_acceleration": "6000",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"support_threshold_angle": "35"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.15mm SPEED @MK4S HF0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_1_4_speed": "50",
|
||||
"overhang_3_4_speed": "60%",
|
||||
"sparse_infill_speed": "300",
|
||||
"travel_speed": "350",
|
||||
|
|
@ -18,5 +18,6 @@
|
|||
"internal_solid_infill_acceleration": "6000",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"support_threshold_angle": "35"
|
||||
}
|
||||
|
|
@ -10,5 +10,8 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "45",
|
||||
"initial_layer_speed": "25",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.25",
|
||||
"gap_infill_speed": "45",
|
||||
"small_perimeter_speed": "45",
|
||||
"outer_wall_speed": "45"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.15mm STRUCTURAL @MK4S 0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"sparse_infill_speed": "120",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.15mm STRUCTURAL @MK4S 0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
"inherits": "0.15mm STRUCTURAL @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"inner_wall_speed": "80",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"inner_wall_speed": "70",
|
||||
"overhang_3_4_speed": "30",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -18,5 +18,6 @@
|
|||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.6",
|
||||
"inner_wall_acceleration": "2500",
|
||||
"outer_wall_acceleration": "1500",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"gap_infill_speed": "70"
|
||||
}
|
||||
|
|
@ -13,5 +13,8 @@
|
|||
"initial_layer_infill_speed": "60",
|
||||
"initial_layer_speed": "45",
|
||||
"top_surface_acceleration": "1500",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3",
|
||||
"small_perimeter_speed": "160",
|
||||
"inner_wall_speed": "160",
|
||||
"outer_wall_speed": "160"
|
||||
}
|
||||
|
|
@ -12,5 +12,8 @@
|
|||
"initial_layer_infill_speed": "60",
|
||||
"initial_layer_speed": "45",
|
||||
"top_surface_acceleration": "1500",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3",
|
||||
"small_perimeter_speed": "50",
|
||||
"inner_wall_speed": "70",
|
||||
"outer_wall_speed": "50"
|
||||
}
|
||||
|
|
@ -4,12 +4,15 @@
|
|||
"inherits": "0.20mm SOLUBLE FULL @MK4S 0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.4 and printer_notes!~/.*HF_NOZZLE.*/",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "100",
|
||||
"initial_layer_speed": "45"
|
||||
"initial_layer_speed": "45",
|
||||
"small_perimeter_speed": "50",
|
||||
"inner_wall_speed": "70",
|
||||
"outer_wall_speed": "50"
|
||||
}
|
||||
|
|
@ -4,12 +4,15 @@
|
|||
"inherits": "0.20mm SOLUBLE INTERFACE @MK4S 0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.4 and printer_notes!~/.*HF_NOZZLE.*/",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "100",
|
||||
"initial_layer_speed": "45"
|
||||
"initial_layer_speed": "45",
|
||||
"small_perimeter_speed": "50",
|
||||
"inner_wall_speed": "70",
|
||||
"outer_wall_speed": "50"
|
||||
}
|
||||
|
|
@ -13,5 +13,8 @@
|
|||
"initial_layer_infill_speed": "60",
|
||||
"initial_layer_speed": "45",
|
||||
"top_surface_acceleration": "1500",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3",
|
||||
"small_perimeter_speed": "160",
|
||||
"inner_wall_speed": "160",
|
||||
"outer_wall_speed": "160"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.20mm SPEED @MK4S 0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -16,5 +16,6 @@
|
|||
"internal_solid_infill_acceleration": "6000",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"support_threshold_angle": "35"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.20mm SPEED @MK4S 0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.20mm SPEED @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"overhang_3_4_speed": "30",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -17,5 +17,8 @@
|
|||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.6 and printer_notes!~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"small_perimeter_speed": "130",
|
||||
"inner_wall_speed": "130",
|
||||
"outer_wall_speed": "130"
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.20mm SPEED @MK4S HF0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "60%",
|
||||
"overhang_3_4_speed": "50",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"sparse_infill_speed": "300",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
|
|
@ -18,5 +18,6 @@
|
|||
"internal_solid_infill_acceleration": "6000",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"support_threshold_angle": "35"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.20mm SPEED @MK4S HF0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.20mm SPEED @MK4S HF0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"overhang_3_4_speed": "30",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -12,5 +12,8 @@
|
|||
"initial_layer_infill_speed": "60",
|
||||
"initial_layer_speed": "45",
|
||||
"top_surface_acceleration": "1500",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.3",
|
||||
"small_perimeter_speed": "50",
|
||||
"inner_wall_speed": "70",
|
||||
"outer_wall_speed": "50"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.20mm STRUCTURAL @MK4S 0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.20mm STRUCTURAL @MK4S 0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.20mm STRUCTURAL @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "30",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.25mm SPEED @MK4S 0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.25mm SPEED @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"overhang_3_4_speed": "30",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -17,5 +17,8 @@
|
|||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.6 and printer_notes!~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"small_perimeter_speed": "75",
|
||||
"inner_wall_speed": "95",
|
||||
"outer_wall_speed": "75"
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.25mm SPEED @MK4S HF0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "60%",
|
||||
"overhang_3_4_speed": "50",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"sparse_infill_speed": "300",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
|
|
@ -13,10 +13,11 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "100",
|
||||
"initial_layer_speed": "45",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.4 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.4 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"sparse_infill_acceleration": "7000",
|
||||
"internal_solid_infill_acceleration": "6000",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"top_surface_acceleration": "2000",
|
||||
"support_threshold_angle": "35"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.25mm SPEED @MK4S HF0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.25mm SPEED @MK4S HF0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"overhang_3_4_speed": "30",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.25mm STRUCTURAL @MK4S 0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.25mm STRUCTURAL @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "30",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.25mm STRUCTURAL @MK4S HF0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.28mm DRAFT @MK4S HF0.4",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"support_threshold_angle": "35",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"inner_wall_acceleration": "6000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.30mm DETAIL @MK4S 0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "35",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "35",
|
||||
"top_surface_acceleration": "2000",
|
||||
"inner_wall_acceleration": "2500",
|
||||
"internal_solid_infill_acceleration": "5000",
|
||||
"sparse_infill_acceleration": "7000",
|
||||
|
|
@ -15,5 +15,6 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "55",
|
||||
"initial_layer_speed": "45",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes!~/.*HF_NOZZLE.*/"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes!~/.*HF_NOZZLE.*/",
|
||||
"gap_infill_speed": "45"
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.30mm SPEED @MK4S HF0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "45",
|
||||
"top_surface_acceleration": "2000",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.30mm STRUCTURAL @MK4S HF0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "40",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "40",
|
||||
"top_surface_acceleration": "2000",
|
||||
"support_speed": "100",
|
||||
"support_interface_speed": "55%",
|
||||
"travel_speed": "350",
|
||||
|
|
@ -18,6 +18,5 @@
|
|||
"sparse_infill_acceleration": "6000",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_acceleration": "2500",
|
||||
"outer_wall_acceleration": "1500",
|
||||
"top_surface_acceleration": "2000"
|
||||
"outer_wall_acceleration": "1500"
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.32mm SPEED @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"overhang_3_4_speed": "30",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.32mm SPEED @MK4S HF0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "50",
|
||||
"overhang_3_4_speed": "50",
|
||||
"support_interface_speed": "50%",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
"inherits": "0.32mm SPEED @MK4S HF0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "35",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "35",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"top_surface_acceleration": "2000",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -17,6 +17,5 @@
|
|||
"sparse_infill_acceleration": "7000",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.6 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"outer_wall_acceleration": "3000"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.32mm STRUCTURAL @MK4S 0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "30",
|
||||
"overhang_3_4_speed": "30",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.32mm STRUCTURAL @MK4S HF0.5",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"overhang_3_4_speed": "45",
|
||||
"support_speed": "120",
|
||||
"support_interface_speed": "50%",
|
||||
"travel_speed": "350",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.32mm STRUCTURAL @MK4S HF0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "35",
|
||||
"overhang_3_4_speed": "35",
|
||||
"support_speed": "110",
|
||||
"support_interface_speed": "50%",
|
||||
"travel_speed": "350",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.40mm QUALITY @MK4S 0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "35",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "35",
|
||||
"top_surface_acceleration": "2000",
|
||||
"inner_wall_acceleration": "2500",
|
||||
"internal_solid_infill_acceleration": "5000",
|
||||
"sparse_infill_acceleration": "7000",
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
"inherits": "0.40mm SPEED @MK4S HF0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "35",
|
||||
"overhang_3_4_speed": "70%",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "35",
|
||||
"overhang_4_4_speed": "70%",
|
||||
"top_surface_acceleration": "2000",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -17,6 +17,5 @@
|
|||
"sparse_infill_acceleration": "7000",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.6 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_acceleration": "6000",
|
||||
"outer_wall_acceleration": "3000",
|
||||
"top_surface_acceleration": "2000"
|
||||
"outer_wall_acceleration": "3000"
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.40mm SPEED @MK4S HF0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "45",
|
||||
"top_surface_acceleration": "2000",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -14,5 +14,7 @@
|
|||
"initial_layer_speed": "45",
|
||||
"internal_solid_infill_acceleration": "5000",
|
||||
"sparse_infill_acceleration": "7000",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes=~/.*HF_NOZZLE.*/"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"small_perimeter_speed": "85",
|
||||
"outer_wall_speed": "85"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.40mm STRUCTURAL @MK4S HF0.6",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "35",
|
||||
"overhang_3_4_speed": "35",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.40mm STRUCTURAL @MK4S HF0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "40",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "40",
|
||||
"top_surface_acceleration": "2000",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
@ -16,6 +16,5 @@
|
|||
"sparse_infill_acceleration": "6000",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes=~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_acceleration": "2500",
|
||||
"outer_wall_acceleration": "1500",
|
||||
"top_surface_acceleration": "2000"
|
||||
"outer_wall_acceleration": "1500"
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"inherits": "0.55mm DRAFT @MK4S 0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"top_surface_speed": "2000",
|
||||
"top_surface_acceleration": "2000",
|
||||
"inner_wall_acceleration": "2500",
|
||||
"internal_solid_infill_acceleration": "5000",
|
||||
"sparse_infill_acceleration": "7000",
|
||||
|
|
@ -14,5 +14,6 @@
|
|||
"support_interface_top_layers": "3",
|
||||
"initial_layer_infill_speed": "55",
|
||||
"initial_layer_speed": "45",
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes!~/.*HF_NOZZLE.*/"
|
||||
"compatible_printers_condition": "printer_notes=~/.*PRINTER_MODEL_COREONE.*/ and nozzle_diameter[0]==0.8 and printer_notes!~/.*HF_NOZZLE.*/",
|
||||
"inner_wall_speed": "45"
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
"inherits": "0.55mm SPEED @MK4S HF0.8",
|
||||
"from": "system",
|
||||
"instantiation": "true",
|
||||
"overhang_2_4_speed": "45",
|
||||
"top_surface_speed": "2000",
|
||||
"overhang_3_4_speed": "45",
|
||||
"top_surface_acceleration": "2000",
|
||||
"travel_speed": "350",
|
||||
"travel_acceleration": "7000",
|
||||
"default_acceleration": "3000",
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@ ROOT_DIR="$(dirname "$0")/.."
|
|||
|
||||
cd "${ROOT_DIR}" || exit 1
|
||||
|
||||
ctest --test-dir build/tests --output-junit "$(pwd)/ctest_results.xml" --output-on-failure -j
|
||||
ctest --test-dir build/tests -L "Http|PlaceholderParser" --output-junit "$(pwd)/ctest_results.xml" --output-on-failure -j
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ Clipper2Lib::Paths64 Slic3rPoints_to_Paths64(const Container& in)
|
|||
return out;
|
||||
}
|
||||
|
||||
Clipper2Lib::Paths64 Slic3rPolylines_to_Paths64(const Polylines& in)
|
||||
{
|
||||
return Slic3rPoints_to_Paths64(in);
|
||||
}
|
||||
|
||||
Points Path64ToPoints(const Clipper2Lib::Path64& path64)
|
||||
{
|
||||
Points points;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@
|
|||
#include "ExPolygon.hpp"
|
||||
#include "Polygon.hpp"
|
||||
#include "Polyline.hpp"
|
||||
#include "clipper2/clipper.h"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
Clipper2Lib::Paths64 Slic3rPolylines_to_Paths64(const Slic3r::Polylines& in);
|
||||
Slic3r::Polylines Paths64_to_polylines(const Clipper2Lib::Paths64& in);
|
||||
Slic3r::Polylines intersection_pl_2(const Slic3r::Polylines& subject, const Slic3r::Polygons& clip);
|
||||
Slic3r::Polylines diff_pl_2(const Slic3r::Polylines& subject, const Slic3r::Polygons& clip);
|
||||
ExPolygons union_ex_2(const Polygons &expolygons);
|
||||
|
|
|
|||
|
|
@ -200,6 +200,10 @@ void Fill3DHoneycomb::_fill_surface_single(
|
|||
if (std::abs(infill_angle) >= EPSILON) expolygon.rotate(-infill_angle);
|
||||
BoundingBox bb = expolygon.contour.bounding_box();
|
||||
|
||||
// Expand the bounding box to avoid artifacts at the edges
|
||||
coord_t expand = 5 * (scale_(this->spacing));
|
||||
bb.offset(expand);
|
||||
|
||||
// Note: with equally-scaled X/Y/Z, the pattern will create a vertically-stretched
|
||||
// truncated octahedron; so Z is pre-adjusted first by scaling by sqrt(2)
|
||||
coordf_t zScale = sqrt(2);
|
||||
|
|
|
|||
|
|
@ -1371,42 +1371,47 @@ void Filler::_fill_surface_single(
|
|||
all_polylines.reserve(lines.size());
|
||||
std::transform(lines.begin(), lines.end(), std::back_inserter(all_polylines), [](const Line& l) { return Polyline{ l.a, l.b }; });
|
||||
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(all_polylines, params, spacing);
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(all_polylines, params, spacing);
|
||||
|
||||
// Crop all polylines
|
||||
all_polylines = intersection_pl(std::move(all_polylines), expolygon);
|
||||
#endif
|
||||
}
|
||||
|
||||
// After intersection_pl some polylines with only one line are split into more lines
|
||||
for (Polyline &polyline : all_polylines) {
|
||||
//FIXME assert that all the points are collinear and in between the start and end point.
|
||||
if (polyline.points.size() > 2)
|
||||
polyline.points.erase(polyline.points.begin() + 1, polyline.points.end() - 1);
|
||||
}
|
||||
// assert(has_no_collinear_lines(all_polylines));
|
||||
if (params.multiline == 1) {
|
||||
// After intersection_pl some polylines with only one line are split into more lines
|
||||
for (Polyline& polyline : all_polylines) {
|
||||
// FIXME assert that all the points are collinear and in between the start and end point.
|
||||
if (polyline.points.size() > 2)
|
||||
polyline.points.erase(polyline.points.begin() + 1, polyline.points.end() - 1);
|
||||
}
|
||||
// assert(has_no_collinear_lines(all_polylines));
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_infill_lines_to_svg(expolygon, all_polylines, debug_out_path("FillAdaptive-initial-%d.svg", iRun++));
|
||||
}
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_infill_lines_to_svg(expolygon, all_polylines, debug_out_path("FillAdaptive-initial-%d.svg", iRun++));
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
const auto hook_length = coordf_t(std::min<float>(std::numeric_limits<coord_t>::max(), scale_(params.anchor_length)));
|
||||
const auto hook_length_max = coordf_t(std::min<float>(std::numeric_limits<coord_t>::max(), scale_(params.anchor_length_max)));
|
||||
const auto hook_length = coordf_t(std::min<float>(std::numeric_limits<coord_t>::max(), scale_(params.anchor_length)));
|
||||
const auto hook_length_max = coordf_t(std::min<float>(std::numeric_limits<coord_t>::max(), scale_(params.anchor_length_max)));
|
||||
|
||||
Polylines all_polylines_with_hooks = all_polylines.size() > 1 ? connect_lines_using_hooks(std::move(all_polylines), expolygon, this->spacing, hook_length, hook_length_max) : std::move(all_polylines);
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_infill_lines_to_svg(expolygon, all_polylines_with_hooks, debug_out_path("FillAdaptive-hooks-%d.svg", iRun++));
|
||||
}
|
||||
{
|
||||
static int iRun = 0;
|
||||
export_infill_lines_to_svg(expolygon, all_polylines_with_hooks, debug_out_path("FillAdaptive-hooks-%d.svg", iRun++));
|
||||
}
|
||||
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
|
||||
|
||||
chain_or_connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->spacing, params);
|
||||
chain_or_connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->spacing, params);
|
||||
} else {
|
||||
// if multiline is > 1 infill is ready to connect
|
||||
chain_or_connect_infill(std::move(all_polylines), expolygon, polylines_out, this->spacing, params);
|
||||
}
|
||||
|
||||
#ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <cmath>
|
||||
#include "../ClipperUtils.hpp"
|
||||
#include "../Clipper2Utils.hpp"
|
||||
#include "../EdgeGrid.hpp"
|
||||
#include "../Geometry.hpp"
|
||||
#include "../Geometry/Circle.hpp"
|
||||
|
|
@ -2699,60 +2700,77 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const Polygons &boun
|
|||
connect_base_support(std::move(infill_ordered), polygons_src, bbox, polylines_out, spacing, params);
|
||||
}
|
||||
|
||||
//Fill Multiline
|
||||
// Fill Multiline -Clipper2 version
|
||||
void multiline_fill(Polylines& polylines, const FillParams& params, float spacing)
|
||||
{
|
||||
if (params.multiline > 1) {
|
||||
const int n_lines = params.multiline;
|
||||
const int n_polylines = static_cast<int>(polylines.size());
|
||||
Polylines all_polylines;
|
||||
all_polylines.reserve(n_lines * n_polylines);
|
||||
if (params.multiline <= 1)
|
||||
return;
|
||||
|
||||
const float center = (n_lines - 1) / 2.0f;
|
||||
const int n_lines = params.multiline;
|
||||
const int n_polylines = static_cast<int>(polylines.size());
|
||||
Polylines all_polylines;
|
||||
all_polylines.reserve(n_lines * n_polylines);
|
||||
|
||||
for (int line = 0; line < n_lines; ++line) {
|
||||
float offset = scale_((static_cast<float>(line) - center) * spacing);
|
||||
// Remove invalid polylines
|
||||
polylines.erase(std::remove_if(polylines.begin(), polylines.end(),
|
||||
[](const Polyline& p) { return p.size() < 2; }),
|
||||
polylines.end());
|
||||
|
||||
for (const Polyline& pl : polylines) {
|
||||
const size_t n = pl.points.size();
|
||||
if (n < 2) {
|
||||
all_polylines.emplace_back(pl);
|
||||
continue;
|
||||
}
|
||||
if (polylines.empty())
|
||||
return;
|
||||
// Convert source polylines to Clipper2 paths
|
||||
Clipper2Lib::Paths64 subject_paths = Slic3rPolylines_to_Paths64(polylines);
|
||||
|
||||
Points new_points;
|
||||
new_points.reserve(n);
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
Vec2f tangent;
|
||||
// For the first and last point, if the polyline is a
|
||||
// closed loop, get the tangent from the points on either
|
||||
// side of the join, otherwise just use the first or last
|
||||
// line.
|
||||
if (i == 0) {
|
||||
if (pl.points[0] == pl.points[n-1]) {
|
||||
tangent = (pl.points[1] - pl.points[n-2]).template cast<float>().normalized();
|
||||
} else {
|
||||
tangent = (pl.points[1] - pl.points[0]).template cast<float>().normalized();
|
||||
}
|
||||
} else if (i == n - 1) {
|
||||
if (pl.points[0] == pl.points[n-1]) {
|
||||
tangent = (pl.points[1] - pl.points[n-2]).template cast<float>().normalized();
|
||||
} else {
|
||||
tangent = (pl.points[n-1] - pl.points[n-2]).template cast<float>().normalized();
|
||||
}
|
||||
} else
|
||||
tangent = (pl.points[i+1] - pl.points[i-1]).template cast<float>().normalized();
|
||||
Vec2f normal(-tangent.y(), tangent.x());
|
||||
const double miter_limit = 2.0;
|
||||
const int rings = n_lines / 2;
|
||||
|
||||
Point p = pl.points[i] + (normal * offset).template cast<coord_t>();
|
||||
new_points.push_back(p);
|
||||
}
|
||||
// Compute offsets (in units of spacing)
|
||||
std::vector<double> offsets;
|
||||
offsets.reserve(n_lines);
|
||||
|
||||
all_polylines.emplace_back(std::move(new_points));
|
||||
}
|
||||
}
|
||||
polylines = std::move(all_polylines);
|
||||
if (n_lines % 2 != 0) {
|
||||
// Odd: center line at offset = 0
|
||||
offsets.push_back(0.0);
|
||||
|
||||
for (int i = 1; i <= rings; ++i)
|
||||
offsets.push_back(i * spacing);
|
||||
} else {
|
||||
// Even: no center, start at 0.5 * spacing
|
||||
double start = 0.5 * spacing;
|
||||
for (int i = 0; i < rings; ++i)
|
||||
offsets.push_back(start + i * spacing);
|
||||
}
|
||||
|
||||
// Process each offset
|
||||
Clipper2Lib::ClipperOffset offsetter(miter_limit);
|
||||
offsetter.AddPaths(subject_paths, Clipper2Lib::JoinType::Round, Clipper2Lib::EndType::Round);
|
||||
|
||||
for (double t : offsets) {
|
||||
if (t == 0.0) {
|
||||
// Center line (only applies when n_lines is odd)
|
||||
all_polylines.insert(all_polylines.end(), polylines.begin(), polylines.end());
|
||||
continue;
|
||||
}
|
||||
|
||||
// ClipperOffset with current offset distance (union is not needed here)
|
||||
Clipper2Lib::Paths64 offset_paths;
|
||||
offsetter.Execute(scale_(t), offset_paths);
|
||||
if (offset_paths.empty())
|
||||
continue;
|
||||
|
||||
// Convert back to polylines
|
||||
Polylines new_polylines = Paths64_to_polylines(offset_paths);
|
||||
|
||||
for (Polyline& pl : new_polylines) {
|
||||
if (pl.points.size() < 3)
|
||||
continue;
|
||||
if (pl.points.front() != pl.points.back())
|
||||
pl.points.push_back(pl.points.front());
|
||||
all_polylines.emplace_back(std::move(pl));
|
||||
}
|
||||
}
|
||||
|
||||
polylines = std::move(all_polylines);
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ void FillConcentric::_fill_surface_single(
|
|||
// no rotation is supported for this infill pattern
|
||||
BoundingBox bounding_box = expolygon.contour.bounding_box();
|
||||
|
||||
coord_t min_spacing = scale_(this->spacing);
|
||||
coord_t min_spacing = scale_(this->spacing) * params.multiline;
|
||||
coord_t distance = coord_t(min_spacing / params.density);
|
||||
|
||||
if (params.density > 0.9999f && !params.dont_adjust) {
|
||||
|
|
@ -27,8 +27,12 @@ void FillConcentric::_fill_surface_single(
|
|||
this->spacing = unscale<double>(distance);
|
||||
}
|
||||
|
||||
Polygons loops = to_polygons(expolygon);
|
||||
ExPolygons last { std::move(expolygon) };
|
||||
// Contract surface polygon by half line width to avoid excesive overlap with perimeter
|
||||
ExPolygons contracted = offset_ex(expolygon, -float(scale_(0.5 * (params.multiline - 1) * this->spacing )));
|
||||
|
||||
Polygons loops = to_polygons(contracted);
|
||||
|
||||
ExPolygons last { std::move(contracted) };
|
||||
while (! last.empty()) {
|
||||
last = offset2_ex(last, -(distance + min_spacing/2), +min_spacing/2);
|
||||
append(loops, to_polygons(last));
|
||||
|
|
@ -46,6 +50,9 @@ void FillConcentric::_fill_surface_single(
|
|||
last_pos = polylines_out.back().last_point();
|
||||
}
|
||||
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(polylines_out, params, spacing);
|
||||
|
||||
// clip the paths to prevent the extruder from getting exactly on the first point of the loop
|
||||
// Keep valid paths only.
|
||||
size_t j = iPathFirst;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ void FillHoneycomb::_fill_surface_single(
|
|||
}
|
||||
}
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(all_polylines, params, 1.1 * spacing);
|
||||
multiline_fill(all_polylines, params, spacing);
|
||||
|
||||
all_polylines = intersection_pl(std::move(all_polylines), expolygon);
|
||||
chain_or_connect_infill(std::move(all_polylines), expolygon, polylines_out, this->spacing, params);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,9 @@ void FillPlanePath::_fill_surface_single(
|
|||
|
||||
BoundingBox snug_bounding_box = get_extents(expolygon).inflated(SCALED_EPSILON);
|
||||
|
||||
// Expand the bounding box to avoid artifacts at the edges
|
||||
snug_bounding_box.offset(scale_(this->spacing)*params.multiline);
|
||||
|
||||
// Rotated bounding box of the area to fill in with the pattern.
|
||||
BoundingBox bounding_box = align ?
|
||||
// Sparse infill needs to be aligned across layers. Align infill across layers using the object's bounding box.
|
||||
|
|
@ -97,7 +100,7 @@ void FillPlanePath::_fill_surface_single(
|
|||
|
||||
Polyline polyline;
|
||||
{
|
||||
auto distance_between_lines = scaled<double>(this->spacing) / params.density;
|
||||
auto distance_between_lines = scaled<double>(this->spacing) * params.multiline / params.density;
|
||||
auto min_x = coord_t(ceil(coordf_t(bounding_box.min.x()) / distance_between_lines));
|
||||
auto min_y = coord_t(ceil(coordf_t(bounding_box.min.y()) / distance_between_lines));
|
||||
auto max_x = coord_t(ceil(coordf_t(bounding_box.max.x()) / distance_between_lines));
|
||||
|
|
@ -117,8 +120,13 @@ void FillPlanePath::_fill_surface_single(
|
|||
}
|
||||
}
|
||||
|
||||
Polylines polylines = {polyline};
|
||||
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(polylines, params, spacing);
|
||||
|
||||
if (polyline.size() >= 2) {
|
||||
Polylines polylines = intersection_pl(polyline, expolygon);
|
||||
polylines = intersection_pl(std::move(polylines), expolygon);
|
||||
if (!polylines.empty()) {
|
||||
Polylines chained;
|
||||
if (params.dont_connect() || params.density > 0.5) {
|
||||
|
|
|
|||
|
|
@ -3000,7 +3000,7 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar
|
|||
params.density /= double(sweep_params.size());
|
||||
assert(params.density > 0.0001f && params.density <= 1.f);
|
||||
|
||||
ExPolygonWithOffset poly_with_offset_base(surface->expolygon, 0, float(scale_(this->overlap - 0.5 * this->spacing)));
|
||||
ExPolygonWithOffset poly_with_offset_base(surface->expolygon, 0, float(scale_(this->overlap + 0.5 * params.multiline * this->spacing)));//increase offset to crop infill lines when using multiline infill
|
||||
if (poly_with_offset_base.n_contours == 0)
|
||||
// Not a single infill line fits.
|
||||
return true;
|
||||
|
|
@ -3012,19 +3012,24 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar
|
|||
for (const SweepParams &sweep : sweep_params) {
|
||||
// Rotate polygons so that we can work with vertical lines here
|
||||
float angle = rotate_vector.first + sweep.angle_base;
|
||||
//Fill Multiline
|
||||
for (int i = 0; i < params.multiline; ++i) {
|
||||
coord_t group_offset = i * line_spacing;
|
||||
coord_t internal_offset = (i - (params.multiline - 1) / 2.0f) * line_width;
|
||||
coord_t total_offset = group_offset + internal_offset;
|
||||
coord_t pattern_shift = scale_(sweep.pattern_shift + unscale_(total_offset));
|
||||
|
||||
make_fill_lines(ExPolygonWithOffset(poly_with_offset_base, -angle), rotate_vector.second.rotated(-angle), angle,
|
||||
line_width + coord_t(SCALED_EPSILON), line_spacing, pattern_shift, fill_lines);
|
||||
}
|
||||
make_fill_lines(ExPolygonWithOffset(poly_with_offset_base, -angle), rotate_vector.second.rotated(-angle), angle,
|
||||
line_width + coord_t(SCALED_EPSILON), line_spacing, coord_t(scale_(sweep.pattern_shift)), fill_lines);
|
||||
}
|
||||
|
||||
// Apply multiline offset if needed
|
||||
multiline_fill(fill_lines, params, spacing);
|
||||
|
||||
// Contract surface polygon by half line width to avoid excesive overlap with perimeter
|
||||
ExPolygons contracted = offset_ex(surface->expolygon, -float(scale_(0.5 * this->spacing)));
|
||||
|
||||
// if contraction results in empty polygon, use original surface
|
||||
const ExPolygon &intersection_surface = contracted.empty() ? surface->expolygon : contracted.front();
|
||||
|
||||
if ((params.pattern == ipLateralLattice || params.pattern == ipLateralHoneycomb ) && params.multiline >1 )
|
||||
// Intersect polylines with perimeter
|
||||
fill_lines = intersection_pl(std::move(fill_lines), intersection_surface);
|
||||
|
||||
if ((params.pattern == ipLateralLattice || params.pattern == ipLateralHoneycomb ) && params.multiline >1 )
|
||||
remove_overlapped(fill_lines, line_width);
|
||||
|
||||
if (!fill_lines.empty()) {
|
||||
|
|
@ -3033,7 +3038,260 @@ if ((params.pattern == ipLateralLattice || params.pattern == ipLateralHoneycomb
|
|||
fill_lines = chain_polylines(std::move(fill_lines));
|
||||
append(polylines_out, std::move(fill_lines));
|
||||
} else
|
||||
connect_infill(std::move(fill_lines), poly_with_offset_base.polygons_outer, get_extents(surface->expolygon.contour), polylines_out, this->spacing, params);
|
||||
connect_infill(std::move(fill_lines), intersection_surface, polylines_out, this->spacing, params);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FillRectilinear::fill_surface_trapezoidal(
|
||||
const Surface* surface,
|
||||
FillParams params,
|
||||
const std::initializer_list<SweepParams>& sweep_params,
|
||||
Polylines& polylines_out,
|
||||
int Pattern_type) // 0=grid, 1=triangular
|
||||
{
|
||||
assert(params.multiline > 1);
|
||||
|
||||
Polylines polylines;
|
||||
|
||||
// Common parameters
|
||||
const coord_t d1 = coord_t(scale_(this->spacing)) * params.multiline; // Infill total wall thickness
|
||||
|
||||
// Pattern-specific parameters
|
||||
coord_t period;
|
||||
double base_angle;
|
||||
std::pair<double, Point> rotate_vector = this->_infill_direction(surface);
|
||||
|
||||
if (Pattern_type == 0) {
|
||||
// Grid pattern parameters
|
||||
period = coord_t((2.0 * d1 / params.density) * std::sqrt(2.0));
|
||||
base_angle = rotate_vector.first + M_PI_4; // 45
|
||||
} else {
|
||||
// Triangular pattern parameters
|
||||
period = coord_t(( 2.0 * d1 / params.density) * std::sqrt(3.0));
|
||||
base_angle = rotate_vector.first + M_PI_2; //90
|
||||
}
|
||||
|
||||
// Obtain the expolygon and rotate to align with pattern base angle
|
||||
ExPolygon expolygon = surface->expolygon;
|
||||
if (std::abs(base_angle) >= EPSILON) {
|
||||
expolygon.rotate(-base_angle, rotate_vector.second);
|
||||
}
|
||||
|
||||
// Use extended object bounding box for consistent pattern across layers
|
||||
BoundingBox bb = this->extended_object_bounding_box();
|
||||
|
||||
switch (Pattern_type) {
|
||||
case 0: // Grid / Trapezoidal
|
||||
{
|
||||
// Generate a non-crossing trapezoidal pattern to avoid overextrusion at intersections when `multiline > 1`.
|
||||
// P1--P2
|
||||
// / \
|
||||
// P0/ \P3__P4
|
||||
//
|
||||
// P1x-P2x=P3x-P4x=d1
|
||||
// P0y-P1y=P2y-P3y=d2
|
||||
|
||||
const coord_t d2 = coord_t(0.5 * period - d1);
|
||||
|
||||
// Align bounding box to the grid
|
||||
bb.merge(align_to_grid(bb.min, Point(period, period)));
|
||||
const coord_t xmin = bb.min.x();
|
||||
const coord_t xmax = bb.max.x();
|
||||
const coord_t ymin = bb.min.y();
|
||||
const coord_t ymax = bb.max.y();
|
||||
|
||||
// Create the two base row patterns once
|
||||
Polyline base_row_normal;
|
||||
base_row_normal.points.reserve(((xmax - xmin) / period + 1) * 5); // 5 points per trapezoid
|
||||
Polyline base_row_flipped;
|
||||
base_row_flipped.points.reserve(((xmax - xmin) / period + 1) * 5); // 5 points per trapezoid
|
||||
|
||||
// Build complete rows from xmin to xmax
|
||||
for (coord_t x = xmin; x < xmax; x += period) {
|
||||
// Normal row
|
||||
base_row_normal.points.emplace_back(Point(x, d1 / 2)); // P0
|
||||
base_row_normal.points.emplace_back(Point(x + d1, d1 / 2)); // P1
|
||||
base_row_normal.points.emplace_back(Point(x + d1 + d2, d1 / 2 + d2)); // P2
|
||||
base_row_normal.points.emplace_back(Point(x + 2 * d1 + d2, d1 / 2 + d2)); // P3
|
||||
base_row_normal.points.emplace_back(Point(x + 2 * d1 + 2 * d2, d1 / 2)); // P4
|
||||
}
|
||||
|
||||
// Flipped row (mirrored vertically)
|
||||
base_row_flipped.points = base_row_normal.points;
|
||||
for (auto& p : base_row_flipped.points) {
|
||||
p.y() = period / 2 - p.y();
|
||||
}
|
||||
|
||||
// Pre-allocate polylines
|
||||
const size_t estimated_rows = ((ymax - ymin) / (period / 2) + 1);
|
||||
polylines.reserve(estimated_rows);
|
||||
|
||||
bool flip_vertical = false;
|
||||
|
||||
// Now just copy and translate vertically
|
||||
for (coord_t y = ymin; y < ymax; y += period / 2) {
|
||||
Polyline pl_row = flip_vertical ? base_row_flipped : base_row_normal;
|
||||
|
||||
// Translate all points vertically
|
||||
for (Point& p : pl_row.points) {
|
||||
p.y() += y;
|
||||
}
|
||||
|
||||
polylines.emplace_back(std::move(pl_row));
|
||||
flip_vertical = !flip_vertical;
|
||||
}
|
||||
|
||||
// transpose points for odd layers
|
||||
if (layer_id % 2 == 1) {
|
||||
for (Polyline& pl : polylines) {
|
||||
for (Point& p : pl.points) {
|
||||
std::swap(p.x(), p.y());
|
||||
p.x() += d1 / 2;
|
||||
p.y() -= d1 / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // Triangular
|
||||
{
|
||||
// Generate a non-crossing trapezoidal pattern with a base line below.
|
||||
// P1-P2
|
||||
// / \
|
||||
// P0/ \P3_P4
|
||||
// ----------------
|
||||
// P1x-P2x=P3x-P4x=d2
|
||||
// P0y-P1y=P2y-P3y=h-2d1
|
||||
//
|
||||
|
||||
// Triangular pattern density adjustment:
|
||||
const coord_t d2_tri = coord_t(2.0 / std::sqrt(3.0) * d1);
|
||||
const coord_t h = coord_t(0.5 * std::sqrt(3.0) * period); // height of triangle
|
||||
|
||||
// Align bounding box to the grid
|
||||
bb.merge(align_to_grid(bb.center(), Point(period,h)));
|
||||
const int layer_mod = layer_id % 3;
|
||||
const double angle = layer_mod * 2.0 * M_PI / 3.0;
|
||||
|
||||
const Point rotation_center = bb.center();
|
||||
const coord_t half_w = bb.size().x() / 2;
|
||||
const coord_t half_h = bb.size().y() / 2;
|
||||
|
||||
// Compute how many full periods fit in each direction
|
||||
const coord_t num_periods_x = coord_t(std::ceil(half_w / double(period)));
|
||||
coord_t num_periods_y =coord_t(std::ceil(half_h / double(h)));
|
||||
// Ensure an even number of rows so the pattern stays centered
|
||||
if ((num_periods_y % 2) != 0)
|
||||
++num_periods_y;
|
||||
|
||||
// Compute aligned limits (symmetric around the origin)
|
||||
const coord_t x_min_aligned = -num_periods_x * period;
|
||||
const coord_t x_max_aligned = num_periods_x * period;
|
||||
const coord_t y_min_aligned = -num_periods_y * h;
|
||||
const coord_t y_max_aligned = num_periods_y * h;
|
||||
|
||||
// Pre-allocate estimated number of polylines
|
||||
const size_t estimated_rows = (y_max_aligned - y_min_aligned) / h + 2;
|
||||
const size_t estimated_polylines = (estimated_rows + 1) * 2; // base line + trapezoid line per row
|
||||
polylines.reserve(estimated_polylines);
|
||||
|
||||
// Create the two base row templates once
|
||||
Polyline base_line_template;
|
||||
base_line_template.points.reserve(2); // 2 points for base line
|
||||
Polyline trapezoid_row_normal;
|
||||
trapezoid_row_normal.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 5); // 5 points per trapezoid
|
||||
Polyline trapezoid_row_shifted;
|
||||
trapezoid_row_shifted.points.reserve(((x_max_aligned - x_min_aligned) / period + 1) * 5); // 5 points per trapezoid
|
||||
// Build base line template (from x_min_aligned to x_max_aligned)
|
||||
base_line_template.points.emplace_back(Point(x_min_aligned, 0));
|
||||
base_line_template.points.emplace_back(Point(x_max_aligned, 0));
|
||||
|
||||
// Build complete trapezoid rows once
|
||||
// Normal row (no shift)
|
||||
for (coord_t x = x_min_aligned; x < x_max_aligned; x += period) {
|
||||
trapezoid_row_normal.points.emplace_back(Point(x + d2_tri / 2, d1)); // P0
|
||||
trapezoid_row_normal.points.emplace_back(Point(x + period / 2 - d2_tri / 2, h - d1)); // P1
|
||||
trapezoid_row_normal.points.emplace_back(Point(x + period / 2 + d2_tri / 2, h - d1)); // P2
|
||||
trapezoid_row_normal.points.emplace_back(Point(x + period - d2_tri / 2, d1)); // P3
|
||||
trapezoid_row_normal.points.emplace_back(Point(x + period, d1)); // P4
|
||||
}
|
||||
|
||||
// Shifted row (mirrored vertically)
|
||||
trapezoid_row_shifted.points = trapezoid_row_normal.points;
|
||||
for (auto& p : trapezoid_row_shifted.points)
|
||||
p.y() = h - p.y();
|
||||
|
||||
bool shift_row = false;
|
||||
|
||||
// Generate pattern by copying and translating templates vertically
|
||||
for (coord_t y = y_min_aligned; y < y_max_aligned; y += h) {
|
||||
// Base line - copy and translate
|
||||
Polyline base_line = base_line_template;
|
||||
for (Point& p : base_line.points) {
|
||||
p.y() += y;
|
||||
}
|
||||
polylines.emplace_back(std::move(base_line));
|
||||
|
||||
// Trapezoid line - copy and translate the appropriate template
|
||||
Polyline trapezoid_line = shift_row ? trapezoid_row_shifted : trapezoid_row_normal;
|
||||
for (Point& p : trapezoid_line.points) {
|
||||
p.y() += y;
|
||||
}
|
||||
|
||||
if (!trapezoid_line.points.empty()) {
|
||||
polylines.emplace_back(std::move(trapezoid_line));
|
||||
}
|
||||
|
||||
shift_row = !shift_row;
|
||||
}
|
||||
|
||||
// Rotate around origin (0,0)
|
||||
if (layer_mod)
|
||||
for (auto& pl : polylines)
|
||||
pl.rotate(angle, Point(0,0));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Handle unknown pattern type
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply multiline fill
|
||||
multiline_fill(polylines, params, spacing);
|
||||
|
||||
// Contract surface polygon by half line width to avoid excesive overlap with perimeter
|
||||
ExPolygons contracted = offset_ex(expolygon, -float(scale_(0.5 * this->spacing)));
|
||||
|
||||
// if contraction results in empty polygon, use original surface
|
||||
const ExPolygon &intersection_surface = contracted.empty() ? expolygon : contracted.front();
|
||||
|
||||
// Intersect polylines with offset expolygon
|
||||
polylines = intersection_pl(std::move(polylines), intersection_surface);
|
||||
|
||||
// Remove very short segments that may cause connection issues
|
||||
const double minlength = scale_(0.8 * this->spacing);
|
||||
if (minlength > 0 && !polylines.empty()) {
|
||||
polylines.erase(std::remove_if(polylines.begin(), polylines.end(),
|
||||
[minlength](const Polyline& pl) { return pl.length() < minlength; }),
|
||||
polylines.end());
|
||||
}
|
||||
|
||||
// Connect infill lines using offset expolygon
|
||||
int infill_start_idx = polylines_out.size();
|
||||
if (!polylines.empty()) {
|
||||
Slic3r::Fill::chain_or_connect_infill(std::move(polylines), intersection_surface, polylines_out, this->spacing, params);
|
||||
|
||||
// Rotate back the infill lines to original orientation
|
||||
if (std::abs(base_angle) >= EPSILON) {
|
||||
for (auto it = polylines_out.begin() + infill_start_idx; it != polylines_out.end(); ++it) {
|
||||
it->rotate(base_angle, rotate_vector.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -3077,15 +3335,27 @@ Polylines FillMonotonicLine::fill_surface(const Surface* surface, const FillPara
|
|||
Polylines FillGrid::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
{
|
||||
Polylines polylines_out;
|
||||
if (! this->fill_surface_by_multilines(
|
||||
surface, params,
|
||||
{ { 0.f, 0.f }, { float(M_PI / 2.), 0.f } },
|
||||
polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface() failed to fill a region.";
|
||||
|
||||
if (this->layer_id % 2 == 1)
|
||||
for (int i = 0; i < polylines_out.size(); i++)
|
||||
std::reverse(polylines_out[i].begin(), polylines_out[i].end());
|
||||
if (params.multiline > 1) {
|
||||
// Experimental trapezoidal grid
|
||||
if (!this->fill_surface_trapezoidal(
|
||||
surface, params,
|
||||
{ { 0.f, 0.f }, { float(M_PI / 2.), 0.f } },
|
||||
polylines_out,0))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface_trapezoidal() failed.";
|
||||
|
||||
} else {
|
||||
if (!this->fill_surface_by_multilines(
|
||||
surface, params,
|
||||
{ { 0.f, 0.f }, { float(M_PI / 2.), 0.f } },
|
||||
polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface() failed to fill a region.";
|
||||
|
||||
|
||||
if (this->layer_id % 2 == 1)
|
||||
for (int i = 0; i < polylines_out.size(); i++)
|
||||
std::reverse(polylines_out[i].begin(), polylines_out[i].end());
|
||||
}
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
|
|
@ -3108,12 +3378,23 @@ Polylines FillLateralLattice::fill_surface(const Surface *surface, const FillPar
|
|||
|
||||
Polylines FillTriangles::fill_surface(const Surface *surface, const FillParams ¶ms){
|
||||
Polylines polylines_out;
|
||||
if (params.multiline > 1) {
|
||||
// Experimental trapezoidal grid
|
||||
if (!this->fill_surface_trapezoidal(
|
||||
surface, params,
|
||||
{ { 0.f, 0.f }, { float(M_PI / 2.), 0.f } },
|
||||
polylines_out,1))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillGrid::fill_surface_trapezoidal() failed.";
|
||||
|
||||
} else {
|
||||
if (! this->fill_surface_by_multilines(
|
||||
surface, params,
|
||||
{ { 0.f, 0.f }, { float(M_PI / 3.), 0.f }, { float(2. * M_PI / 3.), 0. } },
|
||||
polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "FillTriangles::fill_surface() failed to fill a region.";
|
||||
}
|
||||
return polylines_out;
|
||||
|
||||
}
|
||||
|
||||
Polylines FillStars::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
|
|
@ -3144,8 +3425,8 @@ Polylines FillQuarterCubic::fill_surface(const Surface* surface, const FillParam
|
|||
using namespace boost::math::float_constants;
|
||||
Polylines polylines_out;
|
||||
|
||||
coord_t line_width = coord_t(scale_(this->spacing));
|
||||
coord_t period = coord_t(scale_(this->spacing) / params.density) * 4;
|
||||
coord_t line_width = coord_t(scale_(this->spacing)) * params.multiline;
|
||||
coord_t period = coord_t(scale_(this->spacing) *params.multiline / params.density) * 4;
|
||||
|
||||
// First half tetrahedral fill
|
||||
double pattern_z_shift = 0.0;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ protected:
|
|||
float pattern_shift;
|
||||
};
|
||||
bool fill_surface_by_multilines(const Surface *surface, FillParams params, const std::initializer_list<SweepParams> &sweep_params, Polylines &polylines_out);
|
||||
bool fill_surface_trapezoidal(const Surface *surface, FillParams params, const std::initializer_list<SweepParams> &sweep_params, Polylines &polylines_out,int Pattern_type);
|
||||
|
||||
// The extended bounding box of the whole object that covers any rotation of every layer.
|
||||
BoundingBox extended_object_bounding_box() const;
|
||||
|
|
|
|||
|
|
@ -6196,10 +6196,16 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
|||
);
|
||||
}
|
||||
|
||||
// if still in avoidance mode and under “max”, clamp to “min”
|
||||
if (m_resonance_avoidance
|
||||
&& speed <= m_config.max_resonance_avoidance_speed.value) {
|
||||
speed = std::min(speed, m_config.min_resonance_avoidance_speed.value);
|
||||
// if still in avoidance mode and under "max", adjust speed:
|
||||
// - speeds in lower half of range: clamp down to "min"
|
||||
// - speeds in upper half of range: boost up to "max"
|
||||
if (m_resonance_avoidance && speed < m_config.max_resonance_avoidance_speed.value) {
|
||||
if (speed < m_config.min_resonance_avoidance_speed.value +
|
||||
((m_config.max_resonance_avoidance_speed.value - m_config.min_resonance_avoidance_speed.value) / 2)) {
|
||||
speed = std::min(speed, m_config.min_resonance_avoidance_speed.value);
|
||||
} else {
|
||||
speed = m_config.max_resonance_avoidance_speed.value;
|
||||
}
|
||||
}
|
||||
|
||||
// reset flag for next segment
|
||||
|
|
|
|||
|
|
@ -1045,8 +1045,8 @@ namespace client
|
|||
case coFloatOrPercent:
|
||||
{
|
||||
std::string opt_key(opt.it_range.begin(), opt.it_range.end());
|
||||
if (boost::ends_with(opt_key, "extrusion_width")) {
|
||||
// Extrusion width supports defaults and a complex graph of dependencies.
|
||||
if (boost::ends_with(opt_key, "line_width")) {
|
||||
// Line width supports defaults and a complex graph of dependencies.
|
||||
output.set_d(Flow::extrusion_width(opt_key, *ctx, static_cast<unsigned int>(ctx->current_extruder_id)));
|
||||
} else if (! static_cast<const ConfigOptionFloatOrPercent*>(opt.opt)->percent) {
|
||||
// Not a percent, just return the value.
|
||||
|
|
@ -1060,8 +1060,8 @@ namespace client
|
|||
const ConfigOption *opt_parent = opt_def->ratio_over.empty() ? nullptr : ctx->resolve_symbol(opt_def->ratio_over);
|
||||
if (opt_parent == nullptr)
|
||||
ctx->throw_exception("FloatOrPercent variable failed to resolve the \"ratio_over\" dependencies", opt.it_range);
|
||||
if (boost::ends_with(opt_def->ratio_over, "extrusion_width")) {
|
||||
// Extrusion width supports defaults and a complex graph of dependencies.
|
||||
if (boost::ends_with(opt_def->ratio_over, "line_width")) {
|
||||
// Line width supports defaults and a complex graph of dependencies.
|
||||
assert(opt_parent->type() == coFloatOrPercent);
|
||||
v *= Flow::extrusion_width(opt_def->ratio_over, static_cast<const ConfigOptionFloatOrPercent*>(opt_parent), *ctx, static_cast<unsigned int>(ctx->current_extruder_id));
|
||||
break;
|
||||
|
|
@ -2197,9 +2197,8 @@ namespace client
|
|||
initializer_list(_r1)[px::bind(&MyContext::vector_variable_new_from_initializer_list, _r1, _a, _b, _1)]
|
||||
// Process it before conditional_expression, as conditional_expression requires a vector reference to be augmented with an index.
|
||||
// Only process such variable references, which return a naked vector variable.
|
||||
// Orca todo: following code cause strange build errors with MSVC C++17
|
||||
// | eps(px::bind(&MyContext::could_be_vector_variable_reference, _b)) >>
|
||||
// variable_reference(_r1)[px::val(qi::_pass) = px::bind(&MyContext::vector_variable_new_from_copy, _r1, _a, _b, _1)]
|
||||
| eps(px::bind(&MyContext::could_be_vector_variable_reference, _b)) >>
|
||||
variable_reference(_r1)[qi::_pass = px::bind(&MyContext::vector_variable_new_from_copy, _r1, _a, _b, _1)]
|
||||
// Would NOT consume '(' conditional_expression ')' because such value was consumed with the expression above.
|
||||
| conditional_expression(_r1)
|
||||
[px::bind(&MyContext::scalar_variable_new_from_scalar_expression, _r1, _a, _b, _1)]
|
||||
|
|
|
|||
|
|
@ -2752,6 +2752,8 @@ Preset *PresetBundle::get_similar_printer_preset(std::string printer_model, std:
|
|||
{
|
||||
if (printer_model.empty())
|
||||
printer_model = printers.get_selected_preset().config.opt_string("printer_model");
|
||||
if (printer_model.empty()) // ORCA ensure a compatible model exist. fixes switches to blank preset if preset has no inherited value
|
||||
return nullptr;
|
||||
auto printer_variant_old = printers.get_selected_preset().config.opt_string("printer_variant");
|
||||
std::map<std::string, Preset*> printer_presets;
|
||||
for (auto &preset : printers.m_presets) {
|
||||
|
|
@ -2762,7 +2764,8 @@ Preset *PresetBundle::get_similar_printer_preset(std::string printer_model, std:
|
|||
}
|
||||
if (printer_presets.empty())
|
||||
return nullptr;
|
||||
auto prefer_printer = printers.get_selected_preset().name;
|
||||
auto prefer_printer = printers.get_selected_preset().alias; //.name ORCA use alias instead "name" for calling system presets. otherwise nozzle combo will not change printer presets if they custom named
|
||||
|
||||
if (!printer_variant.empty())
|
||||
boost::replace_all(prefer_printer, printer_variant_old, printer_variant);
|
||||
else if (auto n = prefer_printer.find(printer_variant_old); n != std::string::npos)
|
||||
|
|
|
|||
|
|
@ -2750,7 +2750,7 @@ void PrintConfigDef::init_fff_params()
|
|||
def->label = L("Fill Multiline");
|
||||
def->tooltip = L("Using multiple lines for the infill pattern, if supported by infill pattern.");
|
||||
def->min = 1;
|
||||
def->max = 5; // Maximum number of lines for infill pattern
|
||||
def->max = 10; // Maximum number of lines for infill pattern
|
||||
def->set_default_value(new ConfigOptionInt(1));
|
||||
|
||||
def = this->add("sparse_infill_pattern", coEnum);
|
||||
|
|
|
|||
|
|
@ -604,8 +604,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
|
||||
// Infill patterns that support multiline infill.
|
||||
InfillPattern pattern = config->opt_enum<InfillPattern>("sparse_infill_pattern");
|
||||
bool have_multiline_infill_pattern = pattern == ipGyroid || pattern == ipGrid || pattern == ipRectilinear || pattern == ipTpmsD || pattern == ipTpmsFK || pattern == ipCrossHatch || pattern == ipHoneycomb || pattern == ipLateralLattice || pattern == ipLateralHoneycomb ||
|
||||
pattern == ipCubic || pattern == ipStars || pattern == ipAlignedRectilinear || pattern == ipLightning || pattern == ip3DHoneycomb || pattern == ipAdaptiveCubic || pattern == ipSupportCubic;
|
||||
bool have_multiline_infill_pattern = pattern == ipGyroid || pattern == ipGrid || pattern == ipRectilinear || pattern == ipTpmsD || pattern == ipTpmsFK || pattern == ipCrossHatch || pattern == ipHoneycomb || pattern == ipLateralLattice || pattern == ipLateralHoneycomb || pattern == ipConcentric ||
|
||||
pattern == ipCubic || pattern == ipStars || pattern == ipAlignedRectilinear || pattern == ipLightning || pattern == ip3DHoneycomb || pattern == ipAdaptiveCubic || pattern == ipSupportCubic|| pattern == ipTriangles || pattern == ipQuarterCubic|| pattern == ipArchimedeanChords || pattern == ipHilbertCurve || pattern == ipOctagramSpiral;
|
||||
|
||||
// If there is infill, enable/disable fill_multiline according to whether the pattern supports multiline infill.
|
||||
if (have_infill) {
|
||||
|
|
@ -774,10 +774,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, co
|
|||
// Orca: Force solid support interface when using support ironing
|
||||
toggle_field("support_interface_spacing", have_support_material && have_support_interface && !has_support_ironing);
|
||||
|
||||
bool have_skirt_height = have_skirt &&
|
||||
(config->opt_int("skirt_height") > 1 || config->opt_enum<DraftShield>("draft_shield") != dsEnabled);
|
||||
toggle_line("support_speed", have_support_material || have_skirt_height);
|
||||
toggle_line("support_interface_speed", have_support_material && have_support_interface);
|
||||
// see issue #10915
|
||||
// bool have_skirt_height = have_skirt &&
|
||||
// (config->opt_int("skirt_height") > 1 || config->opt_enum<DraftShield>("draft_shield") != dsEnabled);
|
||||
// toggle_line("support_speed", have_support_material || have_skirt_height);
|
||||
// toggle_line("support_interface_speed", have_support_material && have_support_interface);
|
||||
|
||||
// BBS
|
||||
//toggle_field("support_material_synchronize_layers", have_support_soluble);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ ImageDPIFrame::ImageDPIFrame()
|
|||
#ifdef __APPLE__
|
||||
SetWindowStyleFlag(GetWindowStyleFlag() | wxSTAY_ON_TOP);
|
||||
#endif
|
||||
|
||||
// ORCA add border
|
||||
Bind(wxEVT_PAINT, [this](wxPaintEvent& evt) {
|
||||
wxPaintDC dc(this);
|
||||
dc.SetPen(StateColor::darkModeColorFor(wxColour("#DBDBDB")));
|
||||
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0);
|
||||
});
|
||||
|
||||
m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -221,9 +221,14 @@ wxDEFINE_EVENT(EVT_NOTICE_FULL_SCREEN_CHANGED, IntEvent);
|
|||
|
||||
static string get_diameter_string(float diameter)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << std::fixed << std::setprecision(1) << diameter;
|
||||
return stream.str();
|
||||
std::ostringstream stream; // ORCA ensure 0.25 returned as 0.25. previous code returned as 0.2 because of std::setprecision(1)
|
||||
stream << std::fixed << std::setprecision(2) << diameter; // Use 2 decimals to capture 0.25 / 0.15 reliably
|
||||
std::string s = stream.str();
|
||||
if (s.find('.') != std::string::npos) { // Remove trailing zeros, but keep at least one decimal if needed
|
||||
s.erase(s.find_last_not_of('0') + 1);
|
||||
if (s.back() == '.') s += '0'; // Ensure "1." → "1.0"
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
bool Plater::has_illegal_filename_characters(const wxString& wxs_name)
|
||||
|
|
@ -1234,7 +1239,8 @@ bool Sidebar::priv::switch_diameter(bool single)
|
|||
}
|
||||
auto preset = wxGetApp().preset_bundle->get_similar_printer_preset({}, diameter.ToStdString());
|
||||
if (preset == nullptr) {
|
||||
MessageDialog dlg(this->plater, "", "");
|
||||
// ORCA add a text. this appears when user tries to change nozzle value but config doesnt have a inherited or compatible preset
|
||||
MessageDialog dlg(this->plater, _L("Configuration incompatible"), _L("Warning"), wxICON_WARNING | wxOK);
|
||||
dlg.ShowModal();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2564,9 +2570,18 @@ void Sidebar::update_presets(Preset::Type preset_type)
|
|||
p->layout_printer(preset_bundle.use_bbl_network(), isBBL && is_dual_extruder);
|
||||
auto diameters = wxGetApp().preset_bundle->printers.diameters_of_selected_printer();
|
||||
auto diameter = printer_preset.config.opt_string("printer_variant");
|
||||
auto update_extruder_diameter = [&diameters, &diameter](ExtruderGroup & extruder) {
|
||||
auto update_extruder_diameter = [&diameters, &diameter, &nozzle_diameter](int extruder_index,ExtruderGroup & extruder) {
|
||||
extruder.combo_diameter->Clear();
|
||||
int select = -1;
|
||||
// ORCA if user defined a custom nozzle in printer config select it instead inherited one. this will show correct nozzle diameter in combobox if its exist in nozzle diameters list
|
||||
auto nozzle_dia = get_diameter_string(nozzle_diameter->values[extruder_index]);
|
||||
if(nozzle_dia != diameter && std::find(diameters.begin(), diameters.end(), nozzle_dia) != diameters.end())
|
||||
diameter = nozzle_dia;
|
||||
// ORCA try to add nozzle diameter from config if list is empty. fixes blank nozzle combo box when preset has no alias
|
||||
if(diameters[0].empty() && !nozzle_dia.empty()){
|
||||
diameters[0] = nozzle_dia;
|
||||
diameter = nozzle_dia;
|
||||
}
|
||||
for (size_t i = 0; i < diameters.size(); ++i) {
|
||||
if (diameters[i] == diameter)
|
||||
select = extruder.combo_diameter->GetCount();
|
||||
|
|
@ -2580,14 +2595,14 @@ void Sidebar::update_presets(Preset::Type preset_type)
|
|||
AMSCountPopupWindow::UpdateAMSCount(0, p->left_extruder);
|
||||
AMSCountPopupWindow::UpdateAMSCount(1, p->right_extruder);
|
||||
//if (!p->is_switching_diameter) {
|
||||
update_extruder_diameter(*p->left_extruder);
|
||||
update_extruder_diameter(*p->right_extruder);
|
||||
update_extruder_diameter(0, *p->left_extruder);
|
||||
update_extruder_diameter(1, *p->right_extruder);
|
||||
//}
|
||||
p->image_printer_bed->SetBitmap(create_scaled_bitmap(image_path, this, PRINTER_THUMBNAIL_SIZE.GetHeight()));
|
||||
} else {
|
||||
AMSCountPopupWindow::UpdateAMSCount(0, p->single_extruder);
|
||||
//if (!p->is_switching_diameter)
|
||||
update_extruder_diameter(*p->single_extruder);
|
||||
update_extruder_diameter(0, *p->single_extruder);
|
||||
|
||||
// ORCA sync unified nozzle combo box
|
||||
p->combo_nozzle_dia->Clear();
|
||||
|
|
|
|||
|
|
@ -4280,6 +4280,9 @@ void TabFilament::reload_config()
|
|||
this->compatible_widget_reload(m_compatible_printers);
|
||||
this->compatible_widget_reload(m_compatible_prints);
|
||||
Tab::reload_config();
|
||||
|
||||
// Recompute derived override UI from the newly loaded config
|
||||
update_filament_overrides_page(&m_preset_bundle->printers.get_edited_preset().config);
|
||||
}
|
||||
|
||||
//void TabFilament::update_volumetric_flow_preset_hints()
|
||||
|
|
|
|||
|
|
@ -14,40 +14,22 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
|
|||
{ "nozzle_diameter", "0.6;0.6;0.6;0.6" },
|
||||
{ "nozzle_temperature", "357;359;363;378" }
|
||||
});
|
||||
// To let the PlaceholderParser throw when referencing initial_layer_line_width if it is set to percent, as the PlaceholderParser does not know
|
||||
// To test the "min_width_top_surface" over "inner_wall_line_width".
|
||||
config.option<ConfigOptionFloatOrPercent>("inner_wall_line_width")->value = 150.;
|
||||
config.option<ConfigOptionFloatOrPercent>("inner_wall_line_width")->percent = true;
|
||||
// To let the PlaceholderParser throw when referencing scarf_joint_speed if it is set to percent, as the PlaceholderParser does not know
|
||||
// a percent to what.
|
||||
config.option<ConfigOptionFloatOrPercent>("initial_layer_line_width")->value = 50.;
|
||||
config.option<ConfigOptionFloatOrPercent>("initial_layer_line_width")->percent = true;
|
||||
config.option<ConfigOptionFloatOrPercent>("scarf_joint_speed")->value = 50.;
|
||||
config.option<ConfigOptionFloatOrPercent>("scarf_joint_speed")->percent = true;
|
||||
|
||||
parser.apply_config(config);
|
||||
parser.set("foo", 0);
|
||||
parser.set("bar", 2);
|
||||
parser.set("num_extruders", 4);
|
||||
|
||||
SECTION("nested config options (legacy syntax)") { REQUIRE(parser.process("[nozzle_temperature_[foo]]") == "357"); }
|
||||
SECTION("nested config options (legacy syntax)") { REQUIRE(parser.process("[nozzle_temperature[foo]]") == "357"); }
|
||||
SECTION("array reference") { REQUIRE(parser.process("{nozzle_temperature[foo]}") == "357"); }
|
||||
SECTION("whitespaces and newlines are maintained") { REQUIRE(parser.process("test [ nozzle_temperature_ [foo] ] \n hu") == "test 357 \n hu"); }
|
||||
|
||||
// Test the "coFloatOrPercent" and "xxx_width" substitutions.
|
||||
|
||||
// FIXME: Don't know what exactly this referred to in Prusaslicer or
|
||||
// whether it should apply to Orca or not.
|
||||
// {outer_wall_line_width} returns as its default value, 0.
|
||||
// SECTION("outer_wall_line_width") { REQUIRE(std::stod(parser.process("{outer_wall_line_width}")) == Catch::Approx(0.67500001192092896)); }
|
||||
SECTION("support_object_xy_distance") { REQUIRE(std::stod(parser.process("{support_object_xy_distance}")) == Catch::Approx(0.35)); }
|
||||
// initial_layer_line_width ratio over nozzle_diameter.
|
||||
// FIXME: either something else which correctly calculates a ratio should be here,
|
||||
// or something else should be found for for the REQUIRE_THROWS
|
||||
// SECTION("initial_layer_line_width") { REQUIRE(std::stod(parser.process("{initial_layer_line_width}")) == Catch::Approx(0.9)); }
|
||||
// small_perimeter_speed ratio over outer_wall_speed
|
||||
SECTION("small_perimeter_speed") { REQUIRE(std::stod(parser.process("{small_perimeter_speed}")) == Catch::Approx(30.)); }
|
||||
// infill_wall_overlap over inner_wall_line_width
|
||||
// FIXME: Shouldn't this return the calculated value and not the percentage 15?
|
||||
// SECTION("infill_wall_overlap") { REQUIRE(std::stod(parser.process("{infill_wall_overlap}")) == Catch::Approx(0.16875)); }
|
||||
|
||||
// If initial_layer_line_width is set to percent, then it is applied over respective extrusion types by overriding their respective speeds.
|
||||
// The PlaceholderParser has no way to know which extrusion type the caller has in mind, therefore it throws.
|
||||
SECTION("initial_layer_line_width throws failed to resolve the ratio_over dependencies") { REQUIRE_THROWS(parser.process("{initial_layer_line_width}")); }
|
||||
SECTION("whitespaces and newlines are maintained") { REQUIRE(parser.process("test [ nozzle_temperature [foo] ] \n hu") == "test 357 \n hu"); }
|
||||
|
||||
// Test the math expressions.
|
||||
SECTION("math: 2*3") { REQUIRE(parser.process("{2*3}") == "6"); }
|
||||
|
|
@ -84,6 +66,20 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
|
|||
SECTION("math: interpolate_table(13, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(13.)); }
|
||||
SECTION("math: interpolate_table(25, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(25, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(20.)); }
|
||||
|
||||
// Test the "coFloatOrPercent" and "xxx_line_width" substitutions.
|
||||
// min_width_top_surface ratio_over inner_wall_line_width.
|
||||
SECTION("line_width") { REQUIRE(std::stod(parser.process("{line_width}")) == Catch::Approx(0.67500001192092896)); }
|
||||
SECTION("min_width_top_surface") { REQUIRE(std::stod(parser.process("{min_width_top_surface}")) == Catch::Approx(2.7)); }
|
||||
// Orca: this one is not coFloatOrPercent
|
||||
//SECTION("support_object_xy_distance") { REQUIRE(std::stod(parser.process("{support_object_xy_distance}")) == Catch::Approx(0.3375)); }
|
||||
// small_perimeter_speed over outer_wall_speed
|
||||
SECTION("small_perimeter_speed") { REQUIRE(std::stod(parser.process("{small_perimeter_speed}")) == Catch::Approx(30.)); }
|
||||
// infill_anchor over sparse_infill_line_width
|
||||
SECTION("infill_anchor") { REQUIRE(std::stod(parser.process("{infill_anchor}")) == Catch::Approx(2.7)); }
|
||||
// If scarf_joint_speed is set to percent, then it is applied over respective extrusion types by overriding their respective speeds.
|
||||
// The PlaceholderParser has no way to know which extrusion type the caller has in mind, therefore it throws.
|
||||
SECTION("scarf_joint_speed") { REQUIRE_THROWS(parser.process("{scarf_joint_speed}")); }
|
||||
|
||||
// Test the boolean expression parser.
|
||||
auto boolean_expression = [&parser](const std::string& templ) { return parser.evaluate_boolean_expression(templ, parser.config()); };
|
||||
|
||||
|
|
@ -116,3 +112,131 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
|
|||
SECTION("complex expression2") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.6 and num_extruders>1)")); }
|
||||
SECTION("complex expression3") { REQUIRE(! boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.3 and num_extruders>1)")); }
|
||||
}
|
||||
|
||||
SCENARIO("Placeholder parser variables", "[PlaceholderParser]") {
|
||||
PlaceholderParser parser;
|
||||
auto config = DynamicPrintConfig::full_print_config();
|
||||
|
||||
config.set_deserialize_strict({
|
||||
{ "filament_notes", "testnotes" },
|
||||
{ "enable_pressure_advance", "1" },
|
||||
{ "nozzle_diameter", "0.6;0.6;0.6;0.6" },
|
||||
{ "nozzle_temperature", "357;359;363;378" }
|
||||
});
|
||||
|
||||
PlaceholderParser::ContextData context_with_global_dict;
|
||||
context_with_global_dict.global_config = std::make_unique<DynamicConfig>();
|
||||
|
||||
SECTION("create an int local variable") { REQUIRE(parser.process("{local myint = 33+2}{myint}", 0, nullptr, nullptr, nullptr) == "35"); }
|
||||
SECTION("create a string local variable") { REQUIRE(parser.process("{local mystr = \"mine\" + \"only\" + \"mine\"}{mystr}", 0, nullptr, nullptr, nullptr) == "mineonlymine"); }
|
||||
SECTION("create a bool local variable") { REQUIRE(parser.process("{local mybool = 1 + 1 == 2}{mybool}", 0, nullptr, nullptr, nullptr) == "true"); }
|
||||
SECTION("create an int global variable") { REQUIRE(parser.process("{global myint = 33+2}{myint}", 0, nullptr, nullptr, &context_with_global_dict) == "35"); }
|
||||
SECTION("create a string global variable") { REQUIRE(parser.process("{global mystr = \"mine\" + \"only\" + \"mine\"}{mystr}", 0, nullptr, nullptr, &context_with_global_dict) == "mineonlymine"); }
|
||||
SECTION("create a bool global variable") { REQUIRE(parser.process("{global mybool = 1 + 1 == 2}{mybool}", 0, nullptr, nullptr, &context_with_global_dict) == "true"); }
|
||||
|
||||
SECTION("create an int local variable and overwrite it") { REQUIRE(parser.process("{local myint = 33+2}{myint = 12}{myint}", 0, nullptr, nullptr, nullptr) == "12"); }
|
||||
SECTION("create a string local variable and overwrite it") { REQUIRE(parser.process("{local mystr = \"mine\" + \"only\" + \"mine\"}{mystr = \"yours\"}{mystr}", 0, nullptr, nullptr, nullptr) == "yours"); }
|
||||
SECTION("create a bool local variable and overwrite it") { REQUIRE(parser.process("{local mybool = 1 + 1 == 2}{mybool = false}{mybool}", 0, nullptr, nullptr, nullptr) == "false"); }
|
||||
SECTION("create an int global variable and overwrite it") { REQUIRE(parser.process("{global myint = 33+2}{myint = 12}{myint}", 0, nullptr, nullptr, &context_with_global_dict) == "12"); }
|
||||
SECTION("create a string global variable and overwrite it") { REQUIRE(parser.process("{global mystr = \"mine\" + \"only\" + \"mine\"}{mystr = \"yours\"}{mystr}", 0, nullptr, nullptr, &context_with_global_dict) == "yours"); }
|
||||
SECTION("create a bool global variable and overwrite it") { REQUIRE(parser.process("{global mybool = 1 + 1 == 2}{mybool = false}{mybool}", 0, nullptr, nullptr, &context_with_global_dict) == "false"); }
|
||||
|
||||
SECTION("create an int local variable and redefine it") { REQUIRE(parser.process("{local myint = 33+2}{local myint = 12}{myint}", 0, nullptr, nullptr, nullptr) == "12"); }
|
||||
SECTION("create a string local variable and redefine it") { REQUIRE(parser.process("{local mystr = \"mine\" + \"only\" + \"mine\"}{local mystr = \"yours\"}{mystr}", 0, nullptr, nullptr, nullptr) == "yours"); }
|
||||
SECTION("create a bool local variable and redefine it") { REQUIRE(parser.process("{local mybool = 1 + 1 == 2}{local mybool = false}{mybool}", 0, nullptr, nullptr, nullptr) == "false"); }
|
||||
SECTION("create an int global variable and redefine it") { REQUIRE(parser.process("{global myint = 33+2}{global myint = 12}{myint}", 0, nullptr, nullptr, &context_with_global_dict) == "12"); }
|
||||
SECTION("create a string global variable and redefine it") { REQUIRE(parser.process("{global mystr = \"mine\" + \"only\" + \"mine\"}{global mystr = \"yours\"}{mystr}", 0, nullptr, nullptr, &context_with_global_dict) == "yours"); }
|
||||
SECTION("create a bool global variable and redefine it") { REQUIRE(parser.process("{global mybool = 1 + 1 == 2}{global mybool = false}{mybool}", 0, nullptr, nullptr, &context_with_global_dict) == "false"); }
|
||||
|
||||
SECTION("create an ints local variable with repeat()") { REQUIRE(parser.process("{local myint = repeat(2*3, 4*6)}{myint[5]}", 0, nullptr, nullptr, nullptr) == "24"); }
|
||||
SECTION("create a strings local variable with repeat()") { REQUIRE(parser.process("{local mystr = repeat(2*3, \"mine\" + \"only\" + \"mine\")}{mystr[5]}", 0, nullptr, nullptr, nullptr) == "mineonlymine"); }
|
||||
SECTION("create a bools local variable with repeat()") { REQUIRE(parser.process("{local mybool = repeat(5, 1 + 1 == 2)}{mybool[4]}", 0, nullptr, nullptr, nullptr) == "true"); }
|
||||
SECTION("create an ints global variable with repeat()") { REQUIRE(parser.process("{global myint = repeat(2*3, 4*6)}{myint[5]}", 0, nullptr, nullptr, &context_with_global_dict) == "24"); }
|
||||
SECTION("create a strings global variable with repeat()") { REQUIRE(parser.process("{global mystr = repeat(2*3, \"mine\" + \"only\" + \"mine\")}{mystr[5]}", 0, nullptr, nullptr, &context_with_global_dict) == "mineonlymine"); }
|
||||
SECTION("create a bools global variable with repeat()") { REQUIRE(parser.process("{global mybool = repeat(5, 1 + 1 == 2)}{mybool[4]}", 0, nullptr, nullptr, &context_with_global_dict) == "true"); }
|
||||
|
||||
SECTION("create an ints local variable with initializer list") { REQUIRE(parser.process("{local myint = (2*3, 4*6, 5*5)}{myint[1]}", 0, nullptr, nullptr, nullptr) == "24"); }
|
||||
SECTION("create a strings local variable with initializer list") { REQUIRE(parser.process("{local mystr = (2*3, \"mine\" + \"only\" + \"mine\", 8)}{mystr[1]}", 0, nullptr, nullptr, nullptr) == "mineonlymine"); }
|
||||
SECTION("create a bools local variable with initializer list") { REQUIRE(parser.process("{local mybool = (3*3 == 8, 1 + 1 == 2)}{mybool[1]}", 0, nullptr, nullptr, nullptr) == "true"); }
|
||||
SECTION("create an ints global variable with initializer list") { REQUIRE(parser.process("{global myint = (2*3, 4*6, 5*5)}{myint[1]}", 0, nullptr, nullptr, &context_with_global_dict) == "24"); }
|
||||
SECTION("create a strings global variable with initializer list") { REQUIRE(parser.process("{global mystr = (2*3, \"mine\" + \"only\" + \"mine\", 8)}{mystr[1]}", 0, nullptr, nullptr, &context_with_global_dict) == "mineonlymine"); }
|
||||
SECTION("create a bools global variable with initializer list") { REQUIRE(parser.process("{global mybool = (2*3 == 8, 1 + 1 == 2, 5*5 != 33)}{mybool[1]}", 0, nullptr, nullptr, &context_with_global_dict) == "true"); }
|
||||
|
||||
SECTION("create an ints local variable by a copy") { REQUIRE(parser.process("{local myint = nozzle_temperature}{myint[0]}", 0, &config, nullptr, nullptr) == "357"); }
|
||||
SECTION("create a strings local variable by a copy") { REQUIRE(parser.process("{local mystr = filament_notes}{mystr[0]}", 0, &config, nullptr, nullptr) == "testnotes"); }
|
||||
SECTION("create a bools local variable by a copy") { REQUIRE(parser.process("{local mybool = enable_pressure_advance}{mybool[0]}", 0, &config, nullptr, nullptr) == "true"); }
|
||||
SECTION("create an ints global variable by a copy") { REQUIRE(parser.process("{global myint = nozzle_temperature}{myint[0]}", 0, &config, nullptr, &context_with_global_dict) == "357"); }
|
||||
SECTION("create a strings global variable by a copy") { REQUIRE(parser.process("{global mystr = filament_notes}{mystr[0]}", 0, &config, nullptr, &context_with_global_dict) == "testnotes"); }
|
||||
SECTION("create a bools global variable by a copy") { REQUIRE(parser.process("{global mybool = enable_pressure_advance}{mybool[0]}", 0, &config, nullptr, &context_with_global_dict) == "true"); }
|
||||
|
||||
SECTION("create an ints local variable by a copy and overwrite it") {
|
||||
REQUIRE(parser.process("{local myint = nozzle_temperature}{myint = repeat(2*3, 4*6)}{myint[5]}", 0, &config, nullptr, nullptr) == "24");
|
||||
REQUIRE(parser.process("{local myint = nozzle_temperature}{myint = (2*3, 4*6)}{myint[1]}", 0, &config, nullptr, nullptr) == "24");
|
||||
REQUIRE(parser.process("{local myint = nozzle_temperature}{myint = (1)}{myint = nozzle_temperature}{myint[0]}", 0, &config, nullptr, nullptr) == "357");
|
||||
}
|
||||
SECTION("create a strings local variable by a copy and overwrite it") {
|
||||
REQUIRE(parser.process("{local mystr = filament_notes}{mystr = repeat(2*3, \"mine\" + \"only\" + \"mine\")}{mystr[5]}", 0, &config, nullptr, nullptr) == "mineonlymine");
|
||||
REQUIRE(parser.process("{local mystr = filament_notes}{mystr = (2*3, \"mine\" + \"only\" + \"mine\")}{mystr[1]}", 0, &config, nullptr, nullptr) == "mineonlymine");
|
||||
REQUIRE(parser.process("{local mystr = filament_notes}{mystr = (2*3, \"mine\" + \"only\" + \"mine\")}{mystr = filament_notes}{mystr[0]}", 0, &config, nullptr, nullptr) == "testnotes");
|
||||
}
|
||||
SECTION("create a bools local variable by a copy and overwrite it") {
|
||||
REQUIRE(parser.process("{local mybool = enable_pressure_advance}{mybool = repeat(2*3, true)}{mybool[5]}", 0, &config, nullptr, nullptr) == "true");
|
||||
REQUIRE(parser.process("{local mybool = enable_pressure_advance}{mybool = (false, true)}{mybool[1]}", 0, &config, nullptr, nullptr) == "true");
|
||||
REQUIRE(parser.process("{local mybool = enable_pressure_advance}{mybool = (false, false)}{mybool = enable_pressure_advance}{mybool[0]}", 0, &config, nullptr, nullptr) == "true");
|
||||
}
|
||||
|
||||
SECTION("size() of a non-empty vector returns the right size") { REQUIRE(parser.process("{local myint = (0, 1, 2, 3)}{size(myint)}", 0, nullptr, nullptr, nullptr) == "4"); }
|
||||
SECTION("size() of a an empty vector returns the right size") { REQUIRE(parser.process("{local myint = (0);myint=();size(myint)}", 0, nullptr, nullptr, nullptr) == "0"); }
|
||||
SECTION("empty() of a non-empty vector returns false") { REQUIRE(parser.process("{local myint = (0, 1, 2, 3)}{empty(myint)}", 0, nullptr, nullptr, nullptr) == "false"); }
|
||||
SECTION("empty() of a an empty vector returns true") { REQUIRE(parser.process("{local myint = (0);myint=();empty(myint)}", 0, nullptr, nullptr, nullptr) == "true"); }
|
||||
|
||||
SECTION("nested if with new variables") {
|
||||
std::string script =
|
||||
"{if 1 == 1}{local myints = (5, 4, 3, 2, 1)}{else}{local myfloats = (1., 2., 3., 4., 5., 6., 7.)}{endif}"
|
||||
"{myints[1]},{size(myints)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "4,5");
|
||||
}
|
||||
SECTION("nested if with new variables 2") {
|
||||
std::string script =
|
||||
"{if 1 == 0}{local myints = (5, 4, 3, 2, 1)}{else}{local myfloats = (1., 2., 3., 4., 5., 6., 7.)}{endif}"
|
||||
"{size(myfloats)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "7");
|
||||
}
|
||||
SECTION("nested if with new variables 2, mixing }{ with ;") {
|
||||
std::string script =
|
||||
"{if 1 == 0 then local myints = (5, 4, 3, 2, 1);else;local myfloats = (1., 2., 3., 4., 5., 6., 7.);endif}"
|
||||
"{size(myfloats)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "7");
|
||||
}
|
||||
SECTION("nested if with new variables, two level") {
|
||||
std::string script =
|
||||
"{if 1 == 1}{if 2 == 3}{nejaka / haluz}{else}{local myints = (6, 5, 4, 3, 2, 1)}{endif}{else}{if zase * haluz}{else}{local myfloats = (1., 2., 3., 4., 5., 6., 7.)}{endif}{endif}"
|
||||
"{size(myints)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "6");
|
||||
}
|
||||
SECTION("if with empty block and ;") {
|
||||
std::string script =
|
||||
"{if false then else;local myfloats = (1., 2., 3., 4., 5., 6., 7.);endif}"
|
||||
"{size(myfloats)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "7");
|
||||
}
|
||||
SECTION("nested if with new variables, two level, mixing }{ with ;") {
|
||||
std::string script =
|
||||
"{if 1 == 1 then if 2 == 3}nejaka / haluz{else local myints = (6, 5, 4, 3, 2, 1) endif else if zase * haluz then else local myfloats = (1., 2., 3., 4., 5., 6., 7.) endif endif}"
|
||||
"{size(myints)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "6");
|
||||
}
|
||||
SECTION("nested if with new variables, two level, mixing }{ with ; 2") {
|
||||
std::string script =
|
||||
"{if 1 == 1 then if 2 == 3 then nejaka / haluz else}{local myints = (6, 5, 4, 3, 2, 1)}{endif else if zase * haluz then else local myfloats = (1., 2., 3., 4., 5., 6., 7.) endif endif}"
|
||||
"{size(myints)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "6");
|
||||
}
|
||||
SECTION("nested if with new variables, two level, mixing }{ with ; 3") {
|
||||
std::string script =
|
||||
"{if 1 == 1 then if 2 == 3 then nejaka / haluz else}{local myints = (6, 5, 4, 3, 2, 1)}{endif else}{if zase * haluz}{else local myfloats = (1., 2., 3., 4., 5., 6., 7.) endif}{endif}"
|
||||
"{size(myints)}";
|
||||
REQUIRE(parser.process(script, 0, nullptr, nullptr, nullptr) == "6");
|
||||
}
|
||||
SECTION("if else completely empty") { REQUIRE(parser.process("{if false then elsif false then else endif}", 0, nullptr, nullptr, nullptr) == ""); }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue