diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 6bd6e9113e..237bc1713b 100644 --- a/resources/profiles/BBL.json +++ b/resources/profiles/BBL.json @@ -1,7 +1,7 @@ { "name": "Bambulab", "url": "http://www.bambulab.com/Parameters/vendor/BBL.json", - "version": "01.03.00.02", + "version": "01.03.00.13", "force_update": "0", "description": "the initial version of BBL configurations", "machine_model_list": [ diff --git a/resources/profiles/BBL/machine/fdm_bbl_3dp_001_common.json b/resources/profiles/BBL/machine/fdm_bbl_3dp_001_common.json index 4ebec9633d..2ffd970079 100644 --- a/resources/profiles/BBL/machine/fdm_bbl_3dp_001_common.json +++ b/resources/profiles/BBL/machine/fdm_bbl_3dp_001_common.json @@ -111,9 +111,10 @@ "0.08" ], "printable_height": "250", - "extruder_clearance_radius": "32", + "extruder_clearance_radius": "57", + "extruder_clearance_max_radius": "68", "extruder_clearance_height_to_rod": "36", - "extruder_clearance_height_to_lid": "140", + "extruder_clearance_height_to_lid": "90", "nozzle_volume": "118", "nozzle_diameter": [ "0.4" diff --git a/src/libnest2d/include/libnest2d/selections/firstfit.hpp b/src/libnest2d/include/libnest2d/selections/firstfit.hpp index 713768a423..bc2b5a96bb 100644 --- a/src/libnest2d/include/libnest2d/selections/firstfit.hpp +++ b/src/libnest2d/include/libnest2d/selections/firstfit.hpp @@ -84,6 +84,15 @@ public: std::sort(store_.begin(), store_.end(), sortfunc); + // debug: write down intitial order + for (auto it = store_.begin(); it != store_.end(); ++it) { + std::stringstream ss; + ss << "initial order: " << it->get().name << ", p=" << it->get().priority() << ", bed_temp=" << it->get().bed_temp << ", height=" << it->get().height + << ", area=" << it->get().area(); + if (this->unfitindicator_) + this->unfitindicator_(ss.str()); + } + int item_id = 0; auto makeProgress = [this, &item_id](Placer &placer, size_t bin_idx) { packed_bins_[bin_idx] = placer.getItems(); @@ -102,7 +111,7 @@ public: bool was_packed = false; int best_bed_id = -1; int bed_id_firstfit = -1; - double score = LARGE_COST_TO_REJECT, best_score = LARGE_COST_TO_REJECT; + double score = LARGE_COST_TO_REJECT+1, best_score = LARGE_COST_TO_REJECT+1; double score_all_plates = 0, score_all_plates_best = std::numeric_limits::max(); typename Placer::PackResult result, result_best, result_firstfit; size_t j = 0; @@ -130,8 +139,8 @@ public: // item is not fit because we have tried all possible plates to find a good enough fit if (bed_id_firstfit == MAX_NUM_PLATES) { it->get().binId(BIN_ID_UNFIT); - //if (this->unfitindicator_) - // this->unfitindicator_(it->get().name + " bed_id_firstfit == MAX_NUM_PLATES" + ",best_score=" + std::to_string(best_score)); + if (this->unfitindicator_) + this->unfitindicator_(it->get().name + " bed_id_firstfit == MAX_NUM_PLATES" + ",best_score=" + std::to_string(best_score)); break; } else { @@ -152,10 +161,13 @@ public: } if(!was_packed){ - //if (this->unfitindicator_) - // this->unfitindicator_(it->get().name + " ,plate_id=" + std::to_string(j) + ",score=" + std::to_string(score) - // + ", score_all_plates=" + std::to_string(score_all_plates) - // + ", overfit=" + std::to_string(result.overfit())); + if (this->unfitindicator_ && !placers.empty()) + this->unfitindicator_(it->get().name + ", height=" +std::to_string(it->get().height) + + " ,plate_id=" + std::to_string(j-1) + + ", score=" + std::to_string(score) + + ", best_bed_id=" + std::to_string(best_bed_id) + + ", score_all_plates=" + std::to_string(score_all_plates) + +", overfit=" + std::to_string(result.overfit())); placers.emplace_back(bin); placers.back().plateID(placers.size() - 1); diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 0298585704..5214b29d83 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -533,8 +533,10 @@ void AppConfig::save() { // Returns "undefined" if the thread naming functionality is not supported by the operating system. std::optional current_thread_name = get_current_thread_name(); - if (current_thread_name && *current_thread_name != "bambustu_main") - throw CriticalException("Calling AppConfig::save() from a worker thread!"); + if (current_thread_name && *current_thread_name != "bambustu_main") { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__<<", current_thread_name is " << *current_thread_name; + throw CriticalException("Calling AppConfig::save() from a worker thread, thread name: " + *current_thread_name); + } } // The config is first written to a file with a PID suffix and then moved diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp index cc2f1721a3..82dcf0c9a1 100644 --- a/src/libslic3r/Arrange.cpp +++ b/src/libslic3r/Arrange.cpp @@ -404,8 +404,8 @@ protected: hasLidHeightConflict |= (p.height > clearance_height_to_lid); } - double lambda3 = LARGE_COST_TO_REJECT; - double lambda4 = LARGE_COST_TO_REJECT; + double lambda3 = LARGE_COST_TO_REJECT*1.1; + double lambda4 = LARGE_COST_TO_REJECT*1.2; for (int i = 0; i < m_items.size(); i++) { Item& p = m_items[i]; if (p.is_virt_object) continue; @@ -556,12 +556,11 @@ public: } }); - //if (progressind) { - // m_pck.unfitIndicator([this, progressind](std::string name) { - // progressind(100, name+" not fit!"); - // BOOST_LOG_TRIVIAL(debug) << "arrange not fit: " + name; - // }); - //} + if (progressind) { + m_pck.unfitIndicator([this, progressind](std::string name) { + BOOST_LOG_TRIVIAL(debug) << "arrange not fit: " + name; + }); + } if (stopcond) m_pck.stopCondition(stopcond); diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index d9a510a45b..09b3253656 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -52,6 +52,7 @@ struct ArrangePolygon { //BBS: add locked_plate to indicate whether it is in the locked plate int locked_plate{ -1 }; bool is_virt_object{ false }; + bool is_extrusion_cali_object{ false }; bool is_wipe_tower{false}; //BBS: add row/col for sudoku-style layout int row{0}; diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index ace84c064b..0b1d988be3 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -469,7 +469,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: LayerRegion* layerm = this->m_regions[surface_fill.region_id]; params.config = &layerm->region().config(); for (ExPolygon& expoly : surface_fill.expolygons) { - f->no_overlap_expolygons = intersection_ex(layerm->fill_no_overlap_expolygons, ExPolygons() = { expoly }); + f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}); // Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon. f->spacing = surface_fill.params.spacing; surface_fill.surface.expolygon = std::move(expoly); diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 9897205cd0..06931a27c0 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -4058,18 +4058,21 @@ void GCodeProcessor::update_slice_warnings() auto used_extruders = get_used_extruders(); assert(!used_extruders.empty()); + GCodeProcessorResult::SliceWarning warning; + warning.level = 1; if (m_highest_bed_temp != 0) { for (size_t i = 0; i < used_extruders.size(); i++) { int temperature = get_filament_vitrification_temperature(used_extruders[i]); - if (temperature != 0 && m_highest_bed_temp > temperature) { - GCodeProcessorResult::SliceWarning warning; - warning.level = 1; - warning.msg = BED_TEMP_TOO_HIGH_THAN_FILAMENT; - m_result.warnings.emplace_back(std::move(warning)); - } + if (temperature != 0 && m_highest_bed_temp > temperature) + warning.params.push_back(std::to_string(used_extruders[i])); } } + if (!warning.params.empty()) { + warning.msg = BED_TEMP_TOO_HIGH_THAN_FILAMENT; + m_result.warnings.push_back(warning); + } + m_result.warnings.shrink_to_fit(); } diff --git a/src/libslic3r/ModelArrange.cpp b/src/libslic3r/ModelArrange.cpp index 7e280d76b2..a1c43cd39e 100644 --- a/src/libslic3r/ModelArrange.cpp +++ b/src/libslic3r/ModelArrange.cpp @@ -127,11 +127,11 @@ ArrangePolygon get_instance_arrange_poly(ModelInstance* instance, const Slic3r:: const ConfigOptionInts* bed_opt = config.option(get_bed_temp_key(curr_bed_type)); if (bed_opt != nullptr) - ap.bed_temp = bed_opt->get_at(ap.extrude_ids.back()); + ap.bed_temp = bed_opt->get_at(ap.extrude_ids.back()-1); const ConfigOptionInts* bed_opt_1st_layer = config.option(get_bed_temp_1st_layer_key(curr_bed_type)); if (bed_opt_1st_layer != nullptr) - ap.first_bed_temp = bed_opt_1st_layer->get_at(ap.extrude_ids.back()); + ap.first_bed_temp = bed_opt_1st_layer->get_at(ap.extrude_ids.back()-1); } if (config.has("nozzle_temperature")) //get the print temperature diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 555c52020a..242b68e4f0 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -764,7 +764,7 @@ static std::vector s_Preset_printer_options { "printer_technology", "printable_area", "bed_exclude_area", "gcode_flavor","z_lift_type", "single_extruder_multi_material", "machine_start_gcode", "machine_end_gcode", "before_layer_change_gcode", "layer_change_gcode", "change_filament_gcode", - "printer_model", "printer_variant", "printable_height", "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", + "printer_model", "printer_variant", "printable_height", "extruder_clearance_radius", "extruder_clearance_max_radius","extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", "default_print_profile", "inherits", "silent_mode", // BBS diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 6322d9b91b..94187f080c 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -82,6 +82,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "extruder_clearance_height_to_rod", "extruder_clearance_height_to_lid", "extruder_clearance_radius", + "extruder_clearance_max_radius", "extruder_colour", "extruder_offset", "filament_flow_ratio", @@ -398,6 +399,9 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print const PrintInstance *print_instance; BoundingBox bounding_box; Polygon hull_polygon; + int index; + double arrange_score; + double height; }; std::vector print_instance_with_bounding_box; { @@ -475,6 +479,7 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print } } struct print_instance_info print_info {&instance, convex_hull.bounding_box(), convex_hull}; + print_info.height = instance.print_object->height(); print_instance_with_bounding_box.push_back(std::move(print_info)); convex_hulls_other.emplace_back(std::move(convex_hull)); } @@ -489,22 +494,104 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print } } - //sort the print instance + // calc sort order + double hc1 = scale_(print.config().extruder_clearance_height_to_lid); // height to lid + double hc2 = scale_(print.config().extruder_clearance_height_to_rod); // height to rod + double printable_height = scale_(print.config().printable_height); + + auto bed_points = get_bed_shape(print_config); + float bed_width = bed_points[1].x() - bed_points[0].x(); + // 如果扩大以后的多边形的距离小于这个值,就需要严格保证从左到右的打印顺序,否则会撞工具头右侧 + float unsafe_dist = scale_(print_config.extruder_clearance_max_radius.value - print_config.extruder_clearance_radius.value); + struct VecHash + { + size_t operator()(const Vec2i &n1) const + { + return std::hash()(int(n1(0) * 100 + 100)) + std::hash()(int(n1(1) * 100 + 100)) * 101; + } + }; + std::unordered_set left_right_pair; // pairs in this vector must strictly obey the left-right order + for (size_t i = 0; i < print_instance_with_bounding_box.size();i++) { + auto &inst = print_instance_with_bounding_box[i]; + inst.index = i; + Point pt = inst.bounding_box.center(); + inst.arrange_score = pt.x() / 2 + pt.y(); // we prefer print row-by-row, so cost on x-direction is smaller + } + for (size_t i = 0; i < print_instance_with_bounding_box.size(); i++) { + auto &inst = print_instance_with_bounding_box[i]; + auto &l = print_instance_with_bounding_box[i]; + for (size_t j = 0; j < print_instance_with_bounding_box.size(); j++) { + if (j != i) { + auto &r = print_instance_with_bounding_box[j]; + auto ly1 = l.bounding_box.min.y(); + auto ly2 = l.bounding_box.max.y(); + auto ry1 = r.bounding_box.min.y(); + auto ry2 = r.bounding_box.max.y(); + auto lx1 = l.bounding_box.min.x(); + auto rx1 = r.bounding_box.min.x(); + auto lx2 = l.bounding_box.max.x(); + auto rx2 = r.bounding_box.max.x(); + auto inter_min = std::max(ly1, ry1); + auto inter_max = std::min(ly2, ry2); + auto inter_y = inter_max - inter_min; + inter_min = std::max(lx1, rx1); + inter_max = std::min(lx2, rx2); + auto inter_x = inter_max - inter_min; + + // 如果y方向的重合超过轮廓的膨胀量,说明两个物体在一行,应该先打左边的物体,即先比较二者的x坐标。 + if (inter_y > scale_(1)) { + if (std::max(rx1 - lx2, lx1 - rx2) < unsafe_dist) { + if (lx1 > rx1) { + left_right_pair.insert({j, i}); + BOOST_LOG_TRIVIAL(debug) << "in-a-row, print_instance " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")" + << " -> " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")"; + } else { + left_right_pair.insert({i, j}); + BOOST_LOG_TRIVIAL(debug) << "in-a-row, print_instance " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")" + << " -> " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")"; + } + } + } + if (l.height > hc1 && r.height < hc1) { + // 当前物体超过了顶盖高度,必须后打 + left_right_pair.insert({j, i}); + BOOST_LOG_TRIVIAL(debug) << "height>hc1, print_instance " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")" + << " -> " << l.print_instance->model_instance->get_object()->name << "(" << l.arrange_score << ")"; + } + else if (l.height > hc2 && l.height > r.height && l.arrange_scorehc2, print_instance " << inst.print_instance->model_instance->get_object()->name + << ", right=" << r.print_instance->model_instance->get_object()->name << ", l.score: " << l.arrange_score + << ", r.score: " << r.arrange_score; + } + } + } + } + BOOST_LOG_TRIVIAL(debug) << "bed width: " << bed_width << ", unsafe_dist:" << unsafe_dist; + // 多做几次代价传播,因为前一次有些值没有更新。 + // TODO 更好的办法是建立一颗树,一步到位。不过我暂时没精力搞,先就这样吧 + for (int k=0;k<5;k++) + for (auto p : left_right_pair) { + auto &l = print_instance_with_bounding_box[p(0)]; + auto &r = print_instance_with_bounding_box[p(1)]; + if(r.arrange_scoremodel_instance->get_object()->name << "(" << l.arrange_score << ")" + << " -> " << r.print_instance->model_instance->get_object()->name << "(" << r.arrange_score << ")"; + } + // sort the print instance std::sort(print_instance_with_bounding_box.begin(), print_instance_with_bounding_box.end(), - [](auto &l, auto &r) { - auto ly1 = l.bounding_box.min.y(); - auto ly2 = l.bounding_box.max.y(); - auto ry1 = r.bounding_box.min.y(); - auto ry2 = r.bounding_box.max.y(); - auto inter_min = std::max(ly1, ry1); - auto inter_max = std::min(ly2, ry2); - auto lx = l.bounding_box.min.x(); - auto rx = r.bounding_box.min.x(); - if (inter_max - inter_min > 0) - return (lx < rx) || ((lx == rx) && (ly1 < ry1)); - else - return (ly1 < ry1); - }); + [](print_instance_info& l, print_instance_info& r) {return l.arrange_score < r.arrange_score;}); + + for (auto &inst : print_instance_with_bounding_box) + BOOST_LOG_TRIVIAL(debug) << "after sorting print_instance " << inst.print_instance->model_instance->get_object()->name << ", score: " << inst.arrange_score + << ", height:"<< inst.height; // sequential_print_vertical_clearance_valid { @@ -535,9 +622,6 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print break; }*/ - double hc1 = scale_(print.config().extruder_clearance_height_to_lid); - double hc2 = scale_(print.config().extruder_clearance_height_to_rod); - double printable_height = scale_(print.config().printable_height); // if objects are not overlapped on y-axis, they will not collide even if they are taller than extruder_clearance_height_to_rod int print_instance_count = print_instance_with_bounding_box.size(); @@ -545,7 +629,8 @@ StringObjectException Print::sequential_print_clearance_valid(const Print &print for (int k = 0; k < print_instance_count; k++) { auto inst = print_instance_with_bounding_box[k].print_instance; - auto bbox = print_instance_with_bounding_box[k].bounding_box; + // 只需要考虑喷嘴到滑杆的偏移量,这个比整个工具头的碰撞半径要小得多 + auto bbox = print_instance_with_bounding_box[k].bounding_box.inflated(-scale_(0.5 * print.config().extruder_clearance_radius.value)); auto iy1 = bbox.min.y(); auto iy2 = bbox.max.y(); (const_cast(inst->model_instance))->arrange_order = k+1; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index d11a35d547..146a8f8e5d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1025,7 +1025,7 @@ void PrintConfigDef::init_fff_params() def = this->add("extruder_clearance_height_to_rod", coFloat); def->label = L("Height to rod"); def->tooltip = L("Distance of the nozzle tip to the lower rod. " - "Used as input of auto-arranging to avoid collision when printing by object"); + "Used for collision avoidance in by-object printing."); def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; @@ -1035,7 +1035,7 @@ void PrintConfigDef::init_fff_params() def = this->add("extruder_clearance_height_to_lid", coFloat); def->label = L("Height to lid"); def->tooltip = L("Distance of the nozzle tip to the lid. " - "Used as input of auto-arranging to avoid collision when printing by object"); + "Used for collision avoidance in by-object printing."); def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; @@ -1043,12 +1043,20 @@ void PrintConfigDef::init_fff_params() def = this->add("extruder_clearance_radius", coFloat); def->label = L("Radius"); - def->tooltip = L("Clearance radius around extruder. Used as input of auto-arranging to avoid collision when printing by object"); + def->tooltip = L("Clearance radius around extruder. Used for collision avoidance in by-object printing."); def->sidetext = L("mm"); def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(40)); + def = this->add("extruder_clearance_max_radius", coFloat); + def->label = L("Max Radius"); + def->tooltip = L("Max clearance radius around extruder. Used for collision avoidance in by-object printing."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(68)); + def = this->add("extruder_colour", coStrings); def->label = L("Extruder Color"); def->tooltip = L("Only used as a visual help on UI"); diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index f58f5cbd00..c4d6f9eedd 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -841,6 +841,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloat, extruder_clearance_height_to_rod))//BBs ((ConfigOptionFloat, extruder_clearance_height_to_lid))//BBS ((ConfigOptionFloat, extruder_clearance_radius)) + ((ConfigOptionFloat, extruder_clearance_max_radius)) ((ConfigOptionStrings, extruder_colour)) ((ConfigOptionPoints, extruder_offset)) ((ConfigOptionBools, reduce_fan_stop_start_freq)) diff --git a/src/slic3r/GUI/DownloadProgressDialog.cpp b/src/slic3r/GUI/DownloadProgressDialog.cpp index c5f018befd..9c943d1c3a 100644 --- a/src/slic3r/GUI/DownloadProgressDialog.cpp +++ b/src/slic3r/GUI/DownloadProgressDialog.cpp @@ -31,8 +31,8 @@ namespace GUI { DownloadProgressDialog::DownloadProgressDialog(wxString title) : DPIDialog(static_cast(wxGetApp().mainframe), wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) { - wxString download_failed_url = wxT("https://wiki.bambulab.com/e/en/software/bambu-studio/failed-to-get-network-plugin"); - wxString install_failed_url = wxT("https://wiki.bambulab.com/e/en/software/bambu-studio/failed-to-get-network-plugin"); + wxString download_failed_url = wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-get-network-plugin"); + wxString install_failed_url = wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-get-network-plugin"); wxString download_failed_msg = _L("Failed to download the plug-in. Please check your firewall settings and vpn software, check and retry."); wxString install_failed_msg = _L("Failed to install the plug-in. Please check whether it is blocked or deleted by anti-virus software."); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e932b867b0..8f7b29ad65 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -248,7 +248,8 @@ void GLCanvas3D::Labels::render(const std::vector& sorted_ return owner.model_instance_id == id; }); if (it != owners.end()) - it->print_order = std::string((_(L("Sequence"))).ToUTF8()) + "#: " + std::to_string(i + 1); + //it->print_order = std::string((_(L("Sequence"))).ToUTF8()) + "#: " + std::to_string(i + 1); + it->print_order = std::string((_(L("Sequence"))).ToUTF8()) + "#: " + std::to_string(sorted_instances[i]->arrange_order); } } @@ -6032,10 +6033,20 @@ void GLCanvas3D::_render_overlays() bool sequential_print = opt != nullptr && (opt->value == PrintSequence::ByObject); std::vector sorted_instances; if (sequential_print) { - for (ModelObject* model_object : m_model->objects) + const Print* print = fff_print(); + if (print) { + for (const PrintObject *print_object : print->objects()) + { + for (const PrintInstance &instance : print_object->instances()) + { + sorted_instances.emplace_back(instance.model_instance); + } + } + } + /*for (ModelObject* model_object : m_model->objects) for (ModelInstance* model_instance : model_object->instances) { sorted_instances.emplace_back(model_instance); - } + }*/ } m_labels.render(sorted_instances); diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index be52035df8..17a08fada7 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -1333,7 +1333,7 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu) menu->Destroy(item_id); } - const int filaments_cnt = filaments_count(); + int filaments_cnt = filaments_count(); if (filaments_cnt <= 1) return; @@ -1345,6 +1345,10 @@ void MenuFactory::append_menu_item_change_filament(wxMenu* menu) std::vector icons = get_extruder_color_icons(true); if (icons.size() < filaments_cnt) { BOOST_LOG_TRIVIAL(warning) << boost::format("Warning: icons size %1%, filaments_cnt=%2%")%icons.size()%filaments_cnt; + if (icons.size() <= 1) + return; + else + filaments_cnt = icons.size(); } wxMenu* extruder_selection_menu = new wxMenu(); const wxString& name = sels.Count() == 1 ? names[0] : names[1]; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index d8f8f2f891..7e2f8d772f 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -816,7 +816,6 @@ void AssembleView::reload_scene(bool refresh_immediately, bool force_full_scene_ m_canvas->render(true); } m_canvas->reload_scene(refresh_immediately, force_full_scene_refresh); - m_canvas->reload_scene(refresh_immediately, force_full_scene_refresh); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index 2bc950fe34..a8ef43c85b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -611,6 +611,9 @@ void ModelObjectsInfo::on_update() if (!get_pool()->get_canvas()->get_model()->objects.empty()) { m_model_objects = get_pool()->get_canvas()->get_model()->objects; } + else { + m_model_objects.clear(); + } } void ModelObjectsInfo::on_release() diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index ea92b9adf2..df59dff67f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -345,7 +345,7 @@ void GLGizmosManager::update(const Linef3& mouse_ray, const Point& mouse_pos) void GLGizmosManager::update_assemble_view_data() { if (m_assemble_view_data) { - if (m_parent.get_canvas_type() != GLCanvas3D::CanvasAssembleView) + if (!wxGetApp().plater()->get_assmeble_canvas3D()->get_wxglcanvas()->IsShown()) m_assemble_view_data->update(AssembleViewDataID(0)); else m_assemble_view_data->update(AssembleViewDataID((int)AssembleViewDataID::ModelObjectsInfo | (int)AssembleViewDataID::ModelObjectsClipper)); diff --git a/src/slic3r/GUI/Jobs/ArrangeJob.cpp b/src/slic3r/GUI/Jobs/ArrangeJob.cpp index 077ec43809..f8a3874ecc 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob.cpp @@ -503,6 +503,9 @@ void ArrangeJob::process() if (params.is_seq_print) params.min_obj_distance = std::max(params.min_obj_distance, scaled(params.cleareance_radius)); + if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer")) + m_plater->get_partplate_list().preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); + double skirt_distance = print.has_skirt() ? print.config().skirt_distance.value : 0; double brim_max = 0; std::for_each(m_selected.begin(), m_selected.end(), [&](ArrangePolygon ap) { brim_max = std::max(brim_max, ap.brim_width); }); @@ -514,21 +517,26 @@ void ArrangeJob::process() params.bed_shrink_y = settings.bed_shrink_y + params.brim_skirt_distance; // for sequential print, we need to inflate the bed because cleareance_radius is so large if (params.is_seq_print) { - params.bed_shrink_x -= params.cleareance_radius/2; - params.bed_shrink_y -= params.cleareance_radius/2; + float shift_dist = params.cleareance_radius / 2 - 5; + params.bed_shrink_x -= shift_dist; + params.bed_shrink_y -= shift_dist; // dont forget to move the excluded region for (auto& region : m_unselected) { if (region.is_virt_object) - region.poly.translate(-scaled(params.cleareance_radius/2), -scaled(params.cleareance_radius/2)); + region.poly.translate(-scaled(shift_dist), -scaled(shift_dist)); } } // do not inflate brim_width. Objects are allowed to have overlapped brim. std::for_each(m_selected.begin(), m_selected.end(), [&](auto& ap) {ap.inflation = params.min_obj_distance / 2; }); - std::for_each(m_unselected.begin(), m_unselected.end(), [&](auto& ap) {ap.inflation = ap.is_virt_object ? scaled(params.brim_skirt_distance) : params.min_obj_distance / 2; }); + // For occulusion regions, inflation should be larger to prevent genrating brim on them. + // However, extrusion cali regions are exceptional, since we can allow brim overlaps them. + std::for_each(m_unselected.begin(), m_unselected.end(), [&](auto &ap) { + ap.inflation = !ap.is_virt_object ? + params.min_obj_distance / 2 : + (ap.is_extrusion_cali_object ? scaled(params.cleareance_radius / 2) : scaled(params.brim_skirt_distance + params.cleareance_radius / 2)); + }); - if (params.avoid_extrusion_cali_region && print.full_print_config().opt_bool("scan_first_layer")) - m_plater->get_partplate_list().preprocess_nonprefered_areas(m_unselected, MAX_NUM_PLATES); m_plater->get_partplate_list().preprocess_exclude_areas(params.excluded_regions, 1); @@ -567,6 +575,7 @@ void ArrangeJob::process() << ", bed_temp: " << selected.first_bed_temp << ", print_temp: " << selected.print_temp; BOOST_LOG_TRIVIAL(debug) << "items unselected before arrange: "; for (auto item : m_unselected) + if (!item.is_virt_object) BOOST_LOG_TRIVIAL(debug) << item.name << ", extruder: " << item.extrude_ids.back() << ", bed: " << item.bed_idx << ", trans: " << item.translation.transpose(); } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index a3295aa421..1c41948423 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -3461,6 +3461,7 @@ bool PartPlateList::preprocess_nonprefered_areas(arrangement::ArrangePolygons& r ret.translation = Vec2crd(0, 0); ret.rotation = 0.0f; ret.is_virt_object = true; + ret.is_extrusion_cali_object = true; ret.bed_idx = j; ret.height = 1; ret.name = "NonpreferedRegion" + std::to_string(index); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index c673d9b809..035d517a43 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2020,7 +2020,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) //BBS: add bed_exclude_area , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ "printable_area", "bed_exclude_area", "print_sequence", - "extruder_clearance_radius", "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", "skirt_loops", "skirt_distance", + "extruder_clearance_radius", "extruder_clearance_max_radius", + "extruder_clearance_height_to_lid", "extruder_clearance_height_to_rod", "skirt_loops", "skirt_distance", "brim_width", "brim_object_gap", "brim_type", "nozzle_diameter", "single_extruder_multi_material", "enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_volume", "extruder_colour", "filament_colour", "material_colour", "printable_height", "printer_model", "printer_technology", @@ -7224,7 +7225,7 @@ void Plater::add_model(bool imperial_units/* = false*/) if (!load_files(paths, strategy, ask_multi).empty()) { if (get_project_name() == _L("Untitled") && paths.size() > 0) { - p->set_project_filename(wxString(paths[0].string())); + p->set_project_filename(wxString::FromUTF8(paths[0].string())); } wxGetApp().mainframe->update_title(); @@ -9319,6 +9320,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) { bool update_scheduled = false; bool bed_shape_changed = false; + bool print_sequence_changed = false; t_config_option_keys diff_keys = p->config->diff(config); for (auto opt_key : diff_keys) { if (opt_key == "filament_colour") { @@ -9369,6 +9371,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) } else if (opt_key == "print_sequence") { update_scheduled = true; + print_sequence_changed = true; } else if (opt_key == "printer_model") { p->reset_gcode_toolpaths(); @@ -9393,6 +9396,9 @@ void Plater::on_config_change(const DynamicPrintConfig &config) if (seq_print->value == PrintSequence::ByObject) { std::string info_text = L("Print By Object: \nSuggest to use auto-arrange to avoid collisions when printing."); notify_manager->bbl_show_seqprintinfo_notification(info_text); + //always show label when switch to sequence print + if (print_sequence_changed) + this->show_view3D_labels(true); } else notify_manager->bbl_close_seqprintinfo_notification(); diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 28ecd8fd21..8d2667ba09 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -89,6 +89,7 @@ void ReleaseNoteDialog::update_release_note(wxString release_note, std::string v sizer_text_release_note->Add(m_staticText_release_note, 0, wxALL, 5); m_vebview_release_note->SetSizer(sizer_text_release_note); m_vebview_release_note->Layout(); + m_vebview_release_note->Fit(); } void UpdateVersionDialog::alter_choice(wxCommandEvent& event) @@ -333,6 +334,7 @@ void UpdateVersionDialog::update_version_info(wxString release_note, wxString ve 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(); } } diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index bbc1c2726c..4c94d0341b 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -643,7 +643,7 @@ void SelectMachinePopup::update_other_devices() m_placeholder_panel = new wxWindow(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxSize(-1,FromDIP(26))); wxBoxSizer* placeholder_sizer = new wxBoxSizer(wxVERTICAL); - auto m_hyperlink = new wxHyperlinkCtrl(m_placeholder_panel, wxID_ANY, _L("Can't find my devices?"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE); + m_hyperlink = new wxHyperlinkCtrl(m_placeholder_panel, wxID_ANY, _L("Can't find my devices?"), wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE); placeholder_sizer->Add(m_hyperlink, 0, wxALIGN_CENTER | wxALL, 5); @@ -860,6 +860,12 @@ void SelectMachinePopup::OnLeftUp(wxMouseEvent &event) wxPostEvent(p->mPanel, event); } } + + //hyper link + auto h_rect = m_hyperlink->ClientToScreen(wxPoint(0, 0)); + if (mouse_pos.x > h_rect.x && mouse_pos.y > h_rect.y && mouse_pos.x < (h_rect.x + m_hyperlink->GetSize().x) && mouse_pos.y < (h_rect.y + m_hyperlink->GetSize().y)) { + wxLaunchDefaultBrowser(wxT("https://wiki.bambulab.com/en/software/bambu-studio/failed-to-connect-printer")); + } } } diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index fe83a1cc6c..1529ecb8b2 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -198,6 +198,7 @@ private: int m_my_devices_count{0}; int m_other_devices_count{0}; wxWindow* m_placeholder_panel{nullptr}; + wxHyperlinkCtrl* m_hyperlink{nullptr}; wxBoxSizer * m_sizer_body{nullptr}; wxBoxSizer * m_sizer_my_devices{nullptr}; wxBoxSizer * m_sizer_other_devices{nullptr}; diff --git a/version.inc b/version.inc index c5e901839a..3dad0ed7e1 100644 --- a/version.inc +++ b/version.inc @@ -10,5 +10,5 @@ endif() if(NOT DEFINED BBL_INTERNAL_TESTING) set(BBL_INTERNAL_TESTING "1") endif() -set(SLIC3R_VERSION "01.03.00.12") +set(SLIC3R_VERSION "01.03.00.22") set(SoftFever_VERSION "1.3.2")