Merge branch 'main' into plugin-ui-1

This commit is contained in:
Ian Chua
2026-09-11 11:19:23 +08:00
committed by GitHub
45 changed files with 78 additions and 465 deletions
+6
View File
@@ -558,6 +558,12 @@ if (_opts)
target_compile_options(libslic3r_cgal PRIVATE "${_opts_bad}")
endif()
if (IS_CLANG_CL)
# CGAL passes /fp:strict /fp:except-. clang-cl reports the second as overriding part of
# the first; the settings cc1 receives are the same ones MSVC produces from that pair.
target_compile_options(libslic3r_cgal PRIVATE -Wno-overriding-option)
endif ()
target_link_libraries(libslic3r_cgal PRIVATE ${_cgal_tgt} admesh libigl mcut boost_libs)
if (MSVC AND "${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") # 32 bit MSVC workaround
+5 -5
View File
@@ -968,10 +968,10 @@ EmbossStyles Emboss::get_font_list_by_register() {
}
// TODO: Fix global function
bool CALLBACK EnumFamCallBack(LPLOGFONT lplf,
LPNEWTEXTMETRIC lpntm,
DWORD FontType,
LPVOID aFontList)
int CALLBACK EnumFamCallBack(const LOGFONT *lplf,
const TEXTMETRIC *lpntm,
DWORD FontType,
LPARAM aFontList)
{
std::vector<std::wstring> *fontList =
(std::vector<std::wstring> *) (aFontList);
@@ -988,7 +988,7 @@ EmbossStyles Emboss::get_font_list_by_enumeration() {
HDC hDC = GetDC(NULL);
std::vector<std::wstring> font_names;
EnumFontFamilies(hDC, (LPCTSTR) NULL, (FONTENUMPROC) EnumFamCallBack,
EnumFontFamilies(hDC, (LPCTSTR) NULL, EnumFamCallBack,
(LPARAM) &font_names);
EmbossStyles font_list;
+2 -2
View File
@@ -1395,8 +1395,8 @@ void Filler::_fill_surface_single(
}
#endif /* ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT */
const auto hook_length = coordf_t(std::min<float>(std::numeric_limits<coord_t>::max(), scale_(params.anchor_length)));
const auto hook_length_max = coordf_t(std::min<float>(std::numeric_limits<coord_t>::max(), scale_(params.anchor_length_max)));
const auto hook_length = coordf_t(scale_(params.anchor_length));
const auto hook_length_max = coordf_t(scale_(params.anchor_length_max));
Polylines all_polylines_with_hooks = all_polylines.size() > 1 ? connect_lines_using_hooks(std::move(all_polylines), expolygon, this->spacing, hook_length, hook_length_max) : std::move(all_polylines);
+1 -1
View File
@@ -910,7 +910,7 @@ namespace Slic3r
unsigned int iterations = (1 << all_extruders.size());
unsigned int final_state = iterations - 1;
std::vector<std::vector<float>>cache(iterations, std::vector<float>(all_extruders.size(), 0x7fffffff));
std::vector<std::vector<float>>cache(iterations, std::vector<float>(all_extruders.size(), std::numeric_limits<float>::max()));
std::vector<std::vector<int>>prev(iterations, std::vector<int>(all_extruders.size(), -1));
cache[1][0] = 0.;
for (unsigned int state = 0; state < iterations; ++state) {
+2 -2
View File
@@ -30,8 +30,8 @@ bool Line::intersection_infinite(const Line &other, Point* point) const
return false;
double t1 = cross2(v12, v2) / denom;
Vec2d result = (a1 + t1 * v1);
if (result.x() > std::numeric_limits<coord_t>::max() || result.x() < std::numeric_limits<coord_t>::lowest() ||
result.y() > std::numeric_limits<coord_t>::max() || result.y() < std::numeric_limits<coord_t>::lowest()) {
if (result.x() > double(std::numeric_limits<coord_t>::max()) || result.x() < double(std::numeric_limits<coord_t>::lowest()) ||
result.y() > double(std::numeric_limits<coord_t>::max()) || result.y() < double(std::numeric_limits<coord_t>::lowest())) {
// Intersection has at least one of the coordinates much bigger (or smaller) than coord_t maximum value (or minimum).
// So it can not be stored into the Point without integer overflows. That could mean that input lines are parallel or near parallel.
return false;
+6 -8
View File
@@ -1511,13 +1511,9 @@ bool PrintObject::invalidate_state_by_config_options(
steps.emplace_back(posPerimeters);
steps.emplace_back(posSupportMaterial);
} else if (opt_key == "bridge_flow" || opt_key == "internal_bridge_flow") {
if (m_config.support_top_z_distance > 0.) {
// Only invalidate due to bridging if bridging is enabled.
// If later "support_top_z_distance" is modified, the complete PrintObject is invalidated anyway.
steps.emplace_back(posPerimeters);
steps.emplace_back(posInfill);
steps.emplace_back(posSupportMaterial);
}
steps.emplace_back(posPerimeters);
steps.emplace_back(posInfill);
steps.emplace_back(posSupportMaterial);
} else if (
opt_key == "wall_generator"
|| opt_key == "wall_transition_length"
@@ -1635,7 +1631,9 @@ bool PrintObject::invalidate_step(PrintObjectStep step)
bool PrintObject::invalidate_all_steps()
{
// First call the "invalidate" functions, which may cancel background processing.
bool result = Inherited::invalidate_all_steps() | m_print->invalidate_all_steps();
const bool inherited_invalidated = Inherited::invalidate_all_steps();
const bool print_invalidated = m_print->invalidate_all_steps();
bool result = inherited_invalidated || print_invalidated;
// Then reset some of the depending values.
m_slicing_params.valid = false;
return result;
+3 -1
View File
@@ -1007,7 +1007,9 @@ bool SLAPrintObject::invalidate_step(SLAPrintObjectStep step)
bool SLAPrintObject::invalidate_all_steps()
{
return Inherited::invalidate_all_steps() | m_print->invalidate_all_steps();
const bool inherited_invalidated = Inherited::invalidate_all_steps();
const bool print_invalidated = m_print->invalidate_all_steps();
return inherited_invalidated || print_invalidated;
}
double SLAPrintObject::get_elevation() const {
+3 -1
View File
@@ -1,3 +1,5 @@
#include <limits>
#include <nlohmann/json.hpp>
#include "DevMapping.h"
#include "DevFilaSystem.h"
@@ -270,7 +272,7 @@ namespace Slic3r
std::set<int> picked_tar;
for (int k = 0; k < distance_map.size(); k++)
{
float min_val = INT_MAX;
float min_val = std::numeric_limits<float>::max();
int picked_src_idx = -1;
int picked_tar_idx = -1;
for (int i = 0; i < distance_map.size(); i++)
+15 -1
View File
@@ -5059,7 +5059,21 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
}
//BBS: notify instance updates to part plater list
m_selection.notify_instance_update(-1, 0);
// Only what moved: the selected instances, or every instance of an object one of whose
// parts moved. Notifying a plate about an instance that stayed put invalidates its slice
// result, and notifying instance 0 alone left a moved copy unregistered on its new plate.
{
std::set<std::pair<int, int>> notified;
for (unsigned int i : m_selection.get_volume_idxs()) {
const GLVolume* v = m_volumes.volumes[i];
const int object_idx = v->object_idx();
if (object_idx < 0 || object_idx >= static_cast<int>(m_model->objects.size()))
continue;
const std::pair<int, int> key(object_idx, selection_mode == Selection::Volume ? -1 : v->instance_idx());
if (notified.insert(key).second)
m_selection.notify_instance_update(key.first, key.second);
}
}
// Fixes sinking/flying instances (snaps object to buildplate)
for (const std::pair<int, int>& i : done) {
-221
View File
@@ -7769,21 +7769,6 @@ void GUI_App::stop_http_server()
m_http_server.stop();
}
void GUI_App::switch_staff_pick(bool on)
{
mainframe->m_webview->SendDesignStaffpick(on);
}
bool GUI_App::switch_language()
{
if (select_language()) {
recreate_GUI(_L("Switching application language") + dots);
return true;
} else {
return false;
}
}
#ifdef __linux__
static const wxLanguageInfo* linux_get_existing_locale_language(const wxLanguageInfo* language,
const wxLanguageInfo* system_language)
@@ -7878,72 +7863,6 @@ int GUI_App::GetSingleChoiceIndex(const wxString& message,
#endif
}
// select language from the list of installed languages
bool GUI_App::select_language()
{
wxArrayString translations = wxTranslations::Get()->GetAvailableTranslations(SLIC3R_APP_KEY);
std::vector<const wxLanguageInfo*> language_infos;
language_infos.emplace_back(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH));
for (size_t i = 0; i < translations.GetCount(); ++ i) {
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(translations[i]);
if (langinfo != nullptr)
language_infos.emplace_back(langinfo);
}
sort_remove_duplicates(language_infos);
std::sort(language_infos.begin(), language_infos.end(), [](const wxLanguageInfo* l, const wxLanguageInfo* r) { return l->Description < r->Description; });
wxArrayString names;
names.Alloc(language_infos.size());
// Some valid language should be selected since the application start up.
const wxString active_language_code = current_language_code();
const wxLanguageInfo* active_language_info = wxLocale::FindLanguageInfo(active_language_code);
const wxLanguage current_language = active_language_info != nullptr ? wxLanguage(active_language_info->Language) : wxLanguage(m_wxLocale->GetLanguage());
const wxString active_lang_prefix = active_language_code.BeforeFirst('_');
int init_selection = -1;
int init_selection_alt = -1;
int init_selection_default = -1;
for (size_t i = 0; i < language_infos.size(); ++ i) {
if (wxLanguage(language_infos[i]->Language) == current_language)
// The dictionary matches the active language and country.
init_selection = i;
else if ((language_infos[i]->CanonicalName.BeforeFirst('_') == active_lang_prefix) ||
// if the active language is Slovak, mark the Czech language as active.
(language_infos[i]->CanonicalName.BeforeFirst('_') == "cs" && active_lang_prefix == "sk"))
// The dictionary matches the active language, it does not necessarily match the country.
init_selection_alt = i;
if (language_infos[i]->CanonicalName.BeforeFirst('_') == "en")
// This will be the default selection if the active language does not match any dictionary.
init_selection_default = i;
names.Add(language_infos[i]->Description);
}
if (init_selection == -1)
// This is the dictionary matching the active language.
init_selection = init_selection_alt;
if (init_selection != -1)
// This is the language to highlight in the choice dialog initially.
init_selection_default = init_selection;
const long index = GetSingleChoiceIndex(_L("Select the language"), _L("Language"), names, init_selection_default);
// Try to load a new language.
if (index != -1 && (init_selection == -1 || init_selection != index)) {
const wxLanguageInfo *new_language_info = language_infos[index];
if (this->load_language(new_language_info->CanonicalName, false)) {
// Save language at application config.
// Which language to save as the selected dictionary language?
// 1) Hopefully the language set to wxTranslations by this->load_language(), but that API is weird and we don't want to rely on its
// stability in the future:
// wxTranslations::Get()->GetBestTranslation(SLIC3R_APP_KEY, wxLANGUAGE_ENGLISH);
// 2) Current locale language may not match the dictionary name, see GH issue #3901
// m_wxLocale->GetCanonicalName()
// 3) new_language_info->CanonicalName is a safe bet. It points to a valid dictionary name.
app_config->set("language", new_language_info->CanonicalName.ToUTF8().data());
return true;
}
}
return false;
}
// Load gettext translation files and activate them at the start of the application,
// based on the "language" key stored in the application config.
@@ -8330,146 +8249,6 @@ void GUI_App::show_ip_address_enter_dialog_handler(wxCommandEvent& evt)
show_modal_ip_address_enter_dialog(mode == -1?false:true, title);
}
//void GUI_App::add_config_menu(wxMenuBar *menu)
//void GUI_App::add_config_menu(wxMenu *menu)
//{
// auto local_menu = new wxMenu();
// wxWindowID config_id_base = wxWindow::NewControlId(int(ConfigMenuCnt));
//
// const auto config_wizard_name = _(ConfigWizard::name(true));
// const auto config_wizard_tooltip = from_u8((boost::format(_utf8(L("Open %s"))) % config_wizard_name).str());
// // Cmd+, is standard on OS X - what about other operating systems?
// if (is_editor()) {
// local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_name + dots, config_wizard_tooltip);
// local_menu->Append(config_id_base + ConfigMenuUpdate, _L("Check for Configuration Updates"), _L("Check for configuration updates"));
// local_menu->AppendSeparator();
// }
// local_menu->Append(config_id_base + ConfigMenuPreferences, _L("Preferences") + dots +
//#ifdef __APPLE__
// "\tCtrl+,",
//#else
// "\tCtrl+P",
//#endif
// _L("Application preferences"));
// wxMenu* mode_menu = nullptr;
// if (is_editor()) {
// local_menu->AppendSeparator();
// mode_menu = new wxMenu();
// mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _L("Simple"), _L("Simple Mode"));
// mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeAdvanced, _L("Advanced"), _L("Advanced Mode"));
// Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comSimple) evt.Check(true); }, config_id_base + ConfigMenuModeSimple);
// Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { if (get_mode() == comAdvanced) evt.Check(true); }, config_id_base + ConfigMenuModeAdvanced);
//
// local_menu->AppendSubMenu(mode_menu, _L("Mode"), wxString::Format(_L("%s Mode"), SLIC3R_APP_NAME));
// }
// local_menu->AppendSeparator();
// local_menu->Append(config_id_base + ConfigMenuLanguage, _L("Language"));
// if (is_editor()) {
// local_menu->AppendSeparator();
// }
//
// local_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent &event) {
// switch (event.GetId() - config_id_base) {
// case ConfigMenuWizard:
// run_wizard(ConfigWizard::RR_USER);
// break;
// case ConfigMenuUpdate:
// check_updates(true);
// break;
//#ifdef __linux__
// case ConfigMenuDesktopIntegration:
// show_desktop_integration_dialog();
// break;
//#endif
// case ConfigMenuSnapshots:
// //BBS do not support task snapshot
// break;
// case ConfigMenuPreferences:
// {
// //BBS GUI refactor: remove unuse layout logic
// //bool app_layout_changed = false;
// {
// // the dialog needs to be destroyed before the call to recreate_GUI()
// // or sometimes the application crashes into wxDialogBase() destructor
// // so we put it into an inner scope
// PreferencesDialog dlg(mainframe);
// dlg.ShowModal();
// //BBS GUI refactor: remove unuse layout logic
// //app_layout_changed = dlg.settings_layout_changed();
// if (dlg.seq_top_layer_only_changed())
// this->plater_->refresh_print();
//
// if (dlg.recreate_GUI()) {
// recreate_GUI(_L("Restart application") + dots);
// return;
// }
//#ifdef _WIN32
// if (is_editor()) {
// if (app_config->get("associate_3mf") == "true")
// associate_3mf_files();
// if (app_config->get("associate_stl") == "true")
// associate_stl_files();
// }
// else {
// if (app_config->get("associate_gcode") == "true")
// associate_gcode_files();
// }
//#endif // _WIN32
// }
// //BBS GUI refactor: remove unuse layout logic
// /*if (app_layout_changed) {
// // hide full main_sizer for mainFrame
// mainframe->GetSizer()->Show(false);
// mainframe->update_layout();
// mainframe->select_tab(size_t(0));
// }*/
// break;
// }
// case ConfigMenuLanguage:
// {
// /* Before change application language, let's check unsaved changes on 3D-Scene
// * and draw user's attention to the application restarting after a language change
// */
// {
// // the dialog needs to be destroyed before the call to switch_language()
// // or sometimes the application crashes into wxDialogBase() destructor
// // so we put it into an inner scope
// wxString title = is_editor() ? wxString(SLIC3R_APP_NAME) : wxString(GCODEVIEWER_APP_NAME);
// title += " - " + _L("Choose language");
// //wxMessageDialog dialog(nullptr,
// MessageDialog dialog(nullptr,
// _L("Switching the language requires application restart.\n") + "\n\n" +
// _L("Do you want to continue?"),
// title,
// wxICON_QUESTION | wxOK | wxCANCEL);
// if (dialog.ShowModal() == wxID_CANCEL)
// return;
// }
//
// switch_language();
// break;
// }
// case ConfigMenuFlashFirmware:
// //BBS FirmwareDialog::run(mainframe);
// break;
// default:
// break;
// }
// });
//
// using std::placeholders::_1;
//
// if (mode_menu != nullptr) {
// auto modfn = [this](int mode, wxCommandEvent&) { if (get_mode() != mode) save_mode(mode); };
// mode_menu->Bind(wxEVT_MENU, std::bind(modfn, comSimple, _1), config_id_base + ConfigMenuModeSimple);
// mode_menu->Bind(wxEVT_MENU, std::bind(modfn, comAdvanced, _1), config_id_base + ConfigMenuModeAdvanced);
// }
//
// // BBS
// //menu->Append(local_menu, _L("Configuration"));
// menu->AppendSubMenu(local_menu, _L("Configuration"));
//}
void GUI_App::open_presetbundledialog(size_t open_on_tab, const std::string& highlight_option)
{
bool app_layout_changed = false;
-3
View File
@@ -569,7 +569,6 @@ public:
void start_http_server(const std::string& provider = ORCA_CLOUD_PROVIDER);
void start_http_server(int port, const std::string& provider = ORCA_CLOUD_PROVIDER);
void stop_http_server();
void switch_staff_pick(bool on);
void on_show_check_privacy_dlg(int online_login = 0, const std::string& provider = ORCA_CLOUD_PROVIDER);
void show_check_privacy_dlg(wxCommandEvent& evt);
@@ -583,7 +582,6 @@ public:
void persist_window_geometry(wxTopLevelWindow *window, bool default_maximized = false);
void update_ui_from_settings();
bool switch_language();
bool load_language(wxString language, bool initial);
Tab* get_tab(Preset::Type type);
@@ -801,7 +799,6 @@ private:
bool window_pos_restore(wxTopLevelWindow* window, const std::string &name, bool default_maximized = false);
void window_pos_sanitize(wxTopLevelWindow* window);
void window_pos_center(wxTopLevelWindow *window);
bool select_language();
// Dynamic printer agent selection - internal helpers for switch_printer_agent
// and the plugin load/unload callbacks (init_plugin_gui_wiring).
-89
View File
@@ -3275,98 +3275,9 @@ void MainFrame::init_menubar_as_editor()
auto preference_item = new wxMenuItem(parent_menu, ConfigMenuPreferences + config_id_base, _L("Preferences") + "\t" + ctrl + "P", "");
#endif
//auto printer_item = new wxMenuItem(parent_menu, ConfigMenuPrinter + config_id_base, _L("Printer"), "");
//auto language_item = new wxMenuItem(parent_menu, ConfigMenuLanguage + config_id_base, _L("Switch Language"), "");
// parent_menu->Bind(wxEVT_MENU, [this, config_id_base](wxEvent& event) {
// switch (event.GetId() - config_id_base) {
// //case ConfigMenuLanguage:
// //{
// // /* Before change application language, let's check unsaved changes on 3D-Scene
// // * and draw user's attention to the application restarting after a language change
// // */
// // {
// // // the dialog needs to be destroyed before the call to switch_language()
// // // or sometimes the application crashes into wxDialogBase() destructor
// // // so we put it into an inner scope
// // wxString title = _L("Language selection");
// // wxMessageDialog dialog(nullptr,
// // _L("Switching the language requires application restart.\n") + "\n\n" +
// // _L("Do you want to continue?"),
// // title,
// // wxICON_QUESTION | wxOK | wxCANCEL);
// // if (dialog.ShowModal() == wxID_CANCEL)
// // return;
// // }
//
// // wxGetApp().switch_language();
// // break;
// //}
// //case ConfigMenuWizard:
// //{
// // wxGetApp().run_wizard(ConfigWizard::RR_USER);
// // break;
// //}
// case ConfigMenuPrinter:
// {
// wxGetApp().params_dialog()->Popup();
// wxGetApp().get_tab(Preset::TYPE_PRINTER)->restore_last_select_item();
// break;
// }
// case ConfigMenuPreferences:
// {
// CallAfter([this] {
// PreferencesDialog dlg(this);
// dlg.ShowModal();
//#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
//#else
// if (dlg.seq_top_layer_only_changed())
//#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// plater()->refresh_print();
//#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
//#ifdef _WIN32
// /*
// if (wxGetApp().app_config()->get("associate_3mf") == "true")
// wxGetApp().associate_3mf_files();
// if (wxGetApp().app_config()->get("associate_stl") == "true")
// wxGetApp().associate_stl_files();
// /*if (wxGetApp().app_config()->get("associate_step") == "true")
// wxGetApp().associate_step_files();*/
//#endif // _WIN32
//#endif
// });
// break;
// }
// default:
// break;
// }
// });
#ifdef __APPLE__
wxString about_title = wxString::Format(_L("&About %s"), SLIC3R_APP_FULL_NAME);
//auto about_item = new wxMenuItem(parent_menu, OrcaSlicerMenuAbout + bambu_studio_id_base, about_title, "");
//parent_menu->Bind(wxEVT_MENU, [this, bambu_studio_id_base](wxEvent& event) {
// switch (event.GetId() - bambu_studio_id_base) {
// case OrcaSlicerMenuAbout:
// Slic3r::GUI::about();
// break;
// case OrcaSlicerMenuPreferences:
// CallAfter([this] {
// PreferencesDialog dlg(this);
// dlg.ShowModal();
//#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// if (dlg.seq_top_layer_only_changed() || dlg.seq_seq_top_gcode_indices_changed())
//#else
// if (dlg.seq_top_layer_only_changed())
//#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
// plater()->refresh_print();
// });
// break;
// default:
// break;
// }
//});
//parent_menu->Insert(0, about_item);
append_menu_item(
parent_menu, wxID_ANY, _L(about_title), "",
[](wxCommandEvent &) { Slic3r::GUI::about();},
+2 -2
View File
@@ -297,7 +297,7 @@ void MeshClipper::recalculate_triangles()
// it so it lies on our line. This will be the figure to subtract
// from the cut. The coordinates must not overflow after the transform,
// make the rectangle a bit smaller.
const coord_t size = (std::numeric_limits<coord_t>::max()/2 - scale_(std::max(std::abs(e * a), std::abs(e * b)))) / 4;
const coord_t size = (double(std::numeric_limits<coord_t>::max()/2) - scale_(std::max(std::abs(e * a), std::abs(e * b)))) / 4;
Polygons ep {Polygon({Point(-size, 0), Point(size, 0), Point(size, 2*size), Point(-size, 2*size)})};
ep.front().rotate(angle);
ep.front().translate(scale_(-e * a), scale_(-e * b));
@@ -352,7 +352,7 @@ void MeshClipper::recalculate_triangles()
// To prevent overflow after scaling, downscale the input if needed:
double extra_scale = 1.;
coord_t limit = coord_t(std::min(std::numeric_limits<coord_t>::max() / (2. * std::max(1., scale_x)), std::numeric_limits<coord_t>::max() / (2. * std::max(1., scale_y))));
coord_t limit = coord_t(std::min(double(std::numeric_limits<coord_t>::max()) / (2. * std::max(1., scale_x)), double(std::numeric_limits<coord_t>::max()) / (2. * std::max(1., scale_y))));
coord_t max_coord = 0;
for (const Point& pt : exp.contour)
max_coord = std::max(max_coord, std::max(std::abs(pt.x()), std::abs(pt.y())));
+3 -3
View File
@@ -1917,7 +1917,7 @@ std::vector<int> PartPlate::get_extruders_without_support(bool conside_custom_gc
const DynamicPrintConfig& glb_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
for (int obj_idx = 0; obj_idx < m_model->objects.size(); obj_idx++) {
if (!contain_instance_totally(obj_idx, 0))
if (!contain_any_instance_totally(obj_idx))
continue;
ModelObject* mo = m_model->objects[obj_idx];
@@ -2088,7 +2088,7 @@ bool PartPlate::check_single_extruder_mixed_filament_risk(const DynamicPrintConf
"which may significantly increase waste and the risk of nozzle / waste-chute clogging.");
for (int obj_idx = 0; obj_idx < (int)m_model->objects.size(); ++obj_idx) {
if (!contain_instance_totally(obj_idx, 0))
if (!contain_any_instance_totally(obj_idx))
continue;
ModelObject *mo = m_model->objects[obj_idx];
int obj_ext = mo->config.has("extruder") ? mo->config.extruder() : 1;
@@ -2307,7 +2307,7 @@ bool PartPlate::check_compatible_of_nozzle_and_filament(const DynamicPrintConfig
return wipe_tower_size;
for (int obj_idx = 0; obj_idx < m_model->objects.size(); obj_idx++) {
if (!use_global_objects && !contain_instance_totally(obj_idx, 0))
if (!use_global_objects && !contain_any_instance_totally(obj_idx))
continue;
BoundingBoxf3 bbox = m_model->objects[obj_idx]->bounding_box();
+7 -1
View File
@@ -17839,6 +17839,10 @@ void Plater::increase_instances(size_t num)
model_object->add_instance(offset_vec, model_instance->get_scaling_factor(), model_instance->get_rotation(), model_instance->get_mirror());
// p->print.get_object(obj_idx)->add_copy(Slic3r::to_2d(offset_vec));
}
// Register the copies with the plate they land on before the scene reloads: the plate's
// filament list and wipe tower preview are read from that registry.
for (size_t i = model_object->instances.size() - num; i < model_object->instances.size(); ++i)
p->partplate_list.notify_instance_update(obj_idx, static_cast<int>(i));
#ifdef SUPPORT_AUTO_CENTER
if (p->get_config("autocenter") == "true")
@@ -17869,8 +17873,10 @@ void Plater::decrease_instances(size_t num)
ModelObject* model_object = p->model.objects[obj_idx];
if (model_object->instances.size() > num) {
for (size_t i = 0; i < num; ++ i)
for (size_t i = 0; i < num; ++ i) {
p->partplate_list.notify_instance_removed(obj_idx, static_cast<int>(model_object->instances.size()) - 1);
model_object->delete_last_instance();
}
p->update();
// Delete object from Sidebar list. Do it after update, so that the GLScene selection is updated with the modified model.
sidebar().obj_list()->decrease_object_instances(obj_idx, num);
+3 -20
View File
@@ -507,26 +507,14 @@ wxBoxSizer *PreferencesDialog::create_item_language_combobox(wxString title, wxS
}
}
// the dialog needs to be destroyed before the call to switch_language()
// or sometimes the application crashes into wxDialogBase() destructor
// so we put it into an inner scope
MessageDialog msg_wingow(nullptr, _L("Switching languages requires the application to restart.\n") + "\n" + _L("Do you want to continue?"),
L("Language selection"), wxICON_QUESTION | wxOK | wxCANCEL);
if (msg_wingow.ShowModal() == wxID_CANCEL) {
MessageDialog msg_window(nullptr, _L("Switching languages requires the application to restart.\n") + "\n" + _L("Do you want to continue?"),
_L("Language selection"), wxICON_QUESTION | wxOK | wxCANCEL);
if (msg_window.ShowModal() == wxID_CANCEL) {
combobox->SetSelection(m_current_language_selected);
return;
}
}
auto check = [](bool yes_or_no) {
// if (yes_or_no)
// return true;
int act_btns = ActionButtons::SAVE;
return wxGetApp().check_and_keep_current_preset_changes(_L("Switching application language"),
_L("Switching application language while some presets are modified."), act_btns);
};
m_current_language_selected = combobox->GetSelection();
if (m_current_language_selected >= 0 && m_current_language_selected < vlist.size()) {
m_pending_language = vlist[m_current_language_selected]->CanonicalName.ToUTF8().data();
@@ -1031,11 +1019,6 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxString too
app_config->set_bool(param, checkbox->GetValue());
app_config->save();
// if (param == "staff_pick_switch") {
// bool pbool = app_config->get("staff_pick_switch") == "true";
// wxGetApp().switch_staff_pick(pbool);
// }
if (param == "sync_user_preset") {
bool sync = app_config->get("sync_user_preset") == "true" ? true : false;
if (sync) {
+1 -1
View File
@@ -1803,7 +1803,7 @@ static void* get_function(const char* name)
return function;
#if defined(_MSC_VER) || defined(_WIN32)
function = GetProcAddress(module, name);
function = reinterpret_cast<void*>(GetProcAddress(module, name));
#else
function = dlsym(module, name);
#endif
+1 -1
View File
@@ -995,7 +995,7 @@ void FanControlPopupNew::init_names(MachineObject* obj) {
radio_btn_name[AIR_DUCT::AIR_DUCT_HEATING_INTERNAL_FILT] = _L("Heating");
radio_btn_name[AIR_DUCT::AIR_DUCT_EXHAUST] = _L("Exhaust");
radio_btn_name[AIR_DUCT::AIR_DUCT_FULL_COOLING] = _L("Full Cooling");
radio_btn_name[AIR_DUCT::AIR_DUCT_INIT] = L("Init");
radio_btn_name[AIR_DUCT::AIR_DUCT_INIT] = _L("Init");
air_door_func_name[AIR_DOOR::AIR_DOOR_FUNC_CHAMBER] = _L("Chamber");
air_door_func_name[AIR_DOOR::AIR_DOOR_FUNC_INNERLOOP] = _L("Innerloop");
+1 -1
View File
@@ -349,7 +349,7 @@ void* BBLNetworkPlugin::get_function(const char* name)
return function;
#if defined(_MSC_VER) || defined(_WIN32)
function = GetProcAddress(m_networking_module, name);
function = reinterpret_cast<void*>(GetProcAddress(m_networking_module, name));
#else
function = dlsym(m_networking_module, name);
#endif
+16 -5
View File
@@ -8,6 +8,7 @@
#include <nlohmann/json.hpp>
using json = nlohmann::json;
#include <type_traits>
#include <unordered_map>
namespace Slic3r {
@@ -90,6 +91,16 @@ OnMessageFn to_orca_messages(OnMessageFn fn)
return [fn = std::move(fn)](std::string dev_id, std::string msg) { fn(std::move(dev_id), BBLPrinterAgent::to_orca_payload(std::move(msg))); };
}
// Retypes a plug-in entry point for an older plug-in generation. The detour through the
// generic function pointer marks the signature change as deliberate, which a direct cast
// between two signatures does not.
template <typename To, typename From>
To as_abi(From fn)
{
static_assert(std::is_function_v<std::remove_pointer_t<From>>, "as_abi retypes a function pointer");
return reinterpret_cast<To>(reinterpret_cast<void (*)()>(fn));
}
} // namespace
std::string BBLPrinterAgent::to_orca_filament_id(const std::string& printer_filament_id) const
@@ -141,7 +152,7 @@ int BBLPrinterAgent::send_message(std::string dev_id, std::string json_str, int
// series through the legacy form would silently drop MessageFlag sign/encrypt.
switch (plugin.network_abi()) {
case NetworkAbi::Legacy: {
auto legacy_func = reinterpret_cast<func_send_message_legacy>(func);
auto legacy_func = as_abi<func_send_message_legacy>(func);
return legacy_func(agent, std::move(dev_id), std::move(json_str), qos);
}
case NetworkAbi::V0203:
@@ -185,7 +196,7 @@ int BBLPrinterAgent::send_message_to_printer(std::string dev_id, std::string jso
if (func && agent) {
switch (plugin.network_abi()) {
case NetworkAbi::Legacy: {
auto legacy_func = reinterpret_cast<func_send_message_to_printer_legacy>(func);
auto legacy_func = as_abi<func_send_message_to_printer_legacy>(func);
return legacy_func(agent, std::move(dev_id), std::move(json_str), qos);
}
case NetworkAbi::V0203:
@@ -275,7 +286,7 @@ int BBLPrinterAgent::bind(std::string dev_ip, std::string dev_id, std::string de
switch (plugin.network_abi()) {
case NetworkAbi::Legacy:
case NetworkAbi::V0203: {
auto older_func = reinterpret_cast<func_bind_pre0208>(func);
auto older_func = as_abi<func_bind_pre0208>(func);
return older_func(agent, dev_ip, dev_id, sec_link, timezone, improved, update_fn);
}
case NetworkAbi::Current:
@@ -436,9 +447,9 @@ int dispatch_start(CurrentFn func, PrintParams& params, const CallbackFns&... ca
params.ams_mapping_info = BBLPrinterAgent::from_orca_payload(std::move(params.ams_mapping_info));
switch (plugin.network_abi()) {
case NetworkAbi::Legacy:
return reinterpret_cast<LegacyFn>(func)(agent, BBLNetworkPlugin::as_legacy(params), callbacks...);
return as_abi<LegacyFn>(func)(agent, BBLNetworkPlugin::as_legacy(params), callbacks...);
case NetworkAbi::V0203:
return reinterpret_cast<Fn0203>(func)(agent, BBLNetworkPlugin::as_0203(params), callbacks...);
return as_abi<Fn0203>(func)(agent, BBLNetworkPlugin::as_0203(params), callbacks...);
case NetworkAbi::Current:
return func(agent, std::move(params), callbacks...);
default:
+1 -1
View File
@@ -1620,7 +1620,7 @@ void PresetUpdater::priv::check_new_vendors(const std::set<std::string>& system_
Http::get(download_url_str)
.timeout_connect(5)
.on_progress(check_cancel)
.on_error([&vendor_id, &retry_count, max_retries](std::string body, std::string error, unsigned http_status) {
.on_error([&vendor_id, &retry_count](std::string body, std::string error, unsigned http_status) {
BOOST_LOG_TRIVIAL(warning) << "[Orca Updater] download failed for new vendor " << vendor_id
<< " (attempt " << retry_count << "/" << max_retries << "): " << error;
})