Merge branch 'master' into SoftFever

# Conflicts:
#	resources/i18n/zh_cn/BambuStudio.mo
#	version.inc
This commit is contained in:
SoftFever 2022-11-08 11:22:03 +08:00
commit 69e9a7454e
28 changed files with 375 additions and 274 deletions

View file

@ -13,6 +13,7 @@
#include <cassert>
#include <limits>
#include <algorithm>
#include <libslic3r.h>
@ -20,45 +21,35 @@ namespace Slic3r {
const static bool g_wipe_into_objects = false;
void dfs_get_all_sorted_extruders(const std::vector<std::vector<float>> & wipe_volumes,
const std::vector<unsigned int> & all_extruders,
std::vector<unsigned int> & sorted_extruders,
float flush_volume,
std::map<float, std::vector<unsigned int>> &volumes_to_extruder_order)
{
if (sorted_extruders.size() == all_extruders.size()) {
volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders));
return;
}
for (auto extruder_id : all_extruders) {
if (sorted_extruders.empty()) {
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
sorted_extruders.pop_back();
} else {
auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id);
if (itor == sorted_extruders.end()) {
float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id];
flush_volume += delta_flush_volume;
sorted_extruders.push_back(extruder_id);
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order);
flush_volume -= delta_flush_volume;
sorted_extruders.pop_back();
}
}
}
}
std::vector<unsigned int> get_extruders_order(const std::vector<std::vector<float>> &wipe_volumes, std::vector<unsigned int> all_extruders, unsigned int start_extruder_id)
{
if (all_extruders.size() > 1) {
std::vector<unsigned int> sorted_extruders;
auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id);
if (iter != all_extruders.end()) { sorted_extruders.push_back(start_extruder_id); }
std::map<float, std::vector<unsigned int>> volumes_to_extruder_order;
dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order);
if (volumes_to_extruder_order.size() > 0) return volumes_to_extruder_order.begin()->second;
int begin_index = 0;
auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id);
if (iter != all_extruders.end()) {
for (int i = 0; i < all_extruders.size(); ++i) {
if (all_extruders[i] == start_extruder_id) {
std::swap(all_extruders[i], all_extruders[0]);
}
}
begin_index = 1;
}
std::pair<float, std::vector<unsigned int>> volumes_to_extruder_order;
volumes_to_extruder_order.first = 10000 * all_extruders.size();
std::sort(all_extruders.begin() + begin_index, all_extruders.end());
do {
float flush_volume = 0;
for (int i = 0; i < all_extruders.size() - 1; ++i) {
flush_volume += wipe_volumes[all_extruders[i]][all_extruders[i + 1]];
}
if (flush_volume < volumes_to_extruder_order.first) {
volumes_to_extruder_order = std::pair(flush_volume, all_extruders);
}
} while (std::next_permutation(all_extruders.begin() + begin_index, all_extruders.end()));
if (volumes_to_extruder_order.second.size() > 0)
return volumes_to_extruder_order.second;
}
return all_extruders;
}
@ -737,7 +728,10 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume()
for (LayerTools& lt : m_layer_tools) {
if (lt.extruders.empty())
continue;
lt.extruders = get_extruders_order(wipe_volumes, lt.extruders, current_extruder_id);
// todo: The algorithm complexity is too high(o(n2)), currently only 8 colors are supported
if (lt.extruders.size() <= 8) {
lt.extruders = get_extruders_order(wipe_volumes, lt.extruders, current_extruder_id);
}
current_extruder_id = lt.extruders.back();
}
}

View file

@ -248,7 +248,7 @@ PresetsConfigSubstitutions PresetBundle::load_presets(AppConfig &config, Forward
dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/" + config.get("preset_folder");
}
else {
dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/default";
dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/" + DEFAULT_USER_FOLDER_NAME;
}
fs::path user_folder(data_dir() + "/" + PRESET_USER_DIR);
if (!fs::exists(user_folder))
@ -698,8 +698,11 @@ PresetsConfigSubstitutions PresetBundle::import_presets(std::vector<std::string>
//BBS save user preset to user_id preset folder
void PresetBundle::save_user_presets(AppConfig& config, std::vector<std::string>& need_to_delete_list)
{
std::string user_sub_folder = DEFAULT_USER_FOLDER_NAME;
if (!config.get("preset_folder").empty())
user_sub_folder = config.get("preset_folder");
//BBS: change directory by design
const std::string dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/"+ config.get("preset_folder");
const std::string dir_user_presets = data_dir() + "/" + PRESET_USER_DIR + "/"+ user_sub_folder;
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << boost::format(" enter, save to %1%")%dir_user_presets;

View file

@ -9,6 +9,8 @@
#include <unordered_map>
#include <boost/filesystem/path.hpp>
#define DEFAULT_USER_FOLDER_NAME "default"
namespace Slic3r {
// Bundle of Print + Filament + Printer presets.

View file

@ -1513,7 +1513,7 @@ static inline Polygons detect_overhangs(
const coordf_t max_bridge_length = scale_(object_config.max_bridge_length.value);
const bool bridge_no_support = object_config.bridge_no_support.value;
if (layer_id == 0)
if (layer_id == 0)
{
// Don't fill in the holes. The user may apply a higher raft_expansion if one wants a better 1st layer adhesion.
overhang_polygons = to_polygons(layer.lslices);

View file

@ -708,7 +708,7 @@ void TreeSupport::detect_object_overhangs()
if (m_object->tree_support_layer_count() >= m_object->layer_count())
return;
// Clear and create Tree Support Layers
// Create Tree Support Layers
m_object->clear_tree_support_layers();
m_object->clear_tree_support_preview_cache();
@ -721,11 +721,11 @@ void TreeSupport::detect_object_overhangs()
const coordf_t extrusion_width = config.line_width.value;
const coordf_t extrusion_width_scaled = scale_(extrusion_width);
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
const bool bridge_no_support = max_bridge_length > 0;
const bool bridge_no_support = max_bridge_length > 0;// config.bridge_no_support.value;
const bool support_critical_regions_only = config.support_critical_regions_only.value;
const int enforce_support_layers = config.enforce_support_layers.value;
const double area_thresh_well_supported = SQ(scale_(6));
const double length_thresh_well_supported = scale_(6);
const double area_thresh_well_supported = SQ(scale_(6)); // min: 6x6=36mm^2
const double length_thresh_well_supported = scale_(6); // min: 6mm
static const double sharp_tail_max_support_height = 8.f;
// a region is considered well supported if the number of layers below it exceeds this threshold
const int thresh_layers_below = 10 / config.layer_height;
@ -822,19 +822,20 @@ void TreeSupport::detect_object_overhangs()
region2clusterInd.emplace(&region, regionClusters.size() - 1);
}
};
// main part of sharptail detections
has_sharp_tail = false;
if (std::set<SupportType>{stTreeAuto, stHybridAuto, stTree}.count(stype))// == stTreeAuto || stype == stHybridAuto || stype == stTree)
{
double threshold_rad = (config.support_threshold_angle.value < EPSILON ? 30 : config.support_threshold_angle.value+1) * M_PI / 180.;
ExPolygons regions_well_supported;
std::map<ExPolygon, int, ExPolygonComp> region_layers_below;
ExPolygons lower_overhang_dilated;
for (size_t layer_nr = 0; layer_nr < m_object->layer_count(); layer_nr++){
ExPolygons regions_well_supported; // regions on buildplate or well supported
std::map<ExPolygon, int, ExPolygonComp> region_layers_below; // regions and the number of layers below
ExPolygons lower_overhang_dilated; // for small overhang
for (size_t layer_nr = 0; layer_nr < m_object->layer_count(); layer_nr++)
{
if (m_object->print()->canceled())
break;
if (!is_auto && layer_nr > enforce_support_layers)
continue;
@ -872,7 +873,7 @@ void TreeSupport::detect_object_overhangs()
// normal overhang
ExPolygons lower_layer_offseted = offset_ex(lower_polys, support_offset_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS);
ExPolygons overhang_areas = std::move(diff_ex(curr_polys, lower_layer_offseted));
// overhang_areas = std::move(offset2_ex(overhang_areas, -0.1 * extrusion_width_scaled, 0.1 * extrusion_width_scaled));
overhang_areas.erase(std::remove_if(overhang_areas.begin(), overhang_areas.end(),
[extrusion_width_scaled](ExPolygon &area) { return offset_ex(area, -0.1 * extrusion_width_scaled).empty(); }),
overhang_areas.end());
@ -960,7 +961,7 @@ void TreeSupport::detect_object_overhangs()
// 2.4 if the area grows fast than threshold, it get connected to other part or
// it has a sharp slop and will be auto supported.
ExPolygons new_overhang_expolys = diff_ex({expoly}, lower_layer_sharptails);
ExPolygons new_overhang_expolys = diff_ex({ expoly }, lower_layer_sharptails);
if (!offset_ex(new_overhang_expolys, -5.0 * extrusion_width_scaled).empty()) {
is_sharp_tail = false;
break;
@ -1132,6 +1133,7 @@ void TreeSupport::detect_object_overhangs()
// if (erode1.empty() && !inter_with_others.empty())
// blockers[layer_nr].push_back(p_overhang->contour);
}
}
}
@ -1154,13 +1156,12 @@ void TreeSupport::detect_object_overhangs()
for (auto &area : ts_layer->overhang_areas) {
ts_layer->overhang_types.emplace(&area, TreeSupportLayer::Detected);
}
// enforcers
if (layer_nr < enforcers.size()) {
Polygons& enforcer = enforcers[layer_nr];
// coconut: enforcer can't do offset2_ex, otherwise faces with angle near 90 degrees can't have enforcers, which
// is not good. For example: tails of animals needs extra support except the lowest tip.
//enforcer = std::move(offset2_ex(enforcer, -0.1 * extrusion_width_scaled, 0.1 * extrusion_width_scaled));
enforcer = offset(enforcer, 0.1 * extrusion_width_scaled);
for (const Polygon& poly : enforcer) {
ts_layer->overhang_areas.emplace_back(poly);
ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), TreeSupportLayer::Enforced);
@ -1870,30 +1871,30 @@ void TreeSupport::generate_support_areas()
if (!tree_support_enable)
return;
std::vector<std::vector<Node*>> contact_nodes(m_object->layers().size());
std::vector<std::vector<Node*>> contact_nodes(m_object->layers().size()); //Generate empty layers to store the points in.
profiler.stage_start(STAGE_total);
// Generate overhang areas
profiler.stage_start(STAGE_DETECT_OVERHANGS);
m_object->print()->set_status(55, _L("Support: detect overhangs"));
detect_object_overhangs(); // Entry of step#1;
detect_object_overhangs();
profiler.stage_finish(STAGE_DETECT_OVERHANGS);
// Generate contact points of tree support
profiler.stage_start(STAGE_GENERATE_CONTACT_NODES);
m_object->print()->set_status(56, _L("Support: generate contact points"));
generate_contact_points(contact_nodes); // Entry of step#2;
generate_contact_points(contact_nodes);
profiler.stage_finish(STAGE_GENERATE_CONTACT_NODES);
//Drop nodes to lower layers.
profiler.stage_start(STAGE_DROP_DOWN_NODES);
m_object->print()->set_status(60, _L("Support: propagate branches"));
drop_nodes(contact_nodes); // Entry of step#3;
drop_nodes(contact_nodes);
profiler.stage_finish(STAGE_DROP_DOWN_NODES);
// Adjust support layer heights
adjust_layer_heights(contact_nodes); // Entry of step#4;
adjust_layer_heights(contact_nodes);
//Generate support areas.
profiler.stage_start(STAGE_DRAW_CIRCLES);

View file

@ -399,7 +399,7 @@ struct SlabLines {
std::vector<IntersectionLines> at_slice;
// Projections of triangle set boundary lines into layer below (for projection from the top)
// or into layer above (for projection from the bottom).
// In both cases the intersection lines are CCW oriented.
// In both cases the intersection liens are CCW oriented.
std::vector<IntersectionLines> between_slices;
};
@ -790,8 +790,7 @@ inline std::pair<SlabLines, SlabLines> slice_slabs_make_lines(
}
slice_facet_with_slabs<true>(vertices, indices, face_idx, neighbors, edge_ids, num_edges, zs, lines_top, lines_mutex_top);
}
// BBS: add vertical faces option
if (bottom && (fo == FaceOrientation::Down || fo == FaceOrientation::Vertical || fo == FaceOrientation::Degenerate)) {
if (bottom && (fo == FaceOrientation::Down || fo == FaceOrientation::Degenerate)) {
Vec3i neighbors = face_neighbors[face_idx];
// Reset neighborship of this triangle in case the other triangle is oriented backwards from this one.
for (int i = 0; i < 3; ++ i)

View file

@ -300,7 +300,7 @@ void MachineObject::set_access_code(std::string code)
bool MachineObject::is_lan_mode_printer()
{
bool result = false;
if (connection_type() == "lan")
if (!dev_connection_type.empty() && dev_connection_type == "lan")
return true;
return result;
}

View file

@ -1156,7 +1156,12 @@ void GUI_App::post_init()
while (files_vec.size() > LOG_FILES_MAX_NUM) {
auto full_path = log_folder / boost::filesystem::path(files_vec[files_vec.size() - 1].second);
BOOST_LOG_TRIVIAL(info) << "delete log file over " << LOG_FILES_MAX_NUM << ", filename: "<< files_vec[files_vec.size() - 1].second;
boost::filesystem::remove(full_path);
try {
boost::filesystem::remove(full_path);
}
catch (const std::exception& ex) {
BOOST_LOG_TRIVIAL(error) << "failed to delete log file: "<< files_vec[files_vec.size() - 1].second << ". Error: " << ex.what();
}
files_vec.pop_back();
}
}
@ -1213,7 +1218,10 @@ void GUI_App::shutdown()
}
if (m_agent) {
//BBS avoid a crash on mac platform
#ifdef __WINDOWS__
m_agent->start_discovery(false, false);
#endif
delete m_agent;
m_agent = nullptr;
}
@ -3094,6 +3102,7 @@ void GUI_App::request_user_logout()
m_agent->user_logout();
m_agent->set_user_selected_machine("");
app_config->set("preset_folder", "");
/* delete old user settings */
m_device_manager->clean_user_info();
GUI::wxGetApp().sidebar().load_ams_list({});
@ -3651,8 +3660,15 @@ void GUI_App::sync_preset(Preset* preset)
preset->setting_id.clear();
result = 0;
}
else
else {
result = m_agent->put_setting(preset->setting_id, preset->name, &values_map, &http_code);
if (http_code >= 400) {
result = 0;
updated_info = "hold";
BOOST_LOG_TRIVIAL(error) << "[sync_preset] put setting_id = " << preset->setting_id << " failed, http_code = " << http_code;
}
}
}
else {
BOOST_LOG_TRIVIAL(trace) << "[sync_preset]update: can not generate differed key-values, we need to skip this preset "<< preset->name;
@ -3761,8 +3777,10 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg)
it = delete_cache_presets.erase(it);
BOOST_LOG_TRIVIAL(trace) << "sync_preset: sync operation: delete success! setting id = " << del_setting_id;
}
else
else {
BOOST_LOG_TRIVIAL(info) << "delete setting = " <<del_setting_id << " failed";
it++;
}
}
}
} else {

View file

@ -9394,7 +9394,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
if ( seq_print && view3d_canvas && view3d_canvas->is_initialized() && view3d_canvas->is_rendering_enabled() ) {
NotificationManager *notify_manager = get_notification_manager();
if (seq_print->value == PrintSequence::ByObject) {
std::string info_text = L("Print By Object: \nSuggest to use auto-arrange to avoid collisions when printing.");
std::string info_text = _u8L("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)

View file

@ -660,32 +660,30 @@ void MachineInfoPanel::upgrade_firmware_internal() {
void MachineInfoPanel::on_upgrade_firmware(wxCommandEvent &event)
{
ConfirmHintDialog* confirm_dlg = new ConfirmHintDialog(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
confirm_dlg->SetHint(_L(
ConfirmHintDialog confirm_dlg(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
confirm_dlg.SetHint(_L(
"Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating."
));
confirm_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
confirm_dlg.Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
if (m_obj){
m_obj->command_upgrade_confirm();
}
});
if(confirm_dlg->ShowModal())
delete confirm_dlg;
confirm_dlg.ShowModal();
}
void MachineInfoPanel::on_consisitency_upgrade_firmware(wxCommandEvent &event)
{
ConfirmHintDialog* confirm_dlg = new ConfirmHintDialog(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
confirm_dlg->SetHint(_L(
ConfirmHintDialog confirm_dlg(this->GetParent(), wxID_ANY, _L("Upgrade firmware"));
confirm_dlg.SetHint(_L(
"Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating."
));
confirm_dlg->Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
confirm_dlg.Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent &e) {
if (m_obj){
m_obj->command_consistency_upgrade_confirm();
}
});
if(confirm_dlg->ShowModal())
delete confirm_dlg;
confirm_dlg.ShowModal();
}
void MachineInfoPanel::on_show_release_note(wxMouseEvent &event)
@ -800,13 +798,16 @@ void UpgradePanel::update(MachineObject *obj)
if (m_obj && m_show_forced_hint) {
if (m_obj->upgrade_force_upgrade) {
m_show_forced_hint = false; //lock hint
ConfirmHintDialog* force_dlg = new ConfirmHintDialog(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"));
force_dlg->SetHint(_L(
ConfirmHintDialog force_dlg(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"), ConfirmHintDialog::CONFIRM_AND_CANCEL, wxDefaultPosition, wxDefaultSize, wxPD_APP_MODAL);
force_dlg.SetHint(_L(
"An important update was detected and needs to be run before printing can continue. Do you want to update now? You can also update later from 'Upgrade firmware'."
));
force_dlg->Bind(EVT_CONFIRM_HINT, &MachineInfoPanel::on_upgrade_firmware, m_push_upgrade_panel);
if (force_dlg->ShowModal())
delete force_dlg;
force_dlg.Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent& e) {
if (m_obj) {
m_obj->command_upgrade_confirm();
}
});
force_dlg.ShowModal();
}
}
@ -818,13 +819,16 @@ void UpgradePanel::update(MachineObject *obj)
if (m_obj && m_show_consistency_hint) {
if (m_obj->upgrade_consistency_request) {
m_show_consistency_hint = false;
ConfirmHintDialog* consistency_dlg = new ConfirmHintDialog(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"));
consistency_dlg->SetHint(_L(
ConfirmHintDialog consistency_dlg(m_scrolledWindow, wxID_ANY, _L("Upgrade firmware"), ConfirmHintDialog::CONFIRM_AND_CANCEL, wxDefaultPosition, wxDefaultSize, wxPD_APP_MODAL);
consistency_dlg.SetHint(_L(
"The firmware version is abnormal. Repairing and updating are required before printing. Do you want to update now? You can also update later on printer or update next time starting the studio."
));
consistency_dlg->Bind(EVT_CONFIRM_HINT, &MachineInfoPanel::on_consisitency_upgrade_firmware, m_push_upgrade_panel);
if (consistency_dlg->ShowModal())
delete consistency_dlg;
consistency_dlg.Bind(EVT_CONFIRM_HINT, [this](wxCommandEvent& e) {
if (m_obj) {
m_obj->command_consistency_upgrade_confirm();
}
});
consistency_dlg.ShowModal();
}
}
@ -914,4 +918,4 @@ bool UpgradePanel::Show(bool show)
}
}
}
}