mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-24 21:55:14 +00:00
Compare commits
9 Commits
feature/ht
...
fix/linux-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a862b5d5a | ||
|
|
ff68a2859d | ||
|
|
46e47cec0a | ||
|
|
f4a9830752 | ||
|
|
1f2ed70288 | ||
|
|
3370e224b2 | ||
|
|
7fc1e109c5 | ||
|
|
374e4ad8a9 | ||
|
|
d0fbda3af1 |
@@ -94,8 +94,8 @@ text = Switch workspaces\nYou can switch between <b>Prepare</b> and <b>Preview</
|
|||||||
[hint:How to use keyboard shortcuts]
|
[hint:How to use keyboard shortcuts]
|
||||||
text = How to use keyboard shortcuts\nDid you know that Orca Slicer offers a wide range of keyboard shortcuts and 3D scene operations?
|
text = How to use keyboard shortcuts\nDid you know that Orca Slicer offers a wide range of keyboard shortcuts and 3D scene operations?
|
||||||
|
|
||||||
[hint:Reverse on odd]
|
[hint:Reverse on even]
|
||||||
text = Reverse on odd\nDid you know that <b>Reverse on odd</b> feature can significantly improve the surface quality of your overhangs?
|
text = Reverse on even\nDid you know that <b>Reverse on even</b> feature can significantly improve the surface quality of your overhangs? However, it can cause wall inconsistencies so use carefully!
|
||||||
|
|
||||||
[hint:Cut Tool]
|
[hint:Cut Tool]
|
||||||
text = Cut Tool\nDid you know that you can cut a model at any angle and position with the cutting tool?
|
text = Cut Tool\nDid you know that you can cut a model at any angle and position with the cutting tool?
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
@@ -1,237 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "machine",
|
|
||||||
"name": "Anet A8 Plus 0.4 nozzle",
|
|
||||||
"inherits": "",
|
|
||||||
"from": "User",
|
|
||||||
"adaptive_bed_mesh_margin": "0",
|
|
||||||
"auxiliary_fan": "0",
|
|
||||||
"bbl_use_printhost": "0",
|
|
||||||
"bed_custom_model": "",
|
|
||||||
"bed_custom_texture": "",
|
|
||||||
"bed_exclude_area": [
|
|
||||||
"0x0"
|
|
||||||
],
|
|
||||||
"bed_mesh_max": "99999,99999",
|
|
||||||
"bed_mesh_min": "-99999,-99999",
|
|
||||||
"bed_mesh_probe_distance": "50,50",
|
|
||||||
"before_layer_change_gcode": ";BEFORE_LAYER_CHANGE\n;[layer_z]\nG92 E0\n",
|
|
||||||
"best_object_pos": "0.5,0.5",
|
|
||||||
"change_extrusion_role_gcode": "",
|
|
||||||
"change_filament_gcode": "M600",
|
|
||||||
"cooling_tube_length": "5",
|
|
||||||
"cooling_tube_retraction": "91.5",
|
|
||||||
"default_bed_type": "",
|
|
||||||
"default_filament_profile": [
|
|
||||||
"Anycubic Generic PLA"
|
|
||||||
],
|
|
||||||
"default_print_profile": "0.20mm Standard @Anycubic 4MaxPro2",
|
|
||||||
"deretraction_speed": [
|
|
||||||
"25"
|
|
||||||
],
|
|
||||||
"disable_m73": "0",
|
|
||||||
"emit_machine_limits_to_gcode": "1",
|
|
||||||
"enable_filament_ramming": "1",
|
|
||||||
"enable_long_retraction_when_cut": "0",
|
|
||||||
"extra_loading_move": "-2",
|
|
||||||
"extruder_clearance_height_to_lid": "140",
|
|
||||||
"extruder_clearance_height_to_rod": "36",
|
|
||||||
"extruder_clearance_radius": "65",
|
|
||||||
"extruder_colour": [
|
|
||||||
"#018001"
|
|
||||||
],
|
|
||||||
"extruder_offset": [
|
|
||||||
"0x0"
|
|
||||||
],
|
|
||||||
"fan_kickstart": "0",
|
|
||||||
"fan_speedup_overhangs": "1",
|
|
||||||
"fan_speedup_time": "0",
|
|
||||||
"gcode_flavor": "marlin",
|
|
||||||
"head_wrap_detect_zone": [],
|
|
||||||
"high_current_on_filament_swap": "0",
|
|
||||||
"host_type": "octoprint",
|
|
||||||
"layer_change_gcode": ";AFTER_LAYER_CHANGE\n;[layer_z]",
|
|
||||||
"long_retractions_when_cut": [
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"machine_end_gcode": "M104 S0 ; turn off extruder heating\nM140 S0 ; turn off bed heating\nM107 ; turn off fans\nG91 ; relative positioning\nG0 Z+0.5 ; move Z up a tiny bit\nG90 ; absolute positioning\nG0 X135 Y105 F{machine_max_speed_x[0]*60} ; move extruder to center position\nG0 Z190.5 F{machine_max_speed_z[0]*60} ; lower the plattform to Z min\nM84 ; steppers off\nG90 ; absolute positioning\n",
|
|
||||||
"machine_load_filament_time": "0",
|
|
||||||
"machine_max_acceleration_e": [
|
|
||||||
"5000",
|
|
||||||
"5000"
|
|
||||||
],
|
|
||||||
"machine_max_acceleration_extruding": [
|
|
||||||
"1250",
|
|
||||||
"1250"
|
|
||||||
],
|
|
||||||
"machine_max_acceleration_retracting": [
|
|
||||||
"1250",
|
|
||||||
"1250"
|
|
||||||
],
|
|
||||||
"machine_max_acceleration_travel": [
|
|
||||||
"1500",
|
|
||||||
"1500"
|
|
||||||
],
|
|
||||||
"machine_max_acceleration_x": [
|
|
||||||
"1000",
|
|
||||||
"900"
|
|
||||||
],
|
|
||||||
"machine_max_acceleration_y": [
|
|
||||||
"1000",
|
|
||||||
"900"
|
|
||||||
],
|
|
||||||
"machine_max_acceleration_z": [
|
|
||||||
"1000",
|
|
||||||
"100"
|
|
||||||
],
|
|
||||||
"machine_max_jerk_e": [
|
|
||||||
"5",
|
|
||||||
"5"
|
|
||||||
],
|
|
||||||
"machine_max_jerk_x": [
|
|
||||||
"6",
|
|
||||||
"6"
|
|
||||||
],
|
|
||||||
"machine_max_jerk_y": [
|
|
||||||
"6",
|
|
||||||
"6"
|
|
||||||
],
|
|
||||||
"machine_max_jerk_z": [
|
|
||||||
"0.2",
|
|
||||||
"0.2"
|
|
||||||
],
|
|
||||||
"machine_max_junction_deviation": [
|
|
||||||
"0.10",
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"machine_max_speed_e": [
|
|
||||||
"120",
|
|
||||||
"120"
|
|
||||||
],
|
|
||||||
"machine_max_speed_x": [
|
|
||||||
"200",
|
|
||||||
"200"
|
|
||||||
],
|
|
||||||
"machine_max_speed_y": [
|
|
||||||
"200",
|
|
||||||
"200"
|
|
||||||
],
|
|
||||||
"machine_max_speed_z": [
|
|
||||||
"64",
|
|
||||||
"16"
|
|
||||||
],
|
|
||||||
"machine_min_extruding_rate": [
|
|
||||||
"0",
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"machine_min_travel_rate": [
|
|
||||||
"0",
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"machine_pause_gcode": "M601",
|
|
||||||
"machine_start_gcode": "G21 ; metric values\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 X0 Y0 ; home X and Y\nG28 Z0 ; home Z\nG1 Z30 F{machine_max_speed_z[0]*60} ; move Z a bit down to not blow on the bed edge while heating\nG1 X10 F3900 ; let some space on x to prevent the filament cooling exhaust from beeing blocked by the servo motor\nM190 S[bed_temperature_initial_layer_single] ; wait for bed temp\nM104 S[nozzle_temperature_initial_layer] ; set extruder temp\nM106 S80 ; turn on fan to prevent air nozzle melt while heating up\nM109 S[nozzle_temperature_initial_layer] ; wait for extruder temp\nM107 ; start with the fan off\nG28 X0 ; goto X home again\nG92 E0 ; zero the extruded length\nG1 Z0.2 F360 ; move plattform upwards\n; extrude material next to the plattform (comment or remove following lines to disable)\nG1 F180 E20 ; extrude some material next to the plattform\nG92 E0 ; zero the extruded length\nG1 E-[retraction_length] F{retraction_speed[0]*60} ; do a filament retract\nG92 E0 ; zero the extruded length again\nG1 X5 F3900 ; move sideways to get rid of that string\nG1 E[retraction_length] F{retraction_speed[0]*60} ; do a filament deretract with retract parameters\nG92 E0 ; zero the extruded length again\n; draw intro line (comment or remove following lines to disable)\nG1 X30 E5 F700 ; draw intro line\nG92 E0 ; zero the extruded length\nG1 E-[retraction_length] F{retraction_speed[0]*60} ; do a filament retract\nG1 X40 Z2.0 ; move away from the introline\nG92 E0 ; zero the extruded length again\nG1 E[retraction_length] F{retraction_speed[0]*60} ; do a filament deretract with retract parameters\n; end of intro line code\nM117 Printing...\nG5",
|
|
||||||
"machine_tool_change_time": "0",
|
|
||||||
"machine_unload_filament_time": "0",
|
|
||||||
"manual_filament_change": "0",
|
|
||||||
"max_layer_height": [
|
|
||||||
"0.3"
|
|
||||||
],
|
|
||||||
"max_resonance_avoidance_speed": "120",
|
|
||||||
"min_layer_height": [
|
|
||||||
"0.07"
|
|
||||||
],
|
|
||||||
"min_resonance_avoidance_speed": "70",
|
|
||||||
"nozzle_diameter": [
|
|
||||||
"0.4"
|
|
||||||
],
|
|
||||||
"nozzle_height": "2.5",
|
|
||||||
"nozzle_hrc": "0",
|
|
||||||
"nozzle_type": "undefine",
|
|
||||||
"nozzle_volume": "0",
|
|
||||||
"parking_pos_retraction": "92",
|
|
||||||
"pellet_modded_printer": "0",
|
|
||||||
"preferred_orientation": "0",
|
|
||||||
"printable_area": [
|
|
||||||
"0x0",
|
|
||||||
"300x0",
|
|
||||||
"300x300",
|
|
||||||
"0x300"
|
|
||||||
],
|
|
||||||
"printable_height": "350",
|
|
||||||
"printer_model": "Anet A8 Plus",
|
|
||||||
"printer_notes": "",
|
|
||||||
"printer_settings_id": "Anet A8 Plus 0.4 nozzle",
|
|
||||||
"printer_structure": "undefine",
|
|
||||||
"printer_technology": "FFF",
|
|
||||||
"printer_variant": "0.4",
|
|
||||||
"printhost_authorization_type": "key",
|
|
||||||
"printhost_ssl_ignore_revoke": "0",
|
|
||||||
"printing_by_object_gcode": "",
|
|
||||||
"purge_in_prime_tower": "1",
|
|
||||||
"resonance_avoidance": "0",
|
|
||||||
"retract_before_wipe": [
|
|
||||||
"0%"
|
|
||||||
],
|
|
||||||
"retract_length_toolchange": [
|
|
||||||
"10"
|
|
||||||
],
|
|
||||||
"retract_lift_above": [
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"retract_lift_below": [
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"retract_lift_enforce": [
|
|
||||||
"All Surfaces"
|
|
||||||
],
|
|
||||||
"retract_restart_extra": [
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"retract_restart_extra_toolchange": [
|
|
||||||
"0"
|
|
||||||
],
|
|
||||||
"retract_when_changing_layer": [
|
|
||||||
"1"
|
|
||||||
],
|
|
||||||
"retraction_distances_when_cut": [
|
|
||||||
"18"
|
|
||||||
],
|
|
||||||
"retraction_length": [
|
|
||||||
"2.5"
|
|
||||||
],
|
|
||||||
"retraction_minimum_travel": [
|
|
||||||
"2"
|
|
||||||
],
|
|
||||||
"retraction_speed": [
|
|
||||||
"35"
|
|
||||||
],
|
|
||||||
"scan_first_layer": "0",
|
|
||||||
"silent_mode": "0",
|
|
||||||
"single_extruder_multi_material": "1",
|
|
||||||
"support_air_filtration": "1",
|
|
||||||
"support_chamber_temp_control": "1",
|
|
||||||
"support_multi_bed_types": "0",
|
|
||||||
"template_custom_gcode": "",
|
|
||||||
"thumbnails": "48x48/PNG,300x300/PNG",
|
|
||||||
"thumbnails_format": "PNG",
|
|
||||||
"time_cost": "0",
|
|
||||||
"time_lapse_gcode": "",
|
|
||||||
"travel_slope": [
|
|
||||||
"3"
|
|
||||||
],
|
|
||||||
"upward_compatible_machine": [],
|
|
||||||
"use_firmware_retraction": "0",
|
|
||||||
"use_relative_e_distances": "1",
|
|
||||||
"wipe": [
|
|
||||||
"1"
|
|
||||||
],
|
|
||||||
"wipe_distance": [
|
|
||||||
"1"
|
|
||||||
],
|
|
||||||
"z_hop": [
|
|
||||||
"0.4"
|
|
||||||
],
|
|
||||||
"z_hop_types": [
|
|
||||||
"Normal Lift"
|
|
||||||
],
|
|
||||||
"z_offset": "0"
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -719,6 +719,9 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
// Second generate the adjusted G-code.
|
// Second generate the adjusted G-code.
|
||||||
std::string new_gcode;
|
std::string new_gcode;
|
||||||
new_gcode.reserve(gcode.size() * 2);
|
new_gcode.reserve(gcode.size() * 2);
|
||||||
|
// ORCA: per-printer minimum non-zero fan PWM. Applied at every part-cooling fan emission below so any
|
||||||
|
// non-zero command is raised to at least this percent (0 disables the clamp).
|
||||||
|
const unsigned int part_cooling_fan_min_pwm = static_cast<unsigned int>(std::max(0, m_config.part_cooling_fan_min_pwm.value));
|
||||||
bool overhang_fan_control= false;
|
bool overhang_fan_control= false;
|
||||||
int overhang_fan_speed = 0;
|
int overhang_fan_speed = 0;
|
||||||
bool internal_bridge_fan_control= false; // ORCA: Add support for separate internal bridge fan speed control
|
bool internal_bridge_fan_control= false; // ORCA: Add support for separate internal bridge fan speed control
|
||||||
@@ -727,7 +730,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
int supp_interface_fan_speed = 0;
|
int supp_interface_fan_speed = 0;
|
||||||
bool ironing_fan_control= false; // ORCA: Add support for ironing fan speed control
|
bool ironing_fan_control= false; // ORCA: Add support for ironing fan speed control
|
||||||
int ironing_fan_speed = 0; // ORCA: Add support for ironing fan speed control
|
int ironing_fan_speed = 0; // ORCA: Add support for ironing fan speed control
|
||||||
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode,
|
auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, part_cooling_fan_min_pwm,
|
||||||
&overhang_fan_control, &overhang_fan_speed,
|
&overhang_fan_control, &overhang_fan_speed,
|
||||||
&internal_bridge_fan_control, &internal_bridge_fan_speed,
|
&internal_bridge_fan_control, &internal_bridge_fan_speed,
|
||||||
&supp_interface_fan_control, &supp_interface_fan_speed,
|
&supp_interface_fan_control, &supp_interface_fan_speed,
|
||||||
@@ -743,11 +746,11 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer);
|
int full_fan_speed_layer = EXTRUDER_CONFIG(full_fan_speed_layer);
|
||||||
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
supp_interface_fan_speed = EXTRUDER_CONFIG(support_material_interface_fan_speed);
|
||||||
|
|
||||||
if (close_fan_the_first_x_layers <= 0 && full_fan_speed_layer > 0) {
|
// ORCA: previously a silent override forced `close_fan_the_first_x_layers` from 0 up to 1 whenever a ramp
|
||||||
// When ramping up fan speed from close_fan_the_first_x_layers to full_fan_speed_layer, force close_fan_the_first_x_layers above zero,
|
// was configured (`full_fan_speed_layer > 0`), so the first printed layer always had the fan disabled.
|
||||||
// so there will be a zero fan speed at least at the 1st layer.
|
// That hid the user's literal "no cooling for the first 0 layers" setting and produced a non-zero starting
|
||||||
close_fan_the_first_x_layers = 1;
|
// factor on the ramp denominator. The override has been removed: with N=0 and M>0 the ramp now genuinely
|
||||||
}
|
// starts on layer 0 at a factor of 1/M and reaches 100% at layer M-1, matching the intent of the option.
|
||||||
if (int(layer_id) >= close_fan_the_first_x_layers) {
|
if (int(layer_id) >= close_fan_the_first_x_layers) {
|
||||||
float fan_max_speed = EXTRUDER_CONFIG(fan_max_speed);
|
float fan_max_speed = EXTRUDER_CONFIG(fan_max_speed);
|
||||||
float slow_down_layer_time = float(EXTRUDER_CONFIG(slow_down_layer_time));
|
float slow_down_layer_time = float(EXTRUDER_CONFIG(slow_down_layer_time));
|
||||||
@@ -806,7 +809,7 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
m_fan_speed = fan_speed_new;
|
m_fan_speed = fan_speed_new;
|
||||||
m_current_fan_speed = fan_speed_new;
|
m_current_fan_speed = fan_speed_new;
|
||||||
if (immediately_apply)
|
if (immediately_apply)
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed, part_cooling_fan_min_pwm);
|
||||||
}
|
}
|
||||||
//BBS
|
//BBS
|
||||||
if (additional_fan_speed_new != m_additional_fan_speed) {
|
if (additional_fan_speed_new != m_additional_fan_speed) {
|
||||||
@@ -980,26 +983,26 @@ std::string CoolingBuffer::apply_layer_cooldown(
|
|||||||
|
|
||||||
if (need_set_fan) {
|
if (need_set_fan) {
|
||||||
if (fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]){
|
if (fan_speed_change_requests[CoolingLine::TYPE_OVERHANG_FAN_START]){
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, overhang_fan_speed, part_cooling_fan_min_pwm);
|
||||||
m_current_fan_speed = overhang_fan_speed;
|
m_current_fan_speed = overhang_fan_speed;
|
||||||
} else if (fan_speed_change_requests[CoolingLine::TYPE_INTERNAL_BRIDGE_FAN_START]){ // ORCA: Add support for separate internal bridge fan speed control
|
} else if (fan_speed_change_requests[CoolingLine::TYPE_INTERNAL_BRIDGE_FAN_START]){ // ORCA: Add support for separate internal bridge fan speed control
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, internal_bridge_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, internal_bridge_fan_speed, part_cooling_fan_min_pwm);
|
||||||
m_current_fan_speed = internal_bridge_fan_speed;
|
m_current_fan_speed = internal_bridge_fan_speed;
|
||||||
}
|
}
|
||||||
else if (fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]){
|
else if (fan_speed_change_requests[CoolingLine::TYPE_SUPPORT_INTERFACE_FAN_START]){
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, supp_interface_fan_speed, part_cooling_fan_min_pwm);
|
||||||
m_current_fan_speed = supp_interface_fan_speed;
|
m_current_fan_speed = supp_interface_fan_speed;
|
||||||
}
|
}
|
||||||
else if (fan_speed_change_requests[CoolingLine::TYPE_IRONING_FAN_START]){
|
else if (fan_speed_change_requests[CoolingLine::TYPE_IRONING_FAN_START]){
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, ironing_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, ironing_fan_speed, part_cooling_fan_min_pwm);
|
||||||
m_current_fan_speed = ironing_fan_speed;
|
m_current_fan_speed = ironing_fan_speed;
|
||||||
}
|
}
|
||||||
else if(fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] && m_current_fan_speed != -1){
|
else if(fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] && m_current_fan_speed != -1){
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_current_fan_speed, part_cooling_fan_min_pwm);
|
||||||
fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = false;
|
fan_speed_change_requests[CoolingLine::TYPE_FORCE_RESUME_FAN] = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed);
|
new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_fan_speed, part_cooling_fan_min_pwm);
|
||||||
need_set_fan = false;
|
need_set_fan = false;
|
||||||
}
|
}
|
||||||
pos = line_end;
|
pos = line_end;
|
||||||
|
|||||||
@@ -230,7 +230,10 @@ void FanMover::_remove_slow_fan(int16_t min_speed, float past_sec) {
|
|||||||
|
|
||||||
std::string FanMover::_set_fan(int16_t speed) {
|
std::string FanMover::_set_fan(int16_t speed) {
|
||||||
//const Tool* tool = m_writer.get_tool(m_currrent_extruder < 20 ? m_currrent_extruder : 0);
|
//const Tool* tool = m_writer.get_tool(m_currrent_extruder < 20 ? m_currrent_extruder : 0);
|
||||||
return GCodeWriter::set_fan(m_writer.config.gcode_flavor.value, speed);
|
// ORCA: apply the per-printer non-zero fan PWM floor so reposted fan commands respect the clamp too.
|
||||||
|
const int floor_pct = m_writer.config.part_cooling_fan_min_pwm.value;
|
||||||
|
const unsigned int part_cooling_fan_min_pwm = floor_pct > 0 ? static_cast<unsigned int>(floor_pct) : 0u;
|
||||||
|
return GCodeWriter::set_fan(m_writer.config.gcode_flavor.value, speed, part_cooling_fan_min_pwm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1092,9 +1092,13 @@ std::string GCodeWriter::unlift()
|
|||||||
return gcode;
|
return gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int speed)
|
std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm)
|
||||||
{
|
{
|
||||||
std::ostringstream gcode;
|
std::ostringstream gcode;
|
||||||
|
// ORCA: clamp non-zero fan commands up to the configured PWM floor so fans that can't spool at low duty
|
||||||
|
// cycles still start reliably. Zero (fan off) is preserved exactly so disable-fan commands are never altered.
|
||||||
|
if (speed > 0 && part_cooling_fan_min_pwm > 0 && speed < part_cooling_fan_min_pwm)
|
||||||
|
speed = part_cooling_fan_min_pwm;
|
||||||
if (speed == 0) {
|
if (speed == 0) {
|
||||||
switch (gcode_flavor) {
|
switch (gcode_flavor) {
|
||||||
case gcfTeacup:
|
case gcfTeacup:
|
||||||
@@ -1129,7 +1133,9 @@ std::string GCodeWriter::set_fan(const GCodeFlavor gcode_flavor, unsigned int sp
|
|||||||
std::string GCodeWriter::set_fan(unsigned int speed) const
|
std::string GCodeWriter::set_fan(unsigned int speed) const
|
||||||
{
|
{
|
||||||
//BBS
|
//BBS
|
||||||
return GCodeWriter::set_fan(this->config.gcode_flavor, speed);
|
// ORCA: pick up the per-printer PWM floor from the active config.
|
||||||
|
return GCodeWriter::set_fan(this->config.gcode_flavor, speed,
|
||||||
|
static_cast<unsigned int>(std::max(0, this->config.part_cooling_fan_min_pwm.value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//BBS: set additional fan speed for BBS machine only
|
//BBS: set additional fan speed for BBS machine only
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ public:
|
|||||||
void set_xy_offset(double x, double y) { m_x_offset = x; m_y_offset = y; }
|
void set_xy_offset(double x, double y) { m_x_offset = x; m_y_offset = y; }
|
||||||
Vec2f get_xy_offset() { return Vec2f{m_x_offset, m_y_offset}; };
|
Vec2f get_xy_offset() { return Vec2f{m_x_offset, m_y_offset}; };
|
||||||
// To be called by the CoolingBuffer from another thread.
|
// To be called by the CoolingBuffer from another thread.
|
||||||
static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed);
|
// ORCA: `part_cooling_fan_min_pwm` (0-100, default 0) is a floor applied only when `speed` is non-zero, used to overcome
|
||||||
|
// PWM start-up thresholds on fans that won't spool below a certain duty cycle. A `speed` of 0 is always honoured.
|
||||||
|
static std::string set_fan(const GCodeFlavor gcode_flavor, unsigned int speed, unsigned int part_cooling_fan_min_pwm = 0);
|
||||||
// To be called by the main thread. It always emits the G-code, it does not remember the previous state.
|
// To be called by the main thread. It always emits the G-code, it does not remember the previous state.
|
||||||
// Keeping the state is left to the CoolingBuffer, which runs asynchronously on another thread.
|
// Keeping the state is left to the CoolingBuffer, which runs asynchronously on another thread.
|
||||||
std::string set_fan(unsigned int speed) const;
|
std::string set_fan(unsigned int speed) const;
|
||||||
|
|||||||
@@ -1326,7 +1326,7 @@ static std::vector<std::string> s_Preset_machine_limits_options {
|
|||||||
static std::vector<std::string> s_Preset_printer_options {
|
static std::vector<std::string> s_Preset_printer_options {
|
||||||
"printer_technology",
|
"printer_technology",
|
||||||
"printable_area", "extruder_printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor",
|
"printable_area", "extruder_printable_area", "bed_exclude_area","bed_custom_texture", "bed_custom_model", "gcode_flavor",
|
||||||
"fan_kickstart", "fan_speedup_time", "fan_speedup_overhangs",
|
"fan_kickstart", "part_cooling_fan_min_pwm", "fan_speedup_time", "fan_speedup_overhangs",
|
||||||
"single_extruder_multi_material", "manual_filament_change", "file_start_gcode", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "printing_by_object_gcode", "layer_change_gcode", "time_lapse_gcode", "wrapping_detection_gcode", "change_filament_gcode", "change_extrusion_role_gcode",
|
"single_extruder_multi_material", "manual_filament_change", "file_start_gcode", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "printing_by_object_gcode", "layer_change_gcode", "time_lapse_gcode", "wrapping_detection_gcode", "change_filament_gcode", "change_extrusion_role_gcode",
|
||||||
"printer_model", "printer_variant", "printer_extruder_id", "printer_extruder_variant", "extruder_variant_list", "default_nozzle_volume_type",
|
"printer_model", "printer_variant", "printer_extruder_id", "printer_extruder_variant", "extruder_variant_list", "default_nozzle_volume_type",
|
||||||
"printable_height", "extruder_printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
"printable_height", "extruder_printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod",
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||||||
"fan_cooling_layer_time",
|
"fan_cooling_layer_time",
|
||||||
"full_fan_speed_layer",
|
"full_fan_speed_layer",
|
||||||
"fan_kickstart",
|
"fan_kickstart",
|
||||||
|
"part_cooling_fan_min_pwm",
|
||||||
"fan_speedup_overhangs",
|
"fan_speedup_overhangs",
|
||||||
"fan_speedup_time",
|
"fan_speedup_time",
|
||||||
"filament_colour",
|
"filament_colour",
|
||||||
@@ -1753,46 +1754,47 @@ StringObjectException Print::validate(StringObjectException *warning, Polygons*
|
|||||||
};
|
};
|
||||||
std::string warning_key;
|
std::string warning_key;
|
||||||
|
|
||||||
|
const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0];
|
||||||
|
const bool ignore_jerk_validation = m_config.gcode_flavor == gcfMarlinFirmware && max_junction_deviation > 0;
|
||||||
|
|
||||||
// check jerk
|
// check jerk
|
||||||
if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 ||
|
if (!ignore_jerk_validation) {
|
||||||
m_default_object_config.inner_wall_jerk == 1) {
|
if (m_default_object_config.default_jerk == 1 || m_default_object_config.outer_wall_jerk == 1 ||
|
||||||
warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces");
|
m_default_object_config.inner_wall_jerk == 1) {
|
||||||
if (m_default_object_config.outer_wall_jerk == 1)
|
warning->string = L("Setting the jerk speed too low could lead to artifacts on curved surfaces");
|
||||||
warning_key = "outer_wall_jerk";
|
if (m_default_object_config.outer_wall_jerk == 1)
|
||||||
else if (m_default_object_config.inner_wall_jerk == 1)
|
warning_key = "outer_wall_jerk";
|
||||||
warning_key = "inner_wall_jerk";
|
else if (m_default_object_config.inner_wall_jerk == 1)
|
||||||
else
|
warning_key = "inner_wall_jerk";
|
||||||
warning_key = "default_jerk";
|
else
|
||||||
|
warning_key = "default_jerk";
|
||||||
|
|
||||||
warning->opt_key = warning_key;
|
warning->opt_key = warning_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (warning_key.empty() && m_default_object_config.default_jerk > 0) {
|
if (warning_key.empty() && m_default_object_config.default_jerk > 0) {
|
||||||
std::vector<std::string> jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk",
|
std::vector<std::string> jerk_to_check = {"default_jerk", "outer_wall_jerk", "inner_wall_jerk", "infill_jerk",
|
||||||
"top_surface_jerk", "initial_layer_jerk", "travel_jerk"};
|
"top_surface_jerk", "initial_layer_jerk", "travel_jerk"};
|
||||||
const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]);
|
const auto max_jerk = std::min(m_config.machine_max_jerk_x.values[0], m_config.machine_max_jerk_y.values[0]);
|
||||||
warning_key.clear();
|
warning_key.clear();
|
||||||
if (m_default_object_config.default_jerk > 0)
|
warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk);
|
||||||
warning_key = check_motion_ability_object_setting(jerk_to_check, max_jerk);
|
if (!warning_key.empty()) {
|
||||||
if (!warning_key.empty()) {
|
warning->string = L(
|
||||||
warning->string = L(
|
"The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\n"
|
||||||
"The jerk setting exceeds the printer's maximum jerk (machine_max_jerk_x/machine_max_jerk_y).\nOrca will "
|
"Orca will automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\n"
|
||||||
"automatically cap the jerk speed to ensure it doesn't surpass the printer's capabilities.\nYou can adjust the "
|
"You can adjust the maximum jerk setting in your printer's configuration to get higher speeds.");
|
||||||
"maximum jerk setting in your printer's configuration to get higher speeds.");
|
warning->opt_key = warning_key;
|
||||||
warning->opt_key = warning_key;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check junction deviation
|
// Check junction deviation
|
||||||
const auto max_junction_deviation = m_config.machine_max_junction_deviation.values[0];
|
|
||||||
// Orca: Only marlin FW supports max junction deviation. Dont display warning if firmware is not supporting it.
|
// Orca: Only marlin FW supports max junction deviation. Dont display warning if firmware is not supporting it.
|
||||||
const bool support_max_junction_deviation = ( m_config.gcode_flavor == gcfMarlinFirmware);
|
const bool support_max_junction_deviation = ( m_config.gcode_flavor == gcfMarlinFirmware);
|
||||||
if (warning_key.empty() && m_default_object_config.default_junction_deviation.value > max_junction_deviation && support_max_junction_deviation) {
|
if (warning_key.empty() && m_default_object_config.default_junction_deviation.value > max_junction_deviation && support_max_junction_deviation) {
|
||||||
warning->string = L( "Junction deviation setting exceeds the printer's maximum value "
|
warning->string = L( "Junction deviation setting exceeds the printer's maximum value (machine_max_junction_deviation).\n"
|
||||||
"(machine_max_junction_deviation).\nOrca will "
|
"Orca will automatically cap the junction deviation to ensure it doesn't surpass the printer's capabilities.\n"
|
||||||
"automatically cap the junction deviation to ensure it doesn't surpass the printer's "
|
"You can adjust the machine_max_junction_deviation value in your printer's configuration to get higher limits.");
|
||||||
"capabilities.\nYou can adjust the "
|
|
||||||
"machine_max_junction_deviation value in your printer's configuration to get higher limits.");
|
|
||||||
warning->opt_key = warning_key;
|
warning->opt_key = warning_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3724,6 +3724,28 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloat(0));
|
def->set_default_value(new ConfigOptionFloat(0));
|
||||||
|
|
||||||
|
// ORCA: minimum non-zero part cooling fan speed.
|
||||||
|
def = this->add("part_cooling_fan_min_pwm", coInt);
|
||||||
|
def->label = L("Minimum non-zero part cooling fan speed");
|
||||||
|
def->tooltip = L("Some part-cooling fans cannot start spinning when commanded below a certain PWM duty cycle. "
|
||||||
|
"When set above 0, any non-zero part-cooling fan command will be raised to at least this percentage "
|
||||||
|
"so the fan reliably starts. A fan command of 0 (fan off) is always honoured exactly. "
|
||||||
|
"This clamp is applied after every other fan calculation (first-layer ramp, layer-time interpolation, "
|
||||||
|
"overhang/bridge/support-interface/ironing overrides), so scaling still operates within the range "
|
||||||
|
"[this value, 100%]."
|
||||||
|
"\nIf your firmware already disables the fan below a threshold (for example Klipper's "
|
||||||
|
"[fan] off_below: 0.10 shuts the fan off whenever the commanded duty cycle is below 10%), "
|
||||||
|
"this option and the firmware threshold should ideally be set to the same value. Matching them "
|
||||||
|
"(e.g. off_below: 0.10 in Klipper and 10% here) guarantees the slicer never emits a non-zero "
|
||||||
|
"value that the firmware would silently drop, and the fan never receives a value below the one "
|
||||||
|
"you know it can actually spool at."
|
||||||
|
"\nSet to 0 to deactivate.");
|
||||||
|
def->sidetext = L("%");
|
||||||
|
def->min = 0;
|
||||||
|
def->max = 100;
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionInt(0));
|
||||||
|
|
||||||
|
|
||||||
def = this->add("time_cost", coFloat);
|
def = this->add("time_cost", coFloat);
|
||||||
def->label = L("Time cost");
|
def->label = L("Time cost");
|
||||||
|
|||||||
@@ -1309,6 +1309,10 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionFloat, fan_kickstart))
|
((ConfigOptionFloat, fan_kickstart))
|
||||||
((ConfigOptionBool, fan_speedup_overhangs))
|
((ConfigOptionBool, fan_speedup_overhangs))
|
||||||
((ConfigOptionFloat, fan_speedup_time))
|
((ConfigOptionFloat, fan_speedup_time))
|
||||||
|
// ORCA: minimum PWM (as a percent 0-100) emitted when the part-cooling fan is asked for a non-zero speed.
|
||||||
|
// Used to overcome the PWM start-up threshold on fans that cannot spool below a certain duty cycle.
|
||||||
|
// A value of 0 (the default) leaves behaviour unchanged. A fan command of 0 (off) is always honoured.
|
||||||
|
((ConfigOptionInt, part_cooling_fan_min_pwm))
|
||||||
((ConfigOptionFloats, filament_diameter))
|
((ConfigOptionFloats, filament_diameter))
|
||||||
((ConfigOptionBoolsNullable, filament_adaptive_volumetric_speed))
|
((ConfigOptionBoolsNullable, filament_adaptive_volumetric_speed))
|
||||||
((ConfigOptionStrings, volumetric_speed_coefficients))
|
((ConfigOptionStrings, volumetric_speed_coefficients))
|
||||||
|
|||||||
@@ -687,6 +687,8 @@ if (APPLE)
|
|||||||
GUI/Mouse3DHandlerMac.mm
|
GUI/Mouse3DHandlerMac.mm
|
||||||
GUI/InstanceCheckMac.mm
|
GUI/InstanceCheckMac.mm
|
||||||
GUI/InstanceCheckMac.h
|
GUI/InstanceCheckMac.h
|
||||||
|
GUI/DeepLinkHandlerMac.mm
|
||||||
|
GUI/DeepLinkHandlerMac.h
|
||||||
GUI/GUI_UtilsMac.mm
|
GUI/GUI_UtilsMac.mm
|
||||||
GUI/wxMediaCtrl2.mm
|
GUI/wxMediaCtrl2.mm
|
||||||
GUI/wxMediaCtrl2.h
|
GUI/wxMediaCtrl2.h
|
||||||
|
|||||||
16
src/slic3r/GUI/DeepLinkHandlerMac.h
Normal file
16
src/slic3r/GUI/DeepLinkHandlerMac.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef slic3r_GUI_DeepLinkHandlerMac_h_
|
||||||
|
#define slic3r_GUI_DeepLinkHandlerMac_h_
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
// Re-registers a Cocoa Apple Event handler for kInternetEventClass/kAEGetURL.
|
||||||
|
// Works around a regression observed after upgrading to wxWidgets 3.3.2 on
|
||||||
|
// macOS Tahoe (#13119) where wxWidgets' built-in handler is registered but
|
||||||
|
// never fires for orcaslicer:// deep links.
|
||||||
|
void register_mac_deep_link_handler();
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif
|
||||||
41
src/slic3r/GUI/DeepLinkHandlerMac.mm
Normal file
41
src/slic3r/GUI/DeepLinkHandlerMac.mm
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#include <boost/log/trivial.hpp>
|
||||||
|
|
||||||
|
#include "DeepLinkHandlerMac.h"
|
||||||
|
#include "GUI_App.hpp"
|
||||||
|
|
||||||
|
@interface OrcaDeepLinkHandler : NSObject
|
||||||
|
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)reply;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation OrcaDeepLinkHandler
|
||||||
|
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)reply
|
||||||
|
{
|
||||||
|
NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||||
|
if (url == nil || url.length == 0)
|
||||||
|
return;
|
||||||
|
BOOST_LOG_TRIVIAL(info) << "Deep link received: " << [url UTF8String];
|
||||||
|
Slic3r::GUI::wxGetApp().MacOpenURL(wxString::FromUTF8([url UTF8String]));
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
void register_mac_deep_link_handler()
|
||||||
|
{
|
||||||
|
static OrcaDeepLinkHandler *handler = nil;
|
||||||
|
if (handler == nil)
|
||||||
|
handler = [[OrcaDeepLinkHandler alloc] init];
|
||||||
|
|
||||||
|
[[NSAppleEventManager sharedAppleEventManager]
|
||||||
|
setEventHandler:handler
|
||||||
|
andSelector:@selector(handleGetURLEvent:withReplyEvent:)
|
||||||
|
forEventClass:kInternetEventClass
|
||||||
|
andEventID:kAEGetURL];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace GUI
|
||||||
|
} // namespace Slic3r
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "Downloader.hpp"
|
#include "Downloader.hpp"
|
||||||
#include <boost/chrono/duration.hpp>
|
#include <boost/chrono/duration.hpp>
|
||||||
#include <boost/log/detail/native_typeof.hpp>
|
#include <boost/log/detail/native_typeof.hpp>
|
||||||
#include <libslic3r/Config.hpp>
|
|
||||||
#include <wx/event.h>
|
#include <wx/event.h>
|
||||||
|
|
||||||
// Localization headers: include libslic3r version first so everything in this file
|
// Localization headers: include libslic3r version first so everything in this file
|
||||||
@@ -101,6 +100,9 @@
|
|||||||
#include "Mouse3DController.hpp"
|
#include "Mouse3DController.hpp"
|
||||||
#include "RemovableDriveManager.hpp"
|
#include "RemovableDriveManager.hpp"
|
||||||
#include "InstanceCheck.hpp"
|
#include "InstanceCheck.hpp"
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "DeepLinkHandlerMac.h"
|
||||||
|
#endif
|
||||||
#include "NotificationManager.hpp"
|
#include "NotificationManager.hpp"
|
||||||
#include "UnsavedChangesDialog.hpp"
|
#include "UnsavedChangesDialog.hpp"
|
||||||
#include "SavePresetDialog.hpp"
|
#include "SavePresetDialog.hpp"
|
||||||
@@ -784,9 +786,20 @@ void GUI_App::post_init()
|
|||||||
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
|
mainframe->select_tab(size_t(MainFrame::tp3DEditor));
|
||||||
plater_->select_view_3D("3D");
|
plater_->select_view_3D("3D");
|
||||||
//BBS init the opengl resource here
|
//BBS init the opengl resource here
|
||||||
//#ifdef __linux__
|
if (!plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen() ||
|
||||||
if (plater_->canvas3D()->get_wxglcanvas()->IsShownOnScreen()&&plater_->canvas3D()->make_current_for_postinit()) {
|
!plater_->canvas3D()->make_current_for_postinit()) {
|
||||||
//#endif
|
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": glcontext not ready, postpone init";
|
||||||
|
plater_->canvas3D()->enable_render(true);
|
||||||
|
plater_->canvas3D()->set_as_dirty();
|
||||||
|
#ifdef __linux__
|
||||||
|
// Wayland/EGL may not have committed the GL surface yet; ask the
|
||||||
|
// idle loop to retry post_init when the canvas is actually mapped.
|
||||||
|
// Without this, GL function pointers stay null and the first
|
||||||
|
// Preview focus crashes in Camera::apply_viewport.
|
||||||
|
m_post_initialized = false;
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
Size canvas_size = plater_->canvas3D()->get_canvas_size();
|
Size canvas_size = plater_->canvas3D()->get_canvas_size();
|
||||||
wxGetApp().imgui()->set_display_size(static_cast<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
|
wxGetApp().imgui()->set_display_size(static_cast<float>(canvas_size.get_width()), static_cast<float>(canvas_size.get_height()));
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", start to init opengl";
|
||||||
@@ -806,14 +819,7 @@ void GUI_App::post_init()
|
|||||||
plater_->canvas3D()->render(false);
|
plater_->canvas3D()->render(false);
|
||||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished rendering a first frame for test";
|
||||||
}
|
}
|
||||||
//#ifdef __linux__
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "Found glcontext not ready, postpone the init";
|
|
||||||
plater_->canvas3D()->enable_render(true);
|
|
||||||
plater_->canvas3D()->set_as_dirty();
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
if (is_editor())
|
if (is_editor())
|
||||||
mainframe->select_tab(size_t(0));
|
mainframe->select_tab(size_t(0));
|
||||||
if (app_config->get("default_page") == "1")
|
if (app_config->get("default_page") == "1")
|
||||||
@@ -2548,6 +2554,12 @@ std::string get_system_info()
|
|||||||
bool GUI_App::on_init_inner()
|
bool GUI_App::on_init_inner()
|
||||||
{
|
{
|
||||||
wxLog::SetActiveTarget(new wxBoostLog());
|
wxLog::SetActiveTarget(new wxBoostLog());
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// Override wxWidgets' kAEGetURL handler so orcaslicer:// deep links keep
|
||||||
|
// working after the wxWidgets 3.3.2 upgrade on macOS (#13119).
|
||||||
|
register_mac_deep_link_handler();
|
||||||
|
#endif
|
||||||
#if BBL_RELEASE_TO_PUBLIC
|
#if BBL_RELEASE_TO_PUBLIC
|
||||||
wxLog::SetLogLevel(wxLOG_Message);
|
wxLog::SetLogLevel(wxLOG_Message);
|
||||||
#endif
|
#endif
|
||||||
@@ -4836,12 +4848,12 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
|
|||||||
BOOST_LOG_TRIVIAL(warning) << "logout: http error 401.";
|
BOOST_LOG_TRIVIAL(warning) << "logout: http error 401.";
|
||||||
this->request_user_logout(provider);
|
this->request_user_logout(provider);
|
||||||
|
|
||||||
if (!m_show_http_error_msgdlg) {
|
if (!m_show_http_errpr_msgdlg) {
|
||||||
MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK);
|
MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK);
|
||||||
m_show_http_error_msgdlg = true;
|
m_show_http_errpr_msgdlg = true;
|
||||||
auto modal_result = msg_dlg.ShowModal();
|
auto modal_result = msg_dlg.ShowModal();
|
||||||
if (modal_result == wxOK || modal_result == wxCLOSE) {
|
if (modal_result == wxOK || modal_result == wxCLOSE) {
|
||||||
m_show_http_error_msgdlg = false;
|
m_show_http_errpr_msgdlg = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4849,40 +4861,6 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No need to show dialog for 410: 410 means resource has been deleted from the server.
|
|
||||||
if (status == 410) {
|
|
||||||
BOOST_LOG_TRIVIAL(info) << "Http error 410.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool m_is_error_shown = false;
|
|
||||||
// Show general error notification for Orca Cloud API failures (not Bambu)
|
|
||||||
if (provider == ORCA_CLOUD_PROVIDER && status >= 400 && code != HttpErrorVersionLimited) {
|
|
||||||
wxString msg;
|
|
||||||
if (!error.empty()) {
|
|
||||||
msg = wxString::Format(_L("API error (HTTP %u): %s"), status, wxString::FromUTF8(error));
|
|
||||||
} else {
|
|
||||||
msg = wxString::Format(_L("API error (HTTP %u)"), status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (app_config->get_bool("developer_mode")) {
|
|
||||||
// Use notification manager if ImGui is ready; fall back to wxMessageBox on Linux
|
|
||||||
// where ImGui may not be initialized until the user switches to the Prepare tab.
|
|
||||||
if (wxGetApp().plater() != nullptr && wxGetApp().imgui()->display_initialized()) {
|
|
||||||
wxGetApp()
|
|
||||||
.plater()
|
|
||||||
->get_notification_manager()
|
|
||||||
->push_notification(NotificationType::PlaterError, NotificationManager::NotificationLevel::WarningNotificationLevel,
|
|
||||||
msg.ToUTF8().data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_is_error_shown) {
|
|
||||||
m_is_error_shown = true;
|
|
||||||
wxMessageBox(msg, _L("Orca Cloud API Error"), wxOK | wxICON_ERROR, wxGetApp().mainframe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI_App::enable_user_preset_folder(bool enable)
|
void GUI_App::enable_user_preset_folder(bool enable)
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ private:
|
|||||||
bool m_is_dark_mode{ false };
|
bool m_is_dark_mode{ false };
|
||||||
bool m_adding_script_handler { false };
|
bool m_adding_script_handler { false };
|
||||||
bool m_side_popup_status{false};
|
bool m_side_popup_status{false};
|
||||||
bool m_show_http_error_msgdlg{false};
|
bool m_show_http_errpr_msgdlg{false};
|
||||||
bool m_show_error_msgdlg{false};
|
bool m_show_error_msgdlg{false};
|
||||||
wxString m_info_dialog_content;
|
wxString m_info_dialog_content;
|
||||||
HttpServer m_http_server;
|
HttpServer m_http_server;
|
||||||
|
|||||||
@@ -561,14 +561,23 @@ wxString GridCellSupportEditor::ms_stringValues[2] = { wxT(""), wxT("") };
|
|||||||
|
|
||||||
void GridCellSupportEditor::DoActivate(int row, int col, wxGrid* grid)
|
void GridCellSupportEditor::DoActivate(int row, int col, wxGrid* grid)
|
||||||
{
|
{
|
||||||
ObjectGrid* local_table = dynamic_cast<ObjectGrid*>(grid);
|
|
||||||
wxGridBlocks cell_array = grid->GetSelectedBlocks();
|
wxGridBlocks cell_array = grid->GetSelectedBlocks();
|
||||||
|
auto iter = cell_array.begin();
|
||||||
auto left_col = cell_array.begin()->GetLeftCol();
|
|
||||||
auto right_col = cell_array.begin()->GetRightCol();
|
int left_col, right_col, top_row, bottom_row;
|
||||||
auto top_row = cell_array.begin()->GetTopRow();
|
if (iter == cell_array.end()) {
|
||||||
auto bottom_row = cell_array.begin()->GetBottomRow();
|
// wxWidgets 3.3.x returns an empty range when nothing is selected;
|
||||||
|
// fall back to the cell that triggered activation so the single-cell
|
||||||
|
// branch below handles it.
|
||||||
|
left_col = right_col = col;
|
||||||
|
top_row = bottom_row = row;
|
||||||
|
} else {
|
||||||
|
left_col = iter->GetLeftCol();
|
||||||
|
right_col = iter->GetRightCol();
|
||||||
|
top_row = iter->GetTopRow();
|
||||||
|
bottom_row = iter->GetBottomRow();
|
||||||
|
}
|
||||||
|
|
||||||
if ((left_col == right_col) &&
|
if ((left_col == right_col) &&
|
||||||
(top_row == bottom_row)) {
|
(top_row == bottom_row)) {
|
||||||
wxGridCellBoolEditor::DoActivate(row, col, grid);
|
wxGridCellBoolEditor::DoActivate(row, col, grid);
|
||||||
|
|||||||
@@ -373,13 +373,12 @@ public:
|
|||||||
//BBS
|
//BBS
|
||||||
static int TOOLBAR_WINDOW_FLAGS;
|
static int TOOLBAR_WINDOW_FLAGS;
|
||||||
|
|
||||||
bool display_initialized() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init_font(bool compress);
|
void init_font(bool compress);
|
||||||
void init_input();
|
void init_input();
|
||||||
void init_style();
|
void init_style();
|
||||||
void render_draw_data(ImDrawData *draw_data);
|
void render_draw_data(ImDrawData *draw_data);
|
||||||
|
bool display_initialized() const;
|
||||||
void destroy_font();
|
void destroy_font();
|
||||||
std::vector<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight);
|
std::vector<unsigned char> load_svg(const std::string& bitmap_name, unsigned target_width, unsigned target_height, unsigned *outwidth, unsigned *outheight);
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,81 @@
|
|||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
// Workaround for #7210: WebKitGTK crashes on vue-resize's hidden <object> probe used by
|
||||||
|
// older Fluidd/Mainsail pages. Swap that <object> for a <div> shim at appendChild time
|
||||||
|
// and bridge resize events through a fake contentDocument.defaultView so vue-resize keeps
|
||||||
|
// working. Workaround proposed by @VittC.
|
||||||
|
static void inject_vue_resize_workaround(wxWebView *webView)
|
||||||
|
{
|
||||||
|
webView->AddUserScript(
|
||||||
|
"(function() {"
|
||||||
|
" 'use strict';"
|
||||||
|
" function isVueResizeObject(el) {"
|
||||||
|
" return el && el.tagName === 'OBJECT'"
|
||||||
|
" && el.type === 'text/html'"
|
||||||
|
" && el.getAttribute('aria-hidden') === 'true'"
|
||||||
|
" && el.getAttribute('tabindex') === '-1';"
|
||||||
|
" }"
|
||||||
|
" function isResizeObserverParent(p) {"
|
||||||
|
" return p && p.classList && p.classList.contains('resize-observer');"
|
||||||
|
" }"
|
||||||
|
" function makeShim(orig, parentForRO) {"
|
||||||
|
" var shim = document.createElement('div');"
|
||||||
|
" shim.setAttribute('aria-hidden', 'true');"
|
||||||
|
" shim.setAttribute('tabindex', '-1');"
|
||||||
|
" shim.style.display = 'none';"
|
||||||
|
" var fakeWin = document.createElement('div');"
|
||||||
|
" var ro = null;"
|
||||||
|
" var origRemoveEL = fakeWin.removeEventListener.bind(fakeWin);"
|
||||||
|
" fakeWin.removeEventListener = function(type, fn, opts) {"
|
||||||
|
" origRemoveEL(type, fn, opts);"
|
||||||
|
" if (type === 'resize' && ro) { ro.disconnect(); ro = null; }"
|
||||||
|
" };"
|
||||||
|
" Object.defineProperty(shim, 'contentDocument', {"
|
||||||
|
" configurable: true,"
|
||||||
|
" get: function() { return { defaultView: fakeWin }; }"
|
||||||
|
" });"
|
||||||
|
" Object.defineProperty(shim, 'contentWindow', {"
|
||||||
|
" configurable: true,"
|
||||||
|
" get: function() { return fakeWin; }"
|
||||||
|
" });"
|
||||||
|
" if (typeof orig.onload === 'function') { shim.onload = orig.onload; }"
|
||||||
|
" queueMicrotask(function() {"
|
||||||
|
" if (parentForRO && typeof ResizeObserver !== 'undefined') {"
|
||||||
|
" ro = new ResizeObserver(function() {"
|
||||||
|
" fakeWin.dispatchEvent(new Event('resize'));"
|
||||||
|
" });"
|
||||||
|
" ro.observe(parentForRO);"
|
||||||
|
" }"
|
||||||
|
" if (typeof shim.onload === 'function') {"
|
||||||
|
" try { shim.onload(new Event('load')); } catch (e) {}"
|
||||||
|
" }"
|
||||||
|
" shim.dispatchEvent(new Event('load'));"
|
||||||
|
" });"
|
||||||
|
" return shim;"
|
||||||
|
" }"
|
||||||
|
" var origAppend = Node.prototype.appendChild;"
|
||||||
|
" Node.prototype.appendChild = function(child) {"
|
||||||
|
" if (isResizeObserverParent(this) && isVueResizeObject(child)) {"
|
||||||
|
" return origAppend.call(this, makeShim(child, this));"
|
||||||
|
" }"
|
||||||
|
" return origAppend.call(this, child);"
|
||||||
|
" };"
|
||||||
|
" var origInsertBefore = Node.prototype.insertBefore;"
|
||||||
|
" Node.prototype.insertBefore = function(child, ref) {"
|
||||||
|
" if (isResizeObserverParent(this) && isVueResizeObject(child)) {"
|
||||||
|
" return origInsertBefore.call(this, makeShim(child, this), ref);"
|
||||||
|
" }"
|
||||||
|
" return origInsertBefore.call(this, child, ref);"
|
||||||
|
" };"
|
||||||
|
" console.log('[vr-fix] vue-resize WebKitGTK patch active');"
|
||||||
|
"})();",
|
||||||
|
wxWEBVIEW_INJECT_AT_DOCUMENT_START
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
PrinterWebView::PrinterWebView(wxWindow *parent)
|
PrinterWebView::PrinterWebView(wxWindow *parent)
|
||||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
|
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
|
||||||
, m_browser(nullptr)
|
, m_browser(nullptr)
|
||||||
@@ -43,6 +118,8 @@ PrinterWebView::PrinterWebView(wxWindow *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
inject_vue_resize_workaround(m_browser);
|
||||||
|
|
||||||
auto cookiesPath = boost::filesystem::path(data_dir() + "/cache/cookies.db");
|
auto cookiesPath = boost::filesystem::path(data_dir() + "/cache/cookies.db");
|
||||||
auto wv = static_cast<WebKitWebView*>(m_browser->GetNativeBackend());
|
auto wv = static_cast<WebKitWebView*>(m_browser->GetNativeBackend());
|
||||||
auto wv_ctx = webkit_web_view_get_context(wv);
|
auto wv_ctx = webkit_web_view_get_context(wv);
|
||||||
@@ -165,6 +242,10 @@ void PrinterWebView::SendAPIKey()
|
|||||||
)",
|
)",
|
||||||
m_apikey);
|
m_apikey);
|
||||||
m_browser->RemoveAllUserScripts();
|
m_browser->RemoveAllUserScripts();
|
||||||
|
#ifdef __linux__
|
||||||
|
// Re-inject the vue-resize/WebKitGTK workaround that RemoveAllUserScripts just cleared.
|
||||||
|
inject_vue_resize_workaround(m_browser);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_browser->AddUserScript(script);
|
m_browser->AddUserScript(script);
|
||||||
m_browser->Reload();
|
m_browser->Reload();
|
||||||
|
|||||||
@@ -4500,6 +4500,8 @@ void TabPrinter::build_fff()
|
|||||||
line.append_option(optgroup->get_option("fan_speedup_overhangs"));
|
line.append_option(optgroup->get_option("fan_speedup_overhangs"));
|
||||||
optgroup->append_line(line);
|
optgroup->append_line(line);
|
||||||
optgroup->append_single_option_line("fan_kickstart", "printer_basic_information_cooling_fan#fan-kick-start-time");
|
optgroup->append_single_option_line("fan_kickstart", "printer_basic_information_cooling_fan#fan-kick-start-time");
|
||||||
|
// ORCA: PWM floor for fans that won't spool at low duty cycles.
|
||||||
|
optgroup->append_single_option_line("part_cooling_fan_min_pwm", "printer_basic_information_cooling_fan#minimum-non-zero-part-cooling-fan-speed");
|
||||||
|
|
||||||
optgroup = page->new_optgroup(L("Extruder Clearance"), "param_extruder_clearance");
|
optgroup = page->new_optgroup(L("Extruder Clearance"), "param_extruder_clearance");
|
||||||
optgroup->append_single_option_line("extruder_clearance_radius", "printer_basic_information_extruder_clearance#radius");
|
optgroup->append_single_option_line("extruder_clearance_radius", "printer_basic_information_extruder_clearance#radius");
|
||||||
|
|||||||
Reference in New Issue
Block a user