Merge branch 'main' into feature/zaa-contouring

This commit is contained in:
SoftFever
2026-02-10 13:53:52 +08:00
committed by GitHub
26 changed files with 265 additions and 119 deletions

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

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