Compare commits

..
Author SHA1 Message Date
Hanif Koh cca0f61c1b Remove the OBJ Color Dialog That Texture Import Replaced 2026-10-04 20:46:09 +08:00
15 changed files with 528 additions and 1148 deletions
+1 -1
View File
@@ -177,6 +177,7 @@ src/slic3r/GUI/PresetHints.cpp
src/slic3r/GUI/ProgressStatusBar.cpp
src/slic3r/GUI/PlateSettingsDialog.cpp
src/slic3r/GUI/PrivacyUpdateDialog.cpp
src/slic3r/GUI/PublishDialog.cpp
src/slic3r/GUI/PublishSettingsDialog.cpp
src/slic3r/GUI/SavePresetDialog.cpp
src/slic3r/GUI/SceneBenchmark.cpp
@@ -195,7 +196,6 @@ src/slic3r/GUI/Tab.hpp
src/slic3r/GUI/UnsavedChangesDialog.cpp
src/slic3r/GUI/Auxiliary.cpp
src/slic3r/GUI/UpdateDialogs.cpp
src/slic3r/GUI/ObjColorDialog.cpp
src/slic3r/GUI/SyncAmsInfoDialog.cpp
src/slic3r/GUI/WipeTowerDialog.cpp
src/slic3r/GUI/wxExtensions.cpp
+4
View File
@@ -0,0 +1,4 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.97222 3H4C2.89543 3 2 3.89543 2 5V14C2 15.1046 2.89543 16 4 16H14.4444C15.549 16 16.4444 15.1046 16.4444 14V5C16.4444 3.89543 15.549 3 14.4444 3H12.8333" stroke="white" stroke-linecap="round"/>
<path d="M9.93711 2.64645C9.74185 2.45118 9.42527 2.45118 9.23 2.64645L6.04802 5.82843C5.85276 6.02369 5.85276 6.34027 6.04802 6.53553C6.24329 6.7308 6.55987 6.7308 6.75513 6.53553L9.58356 3.70711L12.412 6.53553C12.6072 6.7308 12.9238 6.7308 13.1191 6.53553C13.3144 6.34027 13.3144 6.02369 13.1191 5.82843L9.93711 2.64645ZM9.08356 11.3056C9.08356 11.5817 9.30741 11.8056 9.58356 11.8056C9.8597 11.8056 10.0836 11.5817 10.0836 11.3056H9.08356ZM9.08356 3V11.3056H10.0836V3H9.08356Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 805 B

@@ -0,0 +1,10 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_12)">
<path d="M18 0H0V18H18V0Z" fill="#262E2F"/>
</g>
<defs>
<clipPath id="clip0_1_12">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 283 B

-12
View File
@@ -29,18 +29,6 @@ struct ObjInfo {
std::vector<ObjParser::ObjUseMtl> usemtls; // material spans, for texture import
};
struct ObjDialogInOut
{ // input:colors array
std::vector<RGBA> input_colors;
bool is_single_color{false};
// colors array output:
std::vector<unsigned char> filament_ids;
unsigned char first_extruder_id;
bool deal_vertex_color;
Model * model{nullptr};
std::string lost_material_name{""};
};
typedef std::function<void(ObjDialogInOut &in_out)> ObjImportColorFn;
extern bool load_obj(const char *path, TriangleMesh *mesh, ObjInfo &vertex_colors, std::string &message, ObjParser::MtlData *out_mtl = nullptr);
extern bool load_obj(const char *path, Model *model, ObjInfo &vertex_colors, std::string &message, const char *object_name = nullptr, ObjParser::MtlData *out_mtl = nullptr);
+1 -2
View File
@@ -321,8 +321,7 @@ Model Model::read_from_file(const std::string&
Import3mfProgressFn proFn,
ImportstlProgressFn stlFn,
BBLProject * project,
int plate_id,
ObjImportColorFn objFn)
int plate_id)
{
Model model;
+1 -2
View File
@@ -1756,8 +1756,7 @@ public:
std::vector<Preset*>* project_presets = nullptr, bool* is_xxx = nullptr, Semver* file_version = nullptr, Import3mfProgressFn proFn = nullptr,
ImportstlProgressFn stlFn = nullptr,
BBLProject * project = nullptr,
int plate_id = 0,
ObjImportColorFn objFn = nullptr
int plate_id = 0
);
// BBS
static bool obj_import_vertex_color_deal(const std::vector<unsigned char> &vertex_filament_ids, const unsigned char &first_extruder_id, Model *model);
+2 -2
View File
@@ -428,8 +428,6 @@ set(SLIC3R_GUI_SOURCES
GUI/NotificationManager.hpp
GUI/OAuthDialog.cpp
GUI/OAuthDialog.hpp
GUI/ObjColorDialog.cpp
GUI/ObjColorDialog.hpp
GUI/ObjectDataViewModel.cpp
GUI/ObjectDataViewModel.hpp
GUI/OG_CustomCtrl.cpp
@@ -483,6 +481,8 @@ set(SLIC3R_GUI_SOURCES
GUI/ProjectDirtyStateManager.cpp
GUI/ProjectDirtyStateManager.hpp
GUI/Project.hpp
GUI/PublishDialog.cpp
GUI/PublishDialog.hpp
GUI/PublishSettingsDialog.cpp
GUI/PublishSettingsDialog.hpp
GUI/PurgeModeDialog.cpp
+32
View File
@@ -46,6 +46,7 @@ enum CUSTOM_ID
ID_TOP_DROPDOWN_MENU,
ID_TITLE,
ID_MODEL_STORE,
ID_PUBLISH,
ID_CALIB,
ID_TOOL_BAR = 3200,
ID_AMS_NOTEBOOK,
@@ -338,6 +339,10 @@ void BBLTopbar::Init(wxFrame* parent)
this->AddSpacer(FromDIP(25));
//this->AddStretchSpacer(1);
//m_publish_bitmap = create_scaled_bitmap("topbar_publish", nullptr, TOPBAR_ICON_SIZE);
//m_publish_item = this->AddTool(ID_PUBLISH, "", m_publish_bitmap);
//m_publish_disable_bitmap = create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE);
//m_publish_item->SetDisabledBitmap(m_publish_disable_bitmap);
//this->EnableTool(m_publish_item->GetId(), false);
//this->AddSpacer(FromDIP(4));
@@ -398,6 +403,7 @@ void BBLTopbar::Init(wxFrame* parent)
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnRedo, this, wxID_REDO);
this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnUndo, this, wxID_UNDO);
//this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnModelStoreClicked, this, ID_MODEL_STORE);
//this->Bind(wxEVT_AUITOOLBAR_TOOL_DROPDOWN, &BBLTopbar::OnPublishClicked, this, ID_PUBLISH);
}
BBLTopbar::~BBLTopbar()
@@ -414,6 +420,12 @@ void BBLTopbar::OnOpenProject(wxAuiToolBarEvent& event)
plater->load_project();
}
//void BBLTopbar::show_publish_button(bool show)
//{
// this->EnableTool(m_publish_item->GetId(), show);
// Refresh();
//}
void BBLTopbar::OnSaveProject(wxAuiToolBarEvent& event)
{
MainFrame* main_frame = dynamic_cast<MainFrame*>(m_frame);
@@ -470,6 +482,22 @@ void BBLTopbar::OnModelStoreClicked(wxAuiToolBarEvent& event)
//GUI::wxGetApp().load_url(wxString(wxGetApp().app_config->get_web_host_url() + MODEL_STORE_URL));
}
void BBLTopbar::OnPublishClicked(wxAuiToolBarEvent& event)
{
if (!wxGetApp().getAgent()) {
BOOST_LOG_TRIVIAL(info) << "publish: no agent";
return;
}
//no more check
//if (GUI::wxGetApp().plater()->model().objects.empty()) return;
#ifdef ENABLE_PUBLISHING
wxGetApp().plater()->show_publish_dialog();
#endif
wxGetApp().open_publish_page_dialog();
}
void BBLTopbar::SetFileMenu(wxMenu* file_menu)
{
m_file_menu = file_menu;
@@ -551,6 +579,10 @@ void BBLTopbar::Rescale() {
if (m_title_ctrl)
m_title_ctrl->SetTitle(m_titleText);
/*item = this->FindTool(ID_PUBLISH);
item->SetBitmap(create_scaled_bitmap("topbar_publish", this, TOPBAR_ICON_SIZE));
item->SetDisabledBitmap(create_scaled_bitmap("topbar_publish_disable", nullptr, TOPBAR_ICON_SIZE));*/
/*item = this->FindTool(ID_MODEL_STORE);
item->SetBitmap(create_scaled_bitmap("topbar_store", this, TOPBAR_ICON_SIZE));
*/
+5
View File
@@ -52,10 +52,12 @@ public:
void OnMouseCaptureLost(wxMouseCaptureLostEvent& event);
void OnMenuClose(wxMenuEvent& event);
void OnOpenProject(wxAuiToolBarEvent& event);
//void show_publish_button(bool show);
void OnSaveProject(wxAuiToolBarEvent& event);
void OnUndo(wxAuiToolBarEvent& event);
void OnRedo(wxAuiToolBarEvent& event);
void OnModelStoreClicked(wxAuiToolBarEvent& event);
void OnPublishClicked(wxAuiToolBarEvent &event);
wxAuiToolBarItem* FindToolByCurrentPosition();
@@ -95,11 +97,14 @@ private:
wxString m_titleText;
//wxAuiToolBarItem *m_publish_item;
wxAuiToolBarItem* m_undo_item;
wxAuiToolBarItem* m_redo_item;
wxAuiToolBarItem* m_calib_item;
wxAuiToolBarItem* maximize_btn;
wxBitmap m_publish_bitmap;
wxBitmap m_publish_disable_bitmap;
wxBitmap maximize_bitmap;
wxBitmap window_bitmap;
-971
View File
@@ -1,971 +0,0 @@
#include <algorithm>
#include "libslic3r/TriangleSelector.hpp"
#include "slic3r/GUI/Widgets/HyperLink.hpp"
#include "slic3r/GUI/GUI_Utils.hpp"
#include "libslic3r/Format/OBJ.hpp"
#include <cstddef>
#include "libslic3r/Color.hpp"
#include "slic3r/GUI/GuiColor.hpp"
#include "slic3r/GUI/Widgets/SpinInput.hpp"
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/GUI/wxExtensions.hpp"
#include <cmath>
#include <cstdlib>
#include <boost/log/trivial.hpp>
#include "slic3r/GUI/PartPlate.hpp"
#include "slic3r/GUI/Camera.hpp"
#include <sstream>
//#include "libslic3r/FlushVolCalc.hpp"
#include "ObjColorDialog.hpp"
#include "BitmapCache.hpp"
#include "GUI.hpp"//for ICON_SIZE
#include "I18N.hpp"
#include "GUI_App.hpp"
#include "MsgDialog.hpp"
#include "Widgets/Button.hpp"
#include "MainFrame.hpp"
#include "libslic3r/Config.hpp"
#include "BitmapComboBox.hpp"
#include "Widgets/ComboBox.hpp"
#include "Widgets/DialogButtons.hpp"
#include <wx/colour.h>
#include <wx/event.h>
#include <wx/gdicmn.h>
#include <vector>
#include <string>
#include <wx/dialog.h>
#include <wx/panel.h>
#include <wx/busycursor.h>
#include <wx/arrstr.h>
#include <wx/image.h>
#include <wx/anybutton.h>
#include <wx/scrolwin.h>
#include <wx/sizer.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <wx/spinctrl.h>
#include "libslic3r/ObjColorUtils.hpp"
#include "libslic3r/Model.hpp"
using namespace Slic3r;
using namespace Slic3r::GUI;
int objcolor_scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit() / 10; }
int OBJCOLOR_ITEM_WIDTH() { return objcolor_scale(30); }
static const wxColour g_text_color = wxColour(107, 107, 107, 255);
static const wxColour g_undefined_color_in_obj = wxColour(0, 255, 0, 255);
const int HEADER_BORDER = 5;
const int CONTENT_BORDER = 3;
const int PANEL_WIDTH = 400;
const int COLOR_LABEL_WIDTH = 180;
const int IMAGE_SIZE_WIDTH = 300;
#define MIN_OBJCOLOR_DIALOG_WIDTH FromDIP(400)
#define FIX_SCROLL_HEIGTH FromDIP(400)
#define BTN_SIZE wxSize(FromDIP(58), FromDIP(24))
#define BTN_GAP FromDIP(15)
#define FIX_SCROLL_IMAGE_WIDTH FromDIP(270)
static void update_ui(wxWindow* window)
{
Slic3r::GUI::wxGetApp().UpdateDarkUI(window);
}
static const char g_min_cluster_color = 1;
static const char g_max_color = (int) EnforcerBlockerType::ExtruderMax;
wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags,bool exist_error)
{
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
if (!exist_error) {
btn_sizer->AddSpacer(FromDIP(25));
auto *tips = new HyperLink(this, _L("Wiki Guide")); // ORCA
tips->SetURL("https://www.orcaslicer.com/wiki/import_export#obj");
btn_sizer->Add(tips, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
}
btn_sizer->AddStretchSpacer();
auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
m_button_list[wxOK] = dlg_btns->GetOK();
m_button_list[wxCANCEL] = dlg_btns->GetCANCEL();
btn_sizer->Add(dlg_btns, 0, wxEXPAND);
return btn_sizer;
}
void ObjColorDialog::on_dpi_changed(const wxRect &suggested_rect)
{
m_panel_ObjColor->msw_rescale();
this->Refresh();
}
void ObjColorDialog::update_layout() {
m_main_sizer->Layout();
SetSizerAndFit(m_main_sizer);
}
bool ObjColorDialog::Show(bool show) {
if (m_panel_ObjColor->do_show(show)) {
return DPIDialog::Show(true);
} else {
return DPIDialog::Show(false);
}
};
ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, const bool semm)
: DPIDialog(parent ? parent : static_cast<wxWindow *>(wxGetApp().mainframe),
wxID_ANY,
_(L("OBJ file import color")),
wxDefaultPosition,
wxDefaultSize,
wxDEFAULT_DIALOG_STYLE /* | wxRESIZE_BORDER*/)
{
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
this->SetBackgroundColour(*wxWHITE);
this->SetMinSize(wxSize(MIN_OBJCOLOR_DIALOG_WIDTH, -1));
m_main_sizer = new wxBoxSizer(wxVERTICAL);
m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
// set min sizer width according to extruders count
auto sizer_width = (int) (2.8 * OBJCOLOR_ITEM_WIDTH());
sizer_width = sizer_width > MIN_OBJCOLOR_DIALOG_WIDTH ? sizer_width : MIN_OBJCOLOR_DIALOG_WIDTH;
m_main_sizer->SetMinSize(wxSize(sizer_width, -1));
bool some_face_no_color = false;
if (!in_out.deal_vertex_color) {
auto temp0 = in_out.input_colors.size();
auto temp1 = in_out.model->objects[0]->volumes[0]->mesh_ptr()->facets_count();
some_face_no_color = temp0 < temp1;
}
bool ok = in_out.lost_material_name.empty() && !some_face_no_color;
if (ok) {
m_panel_ObjColor = new ObjColorPanel(this, in_out, extruder_colours, semm);
m_panel_ObjColor->set_layout_callback([this]() { update_layout(); });
m_main_sizer->Add(m_panel_ObjColor, 1, wxEXPAND | wxALL, 0);
}
else {
wxBoxSizer * error_mtl_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticText *error_mtl_title = new wxStaticText(this, wxID_ANY, _L("Some faces don't have color defined."));
if (!in_out.lost_material_name.empty()) {
error_mtl_title->SetLabel(_L("MTL file exist error, could not find the material:") + " " + in_out.lost_material_name + ".");
}
error_mtl_title->SetFont(Label::Head_12);
error_mtl_sizer->Add(error_mtl_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5));
wxStaticText *tip_title = new wxStaticText(this, wxID_ANY, _L("Please check OBJ or MTL file."));
tip_title->SetFont(Label::Head_12);
error_mtl_sizer->Add(tip_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5));
m_main_sizer->Add(error_mtl_sizer, 1, wxEXPAND | wxLEFT, FromDIP(25));
}
m_buttons_sizer = create_btn_sizer(wxOK | wxCANCEL, !ok);
if (!ok) {
m_button_list[wxCANCEL]->Hide();
m_button_list[wxOK]->Enable(true);
// ORCA no need to set colors again
} else {
m_button_list[wxOK]->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) {
if (m_panel_ObjColor->is_ok() == m_button_list[wxOK]->IsEnabled()) { return; }
m_button_list[wxOK]->Enable(m_panel_ObjColor->is_ok());
// ORCA no need to set colors again
}));
}
m_main_sizer->Add(m_buttons_sizer, 0, wxBOTTOM | wxTOP | wxRIGHT | wxEXPAND, BTN_GAP);
SetSizer(m_main_sizer);
m_main_sizer->SetSizeHints(this);
if (this->FindWindowById(wxID_OK, this)) {
this->FindWindowById(wxID_OK, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {// if OK button is clicked..
if (!m_panel_ObjColor) {
EndModal(wxCANCEL);
return;
}
m_panel_ObjColor->clear_instance_and_revert_offset();
m_panel_ObjColor->send_new_filament_to_ui();
EndModal(wxID_OK);
}, wxID_OK);
}
if (this->FindWindowById(wxID_CANCEL, this)) {
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
if (m_panel_ObjColor) {
m_panel_ObjColor->cancel_paint_color();
}
EndModal(wxCANCEL);
});
}
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &e) {
if (m_panel_ObjColor) {
m_panel_ObjColor->cancel_paint_color();
}
EndModal(wxCANCEL);
});
wxGetApp().UpdateDlgDarkUI(this);
CenterOnParent();
}
// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers)
ObjColorPanel::ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, const bool semm)
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize /*,wxBORDER_RAISED*/)
, m_obj_in_out(in_out)
, m_input_colors(in_out.input_colors)
, m_filament_ids(in_out.filament_ids)
, m_first_extruder_id(in_out.first_extruder_id)
, m_semm(semm)
{
if (in_out.input_colors.size() == 0) { return; }
for (const std::string& color : extruder_colours) {
m_colours.push_back(wxColor(color));
}
//deal input_colors
m_input_colors_size = in_out.input_colors.size();
for (size_t i = 0; i < in_out.input_colors.size(); i++) {
if (color_is_equal(in_out.input_colors[i], UNDEFINE_COLOR)) { // not define color range:0~1
in_out.input_colors[i] = convert_to_rgba(m_colours[0]);
}
}
if (in_out.is_single_color && in_out.input_colors.size() >= 1) {
m_cluster_colors_from_algo.emplace_back(in_out.input_colors[0]);
m_cluster_colours.emplace_back(convert_to_wxColour(in_out.input_colors[0]));
m_cluster_labels_from_algo.reserve(m_input_colors_size);
for (size_t i = 0; i < m_input_colors_size; i++) {
m_cluster_labels_from_algo.emplace_back(0);
}
m_cluster_map_filaments.resize(m_cluster_colors_from_algo.size());
m_new_add_colors.resize(m_cluster_map_filaments.size());
m_color_num_recommend = m_color_cluster_num_by_algo = m_cluster_colors_from_algo.size();
} else {//cluster deal
deal_algo(-1);
}
//end first cluster
//draw ui
auto sizer_width = FromDIP(300);
// Create two switched panels with their own sizers
m_sizer_simple = new wxBoxSizer(wxVERTICAL);
m_page_simple = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_page_simple->SetSizer(m_sizer_simple);
m_page_simple->SetBackgroundColour(*wxWHITE);
update_ui(m_page_simple);
// BBS
m_sizer_simple->AddSpacer(FromDIP(10));
// BBS: for tunning flush volumes
{
//color cluster results
wxBoxSizer * specify_cluster_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *specify_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Specify number of colors:"));
specify_color_cluster_title->SetFont(Label::Head_14);
specify_cluster_sizer->Add(specify_color_cluster_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
m_color_cluster_num_by_user_ebox = new SpinInput(m_page_simple, "", wxEmptyString, wxDefaultPosition, wxSize(FromDIP(60), -1), wxTE_PROCESS_ENTER);
m_color_cluster_num_by_user_ebox->SetValue(std::to_string(m_color_cluster_num_by_algo).c_str());
m_color_cluster_num_by_user_ebox->SetToolTip(_L("Enter or click the adjustment button to modify number again"));
{//event
auto on_apply_color_cluster_text_modify = [this](wxEvent &e) {
int number = m_color_cluster_num_by_user_ebox->GetValue();
if (number > m_color_num_recommend || number < g_min_cluster_color) {
number = number < g_min_cluster_color ? g_min_cluster_color : m_color_num_recommend;
auto str = wxString::Format(("%d"), number);
m_color_cluster_num_by_user_ebox->SetValue(str);
// m_color_cluster_num_by_user_ebox->SetInsertionPointEnd();
}
if (m_last_cluster_num != number) {
wxBusyCursor busy;
deal_algo(number, true);
Layout();
Refresh();
Update();
m_last_cluster_num = number;
}
};
m_color_cluster_num_by_user_ebox->Bind(wxEVT_TEXT_ENTER, on_apply_color_cluster_text_modify);
m_color_cluster_num_by_user_ebox->Bind(wxEVT_SPINCTRL, on_apply_color_cluster_text_modify);
m_color_cluster_num_by_user_ebox->Bind(wxEVT_CHAR, [](wxKeyEvent &e) {
int keycode = e.GetKeyCode();
wxString input_char = wxString::Format("%c", keycode);
long value;
if (!input_char.ToLong(&value))
return;
e.Skip();
});
}
specify_cluster_sizer->AddSpacer(FromDIP(2));
specify_cluster_sizer->Add(m_color_cluster_num_by_user_ebox, 0, wxALIGN_CENTER | wxALL, 0);
specify_cluster_sizer->AddSpacer(FromDIP(15));
wxStaticText *recommend_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, "(" + std::to_string(m_color_num_recommend) + " " + _L("Recommended ") + ")");
specify_cluster_sizer->Add(recommend_color_cluster_title, 0, wxALIGN_CENTER | wxALL, 0);
m_sizer_simple->Add(specify_cluster_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20));
{//add combox
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
auto plater = wxGetApp().plater();
{
auto mo = m_obj_in_out.model->objects[0];
mo->add_instance();
auto mv = mo->volumes[0];
m_thumbnail_offset = Slic3r::Vec3d::Zero();
auto box = mo->bounding_box_exact();
if (box.min.x() < 0 || box.min.y() < 0 || box.min.z() < 0) {
m_thumbnail_offset = Slic3r::Vec3d(box.min.x() < 0 ? -box.min.x() : 0, box.min.y() < 0 ? -box.min.y() : 0, box.min.z() < 0 ? -box.min.z() : 0);
mv->translate(m_thumbnail_offset);
}
}
wxStaticText *combox_title = new wxStaticText(m_page_simple, wxID_ANY, _L("view"));
auto cur_combox = new ComboBox(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(100), -1), 0, NULL, wxCB_READONLY);
wxArrayString choices = get_all_camera_view_type();
for (size_t i = 0; i < choices.size(); i++) { cur_combox->Append(choices[i]); }
cur_combox->SetSelection(0);
cur_combox->Bind(wxEVT_COMBOBOX, [this](auto &e) {
set_view_angle_type(e.GetSelection());
Layout();
Fit();
});
// add image
wxImage image(IMAGE_SIZE_WIDTH, IMAGE_SIZE_WIDTH);
image.InitAlpha();
for (unsigned int r = 0; r < IMAGE_SIZE_WIDTH; ++r) {
for (unsigned int c = 0; c < IMAGE_SIZE_WIDTH; ++c) {
image.SetRGB((int) c, (int) r, 0, 255, 0);
image.SetAlpha((int) c, (int) r, 255);
}
}
m_image_button = new wxButton(m_page_simple, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH)),
wxBORDER_NONE | wxBU_AUTODRAW);
m_image_button->SetBitmap(image);
m_image_button->SetCanFocus(false);
#ifdef __WXGTK__
RemoveButtonBorder(m_image_button);
#endif
icon_sizer->Add(m_image_button, 0, wxEXPAND | wxALL,
FromDIP(0)); // wxEXPAND | wxALL
cur_combox->Raise();//for mac
m_sizer_simple->Add(icon_sizer, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(0));
auto view_sizer = new wxBoxSizer(wxHORIZONTAL);
view_sizer->Add(combox_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
view_sizer->Add(cur_combox , 0, wxALIGN_CENTER | wxALL, FromDIP(5));
m_sizer_simple->Add(view_sizer, 0, wxALIGN_RIGHT | wxRIGHT, FromDIP(20));
}
wxBoxSizer * current_filaments_title_sizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *current_filaments_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Current filament colors"));
current_filaments_title->SetFont(Label::Head_14);
current_filaments_title_sizer->Add(current_filaments_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
m_sizer_simple->Add(current_filaments_title_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20));
int current_filament_row = 1;
int current_filament_col = 1;
const int one_row_max = 16;
if (m_colours.size() > 1) {
current_filament_row = (m_colours.size() - 1) / one_row_max + 1;
if (current_filament_row >= 2) {
current_filament_col = one_row_max;
} else {
current_filament_col = m_colours.size();
}
}
m_sizer_current_filaments = new wxBoxSizer(wxHORIZONTAL);
wxGridSizer *current_filaments_sizer = new wxGridSizer(current_filament_row, current_filament_col, FromDIP(5), FromDIP(7)); //(int rows, int cols, int vgap, int hgap );
for (size_t i = 0; i < m_colours.size(); i++) {
auto extruder_icon_sizer = create_extruder_icon_and_rgba_sizer(m_page_simple, i, m_colours[i]);
current_filaments_sizer->Add(extruder_icon_sizer, 0, wxALIGN_LEFT);
}
m_sizer_current_filaments->AddSpacer(FromDIP(1));
m_sizer_current_filaments->Add(current_filaments_sizer, 0, wxEXPAND);
m_sizer_current_filaments->AddStretchSpacer();
m_sizer_simple->Add(m_sizer_current_filaments, 0, wxEXPAND | wxLEFT, FromDIP(25));
//colors table title
wxBoxSizer * matching_title_sizer = new wxBoxSizer(wxHORIZONTAL);
matching_title_sizer->AddSpacer(FromDIP(25));
wxStaticText *matching_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Matching"));
matching_title->SetFont(Label::Head_14);
matching_title_sizer->Add(matching_title, 0, wxEXPAND , 0);
m_sizer_simple->Add(matching_title_sizer, 0, wxEXPAND | wxTOP, FromDIP(15));// wxTop has FromDIP(10) margin
//new color table
m_scrolledWindow = new wxScrolledWindow(m_page_simple, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
m_scrolledWindow->SetScrollRate(0, FromDIP(20));
m_scrolledWindow->EnableScrolling(false, true);
m_scrolledWindow->ShowScrollbars(wxScrollbarVisibility::wxSHOW_SB_NEVER, wxScrollbarVisibility::wxSHOW_SB_DEFAULT);
draw_new_table();
m_sizer_simple->Add(m_scrolledWindow, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(15));
//buttons
wxBoxSizer *quick_set_sizer = new wxBoxSizer(wxHORIZONTAL);
quick_set_sizer->AddSpacer(FromDIP(25));
wxStaticText *quick_set_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Quick set"));
quick_set_title->SetFont(Label::Head_12);
quick_set_sizer->Add(quick_set_title, 0, wxALIGN_CENTER | wxALL, 0);
quick_set_sizer->AddSpacer(FromDIP(10));
auto calc_approximate_match_btn_sizer = create_approximate_match_btn_sizer(m_page_simple);
auto calc_add_btn_sizer = create_add_btn_sizer(m_page_simple);
auto calc_reset_btn_sizer = create_reset_btn_sizer(m_page_simple);
quick_set_sizer->Add(calc_add_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
quick_set_sizer->AddSpacer(FromDIP(10));
quick_set_sizer->Add(calc_approximate_match_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
quick_set_sizer->AddSpacer(FromDIP(10));
quick_set_sizer->Add(calc_reset_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
quick_set_sizer->AddSpacer(FromDIP(10));
m_sizer_simple->Add(quick_set_sizer, 0, wxEXPAND | wxTOP, FromDIP(10));
wxBoxSizer *warning_sizer = new wxBoxSizer(wxHORIZONTAL);
m_warning_text = new wxStaticText(m_page_simple, wxID_ANY, "");
m_warning_text->SetForegroundColour(wxColour(107, 107, 107, 100));
warning_sizer->Add(m_warning_text, 0, wxALIGN_CENTER | wxALL, 0);
m_sizer_simple->Add(warning_sizer, 0, wxEXPAND | wxLEFT, FromDIP(25));
m_sizer_simple->AddSpacer(15);
}
deal_default_strategy();
deal_thumbnail();
//page_simple//page_advanced
m_sizer = new wxBoxSizer(wxVERTICAL);
m_sizer->Add(m_page_simple, 0, wxEXPAND, 0);
m_sizer->SetSizeHints(this);
SetSizer(m_sizer);
this->Layout();
}
ObjColorPanel::~ObjColorPanel() {
}
void ObjColorPanel::msw_rescale()
{
for (unsigned int i = 0; i < m_extruder_icon_list.size(); ++i) {
auto bitmap = *get_extruder_color_icon(m_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16));
m_extruder_icon_list[i]->SetBitmap(bitmap);
}
/* for (unsigned int i = 0; i < m_color_cluster_icon_list.size(); ++i) {
auto bitmap = *get_extruder_color_icon(m_cluster_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16));
m_color_cluster_icon_list[i]->SetBitmap(bitmap);
}*/
}
bool ObjColorPanel::is_ok() {
for (auto item : m_result_icon_list) {
if (item->bitmap_combox->IsShown()) {
auto selection = item->bitmap_combox->GetSelection();
if (selection < 1) {
return false;
}
}
}
return true;
}
void ObjColorPanel::send_new_filament_to_ui()
{
update_new_add_final_colors();
if (m_is_add_filament) {
for (auto c : m_new_add_final_colors) {
/*auto evt = new ColorEvent(EVT_ADD_CUSTOM_FILAMENT, c);
wxQueueEvent(wxGetApp().plater(), evt);*/
wxGetApp().sidebar().add_custom_filament(c);
}
}
}
void ObjColorPanel::cancel_paint_color() {
m_filament_ids.clear();
auto mo = m_obj_in_out.model->objects[0];
mo->config.set("extruder", 1);
clear_instance_and_revert_offset();
auto mv = mo->volumes[0];
mv->mmu_segmentation_facets.reset();
mv->config.set("extruder", 1);
m_first_extruder_id = 1;
}
void ObjColorPanel::update_filament_ids()
{
//deal m_filament_ids
m_filament_ids.clear();
m_filament_ids.reserve(m_input_colors_size);
for (size_t i = 0; i < m_input_colors_size; i++) {
auto label = m_cluster_labels_from_algo[i];
if (m_cluster_map_filaments[label] > 0) {
m_filament_ids.emplace_back(m_cluster_map_filaments[label]);
} else {
m_filament_ids.emplace_back(1);//min filament_id is 1
}
}
m_first_extruder_id = m_cluster_map_filaments[0];
}
void ObjColorPanel::set_layout_callback(LayoutChanggeCallback callback) {
m_layout_callback = callback;
}
void ObjColorPanel::do_layout_callback() {
if (m_layout_callback) {
m_layout_callback();
}
}
wxBoxSizer *ObjColorPanel::create_approximate_match_btn_sizer(wxWindow *parent)
{
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
m_quick_approximate_match_btn = new Button(parent, _L("Color match"));
m_quick_approximate_match_btn->SetToolTip(_L("Approximate color matching."));
m_quick_approximate_match_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
m_quick_approximate_match_btn->SetFocus();
btn_sizer->Add(m_quick_approximate_match_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
m_quick_approximate_match_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
deal_approximate_match_btn();
deal_thumbnail();
});
return btn_sizer;
}
wxBoxSizer *ObjColorPanel::create_add_btn_sizer(wxWindow *parent)
{
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
m_quick_add_btn = new Button(parent, _L("Append"));
m_quick_add_btn->SetToolTip(_L("Append to existing filaments"));
auto cur_btn = m_quick_add_btn;
cur_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
cur_btn->SetFocus();
btn_sizer->Add(cur_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
cur_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
deal_add_btn();
deal_thumbnail();
});
m_quick_add_btn->Enable(m_semm); // only SEMM printer can add more colors
return btn_sizer;
}
wxBoxSizer *ObjColorPanel::create_reset_btn_sizer(wxWindow *parent)
{
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
m_quick_reset_btn = new Button(parent, _L("Reset"));
m_quick_reset_btn->SetToolTip(_L("Reset mapped extruders."));
auto cur_btn = m_quick_reset_btn;
cur_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
cur_btn->SetFocus();
btn_sizer->Add(cur_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
cur_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
deal_reset_btn();
deal_thumbnail();
});
return btn_sizer;
}
wxBoxSizer *ObjColorPanel::create_extruder_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour &color)
{
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
wxButton *icon = new wxButton(parent, wxID_ANY, {}, wxDefaultPosition, FromDIP(wxSize(20,20)), wxBORDER_NONE | wxBU_AUTODRAW);
icon->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(id + 1), FromDIP(20), FromDIP(20)));
icon->SetCanFocus(false);
#ifdef __WXGTK__
RemoveButtonBorder(icon);
#endif
m_extruder_icon_list.emplace_back(icon);
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
//icon_sizer->AddSpacer(FromDIP(5));
return icon_sizer;
}
std::string ObjColorPanel::get_color_str(const wxColour &color) {
std::string str = ("R:" + std::to_string(color.Red()) +
std::string(" G:") + std::to_string(color.Green()) +
std::string(" B:") + std::to_string(color.Blue()) +
std::string(" A:") + std::to_string(color.Alpha()));
return str;
}
ComboBox *ObjColorPanel::CreateEditorCtrl(wxWindow *parent, int id) // wxRect labelRect,, const wxVariant &value
{
std::vector<wxBitmap *> icons = get_extruder_color_icons();
const double em = Slic3r::GUI::wxGetApp().em_unit();
bool thin_icon = false;
const int icon_width = lround((thin_icon ? 2 : 4.4) * em);
const int icon_height = lround(2 * em);
m_combox_icon_width = icon_width;
m_combox_icon_height = icon_height;
icons.insert(icons.begin(), get_extruder_color_icon(g_undefined_color_in_obj.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(-1), icon_width, icon_height));
if (icons.empty())
return nullptr;
::ComboBox *c_editor = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr,
wxCB_READONLY | CB_NO_DROP_ICON | CB_NO_TEXT);
c_editor->SetMinSize(wxSize(icon_width + FromDIP(8), -1)); // match size with bitmap
c_editor->SetMaxSize(wxSize(icon_width + FromDIP(8), -1)); // match size with bitmap
c_editor->GetDropDown().SetUseContentWidth(false);
for (size_t i = 0; i < icons.size(); i++) {
c_editor->Append(wxString::Format("%d", i), *icons[i]);
if (i == 0) {
c_editor->SetItemTooltip(i, g_undefined_color_in_obj.GetAsString(wxC2S_HTML_SYNTAX));
} else {
c_editor->SetItemTooltip(i, m_colours[i-1].GetAsString(wxC2S_HTML_SYNTAX));
}
}
c_editor->SetSelection(0);
c_editor->SetName(wxString::Format("%d", id));
c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
auto *com_box = static_cast<ComboBox *>(evt.GetEventObject());
int i = atoi(com_box->GetName().c_str());
if (i < m_cluster_map_filaments.size()) {
m_cluster_map_filaments[i] = com_box->GetSelection();
m_new_add_colors[i] = com_box->GetItemTooltip(com_box->GetSelection());
deal_thumbnail();
}
evt.StopPropagation();
});
return c_editor;
}
void ObjColorPanel::deal_approximate_match_btn()
{
m_warning_text->SetLabelText("");
if (m_result_icon_list.size() == 0) { return; }
auto map_count = m_result_icon_list[0]->bitmap_combox->GetCount() -1;
if (map_count < 1) { return; }
for (size_t i = 0; i < m_cluster_colours.size(); i++) {
auto c = m_cluster_colours[i];
std::vector<ColorDistValue> color_dists;
color_dists.resize(map_count);
for (size_t j = 0; j < map_count; j++) {
auto tip_color = m_result_icon_list[0]->bitmap_combox->GetItemTooltip(j+1);
wxColour candidate_c(tip_color);
color_dists[j].distance = calc_color_distance(c, candidate_c);
color_dists[j].id = j + 1;
}
std::sort(color_dists.begin(), color_dists.end(), [](ColorDistValue &a, ColorDistValue& b) {
return a.distance < b.distance;
});
auto new_index= color_dists[0].id;
m_result_icon_list[i]->bitmap_combox->SetSelection(new_index);
m_new_add_colors[i] = m_result_icon_list[i]->bitmap_combox->GetItemTooltip(new_index);
m_cluster_map_filaments[i] = new_index;
}
}
void ObjColorPanel::show_sizer(wxSizer *sizer, bool show)
{
wxSizerItemList items = sizer->GetChildren();
for (wxSizerItemList::iterator it = items.begin(); it != items.end(); ++it) {
wxSizerItem *item = *it;
if (wxWindow *window = item->GetWindow()) {
window->Show(show);
}
if (wxSizer *son_sizer = item->GetSizer()) {
show_sizer(son_sizer, show);
}
}
}
void ObjColorPanel::draw_new_table()
{
auto cluster_count = m_cluster_colours.size();
auto col = 3;
auto row = cluster_count / col;
auto remainder = cluster_count % col;
if (remainder > 0) {
row++;
}
int old_row = 0;
bool first_draw = false;
if (m_new_grid_sizer) {
old_row = m_new_grid_sizer->GetRows();
m_new_grid_sizer->SetRows(row);
}
else {
first_draw = true;
m_new_grid_sizer = new wxGridSizer(row, 1, 1, 3); //(int rows, int cols, int vgap, int hgap );
m_scrolledWindow->SetSizer(m_new_grid_sizer);
}
if (!first_draw) {
for (size_t i = old_row; i < row; i++) { show_sizer(m_row_sizer_list[i], true); }
for (size_t i = row; i < old_row; i++) { show_sizer(m_row_sizer_list[i], false); }
for (size_t i = 0; i < cluster_count; i++) { show_sizer(m_row_col_boxsizer_list[i], true); }
for (size_t i = cluster_count; i < m_color_num_recommend; i++) { show_sizer(m_row_col_boxsizer_list[i], false); }
for (size_t ii = 0; ii < row; ii++) {
for (size_t j = 0; j < col; j++) {
auto id = ii * col + j;
if (id >= cluster_count) {
break;
}
auto color = m_cluster_colours[id];
m_color_cluster_icon_list[id]->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), "", FromDIP(16), FromDIP(16)));
}
}
}
else {//first draw
for (size_t ii = 0; ii < row; ii++) {
wxPanel *row_panel = new wxPanel(m_scrolledWindow);
//row_panel->SetBackgroundColour(ii % 2 == 0 ? *wxWHITE : wxColour(238, 238, 238));
auto row_sizer = new wxGridSizer(1, col, 1, 1);
row_panel->SetSizer(row_sizer);
row_panel->SetMinSize(wxSize(FromDIP(PANEL_WIDTH), -1));
row_panel->SetMaxSize(wxSize(FromDIP(PANEL_WIDTH), -1));
for (size_t j = 0; j < col; j++) {
auto id = ii * col + j;
if (id >= cluster_count) {
break;
}
auto cluster_color_icon_sizer = create_color_icon_map_rgba_sizer(row_panel, id, m_cluster_colours[id]);
m_row_col_boxsizer_list.emplace_back(cluster_color_icon_sizer);
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, 0);
}
m_row_sizer_list.emplace_back(row_sizer);
m_new_grid_sizer->Add(row_panel, 0, wxALIGN_LEFT | wxALL, FromDIP(HEADER_BORDER));
}
}
m_new_grid_sizer->Layout();
auto height = m_new_grid_sizer->GetMinSize().GetY();
if (row <= 4 || height < FromDIP(185)) {
m_scrolledWindow->SetMinSize(wxSize(-1, height));
} else {
m_scrolledWindow->SetMinSize(wxSize(-1, FromDIP(185)));
m_scrolledWindow->SetMaxSize(wxSize(-1, FromDIP(185)));
}
m_scrolledWindow->FitInside();
if (!first_draw) {
do_layout_callback();
}
}
void ObjColorPanel::update_new_add_final_colors()
{
m_new_add_final_colors = m_new_add_colors;
if (!m_cluster_map_filaments.empty()) {
m_max_filament_index = *std::max_element(m_cluster_map_filaments.begin(), m_cluster_map_filaments.end());
} else {
m_max_filament_index = 0;
}
if (m_max_filament_index <= m_colours.size()) { // Fix 20240904
m_new_add_final_colors.clear();
}
else {
m_new_add_final_colors.resize(m_max_filament_index - m_colours.size());
for (int ii = m_colours.size() ; ii < m_max_filament_index; ii++) {
for (int j = 0; j < m_cluster_map_filaments.size(); j++) {
if (m_cluster_map_filaments[j] == (ii+ 1) && j < m_new_add_colors.size()) {
auto index = ii - m_colours.size();
if (index < m_new_add_final_colors.size()) {
m_new_add_final_colors[index] = m_new_add_colors[j];
}
}
}
}
}
if (m_new_add_final_colors.size() > 0) {
m_is_add_filament = true;
}
}
void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui)
{
if (m_last_cluster_number == cluster_number) {
return;
}
wxBusyCursor cursor;
m_last_cluster_number = cluster_number;
obj_color_deal_algo(m_input_colors, m_cluster_colors_from_algo, m_cluster_labels_from_algo, cluster_number,g_max_color);
m_cluster_colours.clear();
m_cluster_colours.reserve(m_cluster_colors_from_algo.size());
for (size_t i = 0; i < m_cluster_colors_from_algo.size(); i++) {
m_cluster_colours.emplace_back(convert_to_wxColour(m_cluster_colors_from_algo[i]));
}
if (m_cluster_colours.size() == 0) {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",m_cluster_colours.size() = 0\n";
return;
}
m_cluster_map_filaments.resize(m_cluster_colors_from_algo.size());
m_new_add_colors.resize(m_cluster_map_filaments.size());
m_color_cluster_num_by_algo = m_cluster_colors_from_algo.size();
if (cluster_number == -1) {
m_color_num_recommend = m_color_cluster_num_by_algo;
}
//redraw ui
if (redraw_ui) {
deal_reset_btn();
draw_new_table();
deal_default_strategy();
deal_thumbnail();
}
}
void ObjColorPanel::deal_default_strategy()
{
bool is_exceed = deal_add_btn();
if (!is_exceed) {
deal_approximate_match_btn();
}
m_warning_text->SetLabelText(_L("Note") + ": " + _L("The color has been selected, you can choose OK \n to continue or manually adjust it."));
}
void ObjColorPanel::deal_thumbnail() {
update_filament_ids();
// generate model volume
if (m_obj_in_out.deal_vertex_color) {
if (m_obj_in_out.filament_ids.size() > 0) {
m_deal_thumbnail_flag = Model::obj_import_vertex_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model);
}
} else {
if (m_obj_in_out.filament_ids.size() > 0) {
m_deal_thumbnail_flag = Model::obj_import_face_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model);
}
}
generate_thumbnail();
}
void ObjColorPanel::generate_thumbnail()
{
if (m_deal_thumbnail_flag && m_obj_in_out.model->objects.size() == 1) {
std::vector<Slic3r::ColorRGBA> colors = GUI::wxGetApp().plater()->get_extruders_colors();
for (size_t i = 0; i < m_new_add_colors.size(); i++) {
Slic3r::ColorRGBA temp_color;
temp_color[0] = m_new_add_colors[i].Red() / 255.f;
temp_color[1] = m_new_add_colors[i].Green() / 255.f;
temp_color[2] = m_new_add_colors[i].Blue() / 255.f;
temp_color[3] = m_new_add_colors[i].Alpha() / 255.f;
colors.emplace_back(temp_color);
}
auto mo = m_obj_in_out.model->objects[0];
wxGetApp().plater()->update_obj_preview_thumbnail(mo, 0, 0, colors, (int) m_camera_view_angle_type);
// get thumbnail image
PartPlate *plate = wxGetApp().plater()->get_partplate_list().get_plate(0);
auto & data = plate->obj_preview_thumbnail_data;
if (data.is_valid()) {
wxImage image(data.width, data.height);
image.InitAlpha();
for (unsigned int r = 0; r < data.height; ++r) {
unsigned int rr = (data.height - 1 - r) * data.width;
for (unsigned int c = 0; c < data.width; ++c) {
unsigned char *px = (unsigned char *) data.pixels.data() + 4 * (rr + c);
image.SetRGB((int) c, (int) r, px[0], px[1], px[2]);
image.SetAlpha((int) c, (int) r, px[3]);
}
}
image = image.Rescale(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH));
m_image_button->SetBitmap(image);
}
}
else {
#ifdef _WIN32
__debugbreak();
#endif
}
}
void ObjColorPanel::set_view_angle_type(int value)
{
if (value >= 0) {
m_camera_view_angle_type = (Slic3r::GUI::Camera::ViewAngleType) value;
generate_thumbnail();
}
}
void ObjColorPanel::clear_instance_and_revert_offset()
{
auto mo = m_obj_in_out.model->objects[0];
mo->clear_instances();
auto mv = mo->volumes[0];
auto box = mo->bounding_box_exact();
if (!m_thumbnail_offset.isApprox(Slic3r::Vec3d::Zero())) {
mv->translate(-m_thumbnail_offset);
}
}
bool ObjColorPanel::do_show(bool show) {
if (show) {
return true;
} else {
return false;
}
}
bool ObjColorPanel::deal_add_btn()
{
if (!m_semm) { return false; }// only SEMM printer can add more colors
if (m_colours.size() > g_max_color) { return false; }
deal_reset_btn();
std::vector<wxBitmap *> new_icons;
auto new_color_size = m_cluster_colors_from_algo.size();
new_icons.reserve(new_color_size);
m_new_add_colors.clear();
m_new_add_colors.reserve(new_color_size);
int new_index = m_colours.size() + 1;
bool is_exceed = false;
for (size_t i = 0; i < new_color_size; i++) {
if (m_colours.size() + new_icons.size() >= g_max_color) {
is_exceed = true;
break;
}
wxColour cur_color = convert_to_wxColour(m_cluster_colors_from_algo[i]);
m_new_add_colors.emplace_back(cur_color);
new_icons.emplace_back(get_extruder_color_icon(cur_color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(),
std::to_string(new_index), m_combox_icon_width, m_combox_icon_height));
new_index++;
}
new_index = m_colours.size() + 1;
for (size_t i = 0; i < m_result_icon_list.size(); i++) {
auto item = m_result_icon_list[i];
for (size_t k = 0; k < new_icons.size(); k++) {
item->bitmap_combox->Append(wxString::Format("%d", item->bitmap_combox->GetCount()), *new_icons[k]);
item->bitmap_combox->SetItemTooltip(item->bitmap_combox->GetCount() -1,m_new_add_colors[k].GetAsString(wxC2S_HTML_SYNTAX));
}
item->bitmap_combox->SetSelection(new_index);
m_cluster_map_filaments[i] = new_index;
new_index++;
}
if (is_exceed) {
deal_approximate_match_btn();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",Waring:The count of newly added and \n current extruders exceeds 32.";
return true;
}
return false;
}
void ObjColorPanel::deal_reset_btn()
{
for (auto item : m_result_icon_list) {
// delete redundant bitmap
while (item->bitmap_combox->GetCount() > m_colours.size()+ 1) {
item->bitmap_combox->DeleteOneItem(item->bitmap_combox->GetCount() - 1);
}
item->bitmap_combox->SetSelection(0);
}
for (int i = 0; i < m_new_add_colors.size(); i++) {
m_new_add_colors[i] = g_undefined_color_in_obj;
}
m_warning_text->SetLabelText("");
}
wxBoxSizer *ObjColorPanel::create_color_icon_map_rgba_sizer(wxWindow *parent, int id, const wxColour &color)
{
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
//icon_sizer->AddSpacer(FromDIP(40));
wxButton *icon = new wxButton(parent, wxID_ANY, {}, wxDefaultPosition, FromDIP(wxSize(20,20)), wxBORDER_NONE | wxBU_AUTODRAW);
icon->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), "", FromDIP(20), FromDIP(20)));
icon->SetCanFocus(false);
#ifdef __WXGTK__
RemoveButtonBorder(icon);
#endif
m_color_cluster_icon_list.emplace_back(icon);
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
icon_sizer->AddSpacer(FromDIP(10));
wxStaticText *map_text = new wxStaticText(parent, wxID_ANY, _L(u8"—> "));
map_text->SetFont(Label::Head_12);
icon_sizer->Add(map_text, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
for (size_t i = m_result_icon_list.size(); i < id + 1; i++) {
m_result_icon_list.emplace_back(new ButtonState());
}
m_result_icon_list[id]->bitmap_combox = CreateEditorCtrl(parent, id);
icon_sizer->Add(m_result_icon_list[id]->bitmap_combox, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
return icon_sizer;
}
-136
View File
@@ -1,136 +0,0 @@
#ifndef _OBJ_COLOR_DIALOG_H_
#define _OBJ_COLOR_DIALOG_H_
#include "GUI_Utils.hpp"
#include "Camera.hpp"
#include "GuiColor.hpp"
#include "libslic3r/Format/OBJ.hpp"
#include <wx/panel.h>
#include <vector>
#include <string>
#include <functional>
#include <wx/colour.h>
#include <wx/scrolwin.h>
#include "libslic3r/Color.hpp"
#include "libslic3r/Point.hpp"
#include <unordered_map>
#include <wx/sizer.h>
#include <wx/spinctrl.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/checkbox.h>
#include <wx/msgdlg.h>
#include "Widgets/SpinInput.hpp"
class Button;
class Label;
class ComboBox;
class ObjColorPanel : public wxPanel
{
public:
// BBS
ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, bool semm);
~ObjColorPanel();
void msw_rescale();
bool is_ok();
void send_new_filament_to_ui();
void cancel_paint_color();
void update_filament_ids();
struct ButtonState
{
ComboBox* bitmap_combox{nullptr};
bool is_map{false};//int id{0};
};
typedef std::function<void()> LayoutChanggeCallback;
void set_layout_callback(LayoutChanggeCallback);
void do_layout_callback();
bool do_show(bool show);
void clear_instance_and_revert_offset();
private:
wxBoxSizer *create_approximate_match_btn_sizer(wxWindow *parent);
wxBoxSizer *create_add_btn_sizer(wxWindow *parent);
wxBoxSizer *create_reset_btn_sizer(wxWindow *parent);
wxBoxSizer *create_extruder_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour& color);
std::string get_color_str(const wxColour &color);
wxBoxSizer *create_color_icon_map_rgba_sizer(wxWindow *parent, int id, const wxColour &color);//for display map
ComboBox* CreateEditorCtrl(wxWindow *parent,int id);
void draw_new_table();
void update_new_add_final_colors();
void show_sizer(wxSizer *sizer, bool show);
void deal_approximate_match_btn();
bool deal_add_btn();
void deal_reset_btn();
void deal_algo(char cluster_number,bool redraw_ui =false);
void deal_default_strategy();
void deal_thumbnail();
void generate_thumbnail();
void set_view_angle_type(int);
private:
//view ui
Slic3r::ObjDialogInOut & m_obj_in_out;
Slic3r::GUI::Camera::ViewAngleType m_camera_view_angle_type{Slic3r::GUI::Camera::ViewAngleType::Iso};
wxPanel * m_page_simple = nullptr;
wxBoxSizer * m_sizer = nullptr;
wxBoxSizer * m_sizer_simple = nullptr;
wxBoxSizer * m_sizer_current_filaments = nullptr;
SpinInput * m_color_cluster_num_by_user_ebox{nullptr};
wxStaticText * m_warning_text{nullptr};
wxGridSizer * m_new_grid_sizer{nullptr};
wxScrolledWindow * m_scrolledWindow{nullptr};
Button * m_quick_approximate_match_btn{nullptr};
Button * m_quick_add_btn{nullptr};
Button * m_quick_reset_btn{nullptr};
std::vector<wxButton*> m_extruder_icon_list;
std::vector<wxButton*> m_color_cluster_icon_list;//need modeify
std::vector<wxStaticText*> m_color_cluster_text_list;//need modeify
std::vector<wxGridSizer*> m_row_sizer_list; // control show or not
std::vector<wxBoxSizer *> m_row_col_boxsizer_list;
std::vector<ButtonState*> m_result_icon_list;
int m_last_cluster_num{-1};
int m_combox_icon_width;
int m_combox_icon_height;
wxButton * m_image_button = nullptr;
LayoutChanggeCallback m_layout_callback;
//data
char m_last_cluster_number{-2};
std::vector<Slic3r::RGBA>& m_input_colors;
int m_color_num_recommend{0};
int m_color_cluster_num_by_algo{0};
int m_input_colors_size{0};
bool m_semm; // only SEMM printer can add more colors
std::vector<wxColour> m_colours;//from project and show right
std::vector<int> m_cluster_map_filaments;//show middle
int m_max_filament_index = 0;
std::vector<wxColour> m_cluster_colours;//from_algo and show left
bool m_deal_thumbnail_flag{false};
std::vector<wxColour> m_new_add_colors;
std::vector<wxColour> m_new_add_final_colors;
//algo result
std::vector<Slic3r::RGBA> m_cluster_colors_from_algo;
std::vector<int> m_cluster_labels_from_algo;
//result
bool m_is_add_filament{false};
unsigned char& m_first_extruder_id;
std::vector<unsigned char> &m_filament_ids;
Slic3r::Vec3d m_thumbnail_offset;
};
class ObjColorDialog : public Slic3r::GUI::DPIDialog
{
public:
ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, bool semm);
wxBoxSizer *create_btn_sizer(long flags, bool exist_error);
void on_dpi_changed(const wxRect &suggested_rect) override;
void update_layout();
bool Show(bool show) override;
private:
ObjColorPanel* m_panel_ObjColor = nullptr;
wxBoxSizer * m_main_sizer = nullptr;
wxBoxSizer * m_buttons_sizer = nullptr;
std::unordered_map<int, Button *> m_button_list;
};
#endif // _WIPE_TOWER_DIALOG_H_
+119 -22
View File
@@ -226,6 +226,7 @@
#include "SelectMachine.hpp"
#include "SendMultiMachinePage.hpp"
#include "SendToPrinter.hpp"
#include "PublishDialog.hpp"
#include "ConfigWizard.hpp"
#include "SyncAmsInfoDialog.hpp"
#include "../Utils/ASCIIFolding.hpp"
@@ -272,7 +273,6 @@
#include "ColorDecomposeSupport.hpp"
#include "FilamentBitmapUtils.hpp"
#include "libslic3r/FilamentMixer.hpp"
#include "ObjColorDialog.hpp"
#include "libslic3r/CustomGCode.hpp"
#include "libslic3r/Platform.hpp"
@@ -330,6 +330,7 @@ wxDEFINE_EVENT(EVT_EXPORT_BEGAN, wxCommandEvent);
wxDEFINE_EVENT(EVT_EXPORT_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_IMPORT_MODEL_ID, wxCommandEvent);
wxDEFINE_EVENT(EVT_DOWNLOAD_PROJECT, wxCommandEvent);
wxDEFINE_EVENT(EVT_PUBLISH, wxCommandEvent);
wxDEFINE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent);
wxDEFINE_EVENT(EVT_OPEN_FILAMENT_MAP_SETTINGS_DIALOG, wxCommandEvent);
// BBS: backup & restore
@@ -337,6 +338,7 @@ wxDEFINE_EVENT(EVT_RESTORE_PROJECT, wxCommandEvent);
wxDEFINE_EVENT(EVT_PRINT_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_SEND_CALIBRATION_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_SEND_FINISHED, wxCommandEvent);
wxDEFINE_EVENT(EVT_PUBLISH_FINISHED, wxCommandEvent);
//BBS: repair model
wxDEFINE_EVENT(EVT_REPAIR_MODEL, wxCommandEvent);
wxDEFINE_EVENT(EVT_FILAMENT_COLOR_CHANGED, wxCommandEvent);
@@ -7143,6 +7145,7 @@ struct Plater::priv
SelectMachineDialog* m_select_machine_dlg = nullptr;
SendMultiMachinePage* m_send_multi_dlg = nullptr;
SendToPrinterDialog* m_send_to_sdcard_dlg = nullptr;
PublishDialog *m_publish_dlg = nullptr;
// Session-level stash of the last published selection. Written on publish and on
// loading a published 3MF; read when the Publish dialog is opened.
@@ -7196,6 +7199,7 @@ struct Plater::priv
std::string m_broken_shown_sig;
bool auto_reslice_pending {false};
bool auto_reslice_after_cancel {false};
bool m_is_publishing {false};
int m_is_RightClickInLeftUI{-1};
int m_cur_slice_plate;
//BBS: m_slice_all in .gcode.3mf file case, set true when slice all
@@ -7599,6 +7603,7 @@ struct Plater::priv
void on_action_open_project(SimpleEvent&);
void on_action_slice_plate(SimpleEvent&);
void on_action_slice_all(SimpleEvent&);
void on_action_publish(wxCommandEvent &evt);
void on_action_print_plate(SimpleEvent&);
void open_machine_select_dialog(int plate_idx, PrintFromType print_type = PrintFromType::FROM_NORMAL);
void on_action_print_all(SimpleEvent&);
@@ -7616,6 +7621,8 @@ struct Plater::priv
void on_3dcanvas_mouse_dragging_finished(SimpleEvent&);
//void show_action_buttons(const bool is_ready_to_slice) const;
bool show_publish_dlg(bool show = true);
void update_publish_dialog_status(wxString &msg, int percent = -1);
void on_action_print_plate_from_sdcard(SimpleEvent&);
void on_tab_selection_changing(wxBookCtrlEvent&);
@@ -7865,6 +7872,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
background_process.set_export_began_event(EVT_EXPORT_BEGAN);
background_process.set_export_finished_event(EVT_EXPORT_FINISHED);
this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
this->q->Bind(EVT_PUBLISH, &priv::on_action_publish, this);
this->q->Bind(EVT_REPAIR_MODEL, &priv::on_repair_model, this);
this->q->Bind(EVT_FILAMENT_COLOR_CHANGED, &priv::on_filament_color_changed, this);
this->q->Bind(EVT_INSTALL_PLUGIN_NETWORKING, &priv::install_network_plugin, this);
@@ -8217,6 +8225,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
q->Bind(EVT_PRINT_FINISHED, [q](wxCommandEvent& evt) { q->print_job_finished(evt); });
q->Bind(EVT_SEND_CALIBRATION_FINISHED, [q](wxCommandEvent& evt) { q->send_calibration_job_finished(evt); });
q->Bind(EVT_SEND_FINISHED, [q](wxCommandEvent& evt) { q->send_job_finished(evt); });
q->Bind(EVT_PUBLISH_FINISHED, [q](wxCommandEvent& evt) { q->publish_job_finished(evt);});
q->Bind(EVT_OPEN_PLATESETTINGSDIALOG, [q](wxCommandEvent& evt) { q->open_platesettings_dialog(evt);});
q->Bind(EVT_OPEN_FILAMENT_MAP_SETTINGS_DIALOG, [q](wxCommandEvent &evt) { q->open_filament_map_setting_dialog(evt); });
//q->Bind(EVT_GLVIEWTOOLBAR_ASSEMBLE, [q](SimpleEvent&) { q->select_view_3D("Assemble"); });
@@ -9765,16 +9774,6 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
bool is_xxx;
Semver file_version;
//ObjImportColorFn obj_color_fun=nullptr;
auto obj_color_fun = [&path](ObjDialogInOut &in_out) {
if (!boost::iends_with(path.string(), ".obj")) { return; }
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
ObjColorDialog color_dlg(nullptr, in_out, extruder_colours, Sidebar::should_show_SEMM_buttons());
if (color_dlg.ShowModal() != wxID_OK) {
in_out.filament_ids.clear();
}
};
if (boost::iends_with(path.string(), ".stp") ||
boost::iends_with(path.string(), ".step")) {
double linear = string_to_double_decimal_point(wxGetApp().app_config->get("linear_deflection"));
@@ -9841,7 +9840,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
cont = dlg.Update(progress_percent, msg);
cancel = !cont;
},
nullptr, 0, obj_color_fun);
nullptr, 0);
}
if (designer_model_id.empty() && boost::algorithm::iends_with(path.string(), ".stl")) {
@@ -12133,14 +12132,6 @@ void Plater::priv::reload_from_disk()
// load one file at a time
for (size_t i = 0; i < input_paths.size(); ++i) {
const auto& path = input_paths[i].string();
auto obj_color_fun = [&path](ObjDialogInOut &in_out) {
if (!boost::iends_with(path, ".obj")) { return; }
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
ObjColorDialog color_dlg(nullptr, in_out, extruder_colours, Sidebar::should_show_SEMM_buttons());
if (color_dlg.ShowModal() != wxID_OK) {
in_out.filament_ids.clear();
}
};
wxBusyCursor wait;
wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas());
@@ -12160,7 +12151,7 @@ void Plater::priv::reload_from_disk()
bool is_split = wxGetApp().app_config->get_bool("is_split_compound");
new_model = Model::read_from_step(path, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, nullptr, nullptr, nullptr, linear, angle, is_split);
}else {
new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, &plate_data, &project_presets, nullptr, nullptr, nullptr, nullptr, nullptr, 0, obj_color_fun);
new_model = Model::read_from_file(path, nullptr, nullptr, LoadStrategy::AddDefaultInstances | LoadStrategy::LoadModel, &plate_data, &project_presets, nullptr, nullptr, nullptr, nullptr, nullptr, 0);
}
@@ -13351,6 +13342,11 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
show_action_buttons(true);*/
ready_to_slice = true;
//this->main_frame->update_slice_print_status(MainFrame::eEventSliceUpdate, true, true);
//BBS
if (m_is_publishing) {
m_publish_dlg->cancel();
}
} else {
if((ready_to_slice) || (wxGetApp().get_mode() == comSimple)) {
//this means the current plate is not the slicing plate
@@ -13392,6 +13388,15 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
exporting_status = ExportingStatus::NOT_EXPORTING;
// BBS stop publishing if error occur
//if (m_is_publishing) {
// GCodeProcessorResult *gcode_result = background_process.get_current_gcode_result();
// m_publish_dlg->UpdateStatus(_L("Error occurred during slicing"), -1, false);
// // if toolpath is outside
// if (!gcode_result || gcode_result->toolpath_outside) {
// m_is_publishing = false;
// }
//}
if (is_finished)
@@ -13400,6 +13405,16 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
m_is_slicing = false;
this->preview->reload_print(false);
q->mark_plate_toolbar_image_dirty();
/* BBS if in publishing progress */
if (m_is_publishing) {
if (m_publish_dlg && !m_publish_dlg->was_cancelled()) {
if (m_publish_dlg->IsShown()) {
q->publish_project();
} else {
m_is_publishing = false;
}
}
}
q->SetDropTarget(new PlaterDropTarget(*main_frame, *q));
}
else
@@ -13418,6 +13433,13 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
//not the last plate
update_fff_scene_only_shells();
q->Thaw();
if (m_is_publishing) {
if (m_publish_dlg && !m_publish_dlg->was_cancelled()) {
wxString msg = wxString::Format(_L("Slicing Plate %d"), m_cur_slice_plate + 1);
int percent = 70 * m_cur_slice_plate / partplate_list.get_plate_count();
m_publish_dlg->UpdateStatus(msg, percent, false);
}
}
}
if (auto_reslice_after_cancel) {
auto_reslice_after_cancel = false;
@@ -13499,12 +13521,40 @@ void Plater::priv::on_action_slice_all(SimpleEvent&)
//select plate
q->select_plate(m_cur_slice_plate);
q->reslice();
q->select_view_3D("Preview");
if (!m_is_publishing)
q->select_view_3D("Preview");
//BBS: wish to select all plates stats item
preview->get_canvas3d()->_update_select_plate_toolbar_stats_item(true);
}
}
void Plater::priv::on_action_publish(wxCommandEvent &event)
{
if (q != nullptr) {
if (event.GetInt() == EVT_PUBLISHING_START) {
// update by background slicing process
if (process_completed_with_error >= 0) {
wxString msg = _L("Please resolve the slicing errors and publish again.");
this->m_publish_dlg->UpdateStatus(msg, false);
return;
}
m_is_publishing = true;
// if slicing is ready publish project, else slicing first
if (partplate_list.is_all_slice_results_valid()) {
q->publish_project();
} else {
BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":received slice project in background event\n";
SimpleEvent evt = SimpleEvent(EVT_GLTOOLBAR_SLICE_ALL);
this->on_action_slice_all(evt);
}
} else {
m_is_publishing = false;
show_publish_dlg(false);
}
}
}
void Plater::priv::on_action_print_plate(SimpleEvent&)
{
if (q != nullptr) {
@@ -14280,6 +14330,11 @@ int Plater::get_send_finished_event()
return EVT_SEND_FINISHED;
}
int Plater::get_publish_finished_event()
{
return EVT_PUBLISH_FINISHED;
}
void Plater::priv::set_current_canvas_as_dirty()
{
if (current_panel == view3D)
@@ -14688,6 +14743,31 @@ bool Plater::priv::can_reload_from_disk() const
return !paths.empty();
}
void Plater::priv::update_publish_dialog_status(wxString &msg, int percent)
{
if (m_publish_dlg)
m_publish_dlg->UpdateStatus(msg, percent);
}
bool Plater::priv::show_publish_dlg(bool show)
{
if (q != nullptr) { BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << ":recevied publish event\n"; }
if (!m_publish_dlg) m_publish_dlg = new PublishDialog(q);
if (show) {
m_publish_dlg->reset();
m_publish_dlg->start_slicing();
//m_publish_dlg->Show();
m_publish_dlg->ShowModal();
} else {
m_publish_dlg->EndModal(wxID_OK);
//cancel the slicing
if (this->background_process.running())
this->background_process.stop();
}
return true;
}
//BBS: add bed exclude area
void Plater::priv::set_bed_shape(const Pointfs &shape,
const Pointfs &exclude_areas,
@@ -19816,6 +19896,11 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
return ret;
}
void Plater::publish_project()
{
return;
}
void Plater::reload_from_disk()
{
@@ -20458,6 +20543,13 @@ void Plater::send_job_finished(wxCommandEvent& evt)
// curr_monitor->get_tabpanel()->ChangeSelection(MonitorPanel::PrinterTab::PT_STATUS);
}
void Plater::publish_job_finished(wxCommandEvent &evt)
{
p->m_publish_dlg->EndModal(wxID_OK);
// GUI::wxGetApp().load_url(evt.GetString());
//GUI::wxGetApp().open_publish_page_dialog(evt.GetString());
}
// Called when the Eject button is pressed.
void Plater::eject_drive()
{
@@ -22755,6 +22847,11 @@ void Plater::show_object_info()
notify_manager->bbl_show_objectsinfo_notification(info_text, non_manifold_edges > 0, !(p->current_panel == p->view3D));
}
bool Plater::show_publish_dialog(bool show)
{
return p->show_publish_dlg(show);
}
void Plater::post_process_string_object_exception(StringObjectException &err)
{
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
+8
View File
@@ -116,8 +116,12 @@ enum class ActionButtonType : int;
// (Sidebar::priv::m_menu_filament_id) rather than an explicit index.
inline constexpr int kSidebarContextMenuFilamentId = -2;
#define EVT_PUBLISHING_START 1
#define EVT_PUBLISHING_STOP 2
//BBS: add EVT_SLICING_UPDATE declare here
wxDECLARE_EVENT(EVT_SLICING_UPDATE, Slic3r::SlicingStatusEvent);
wxDECLARE_EVENT(EVT_PUBLISH, wxCommandEvent);
wxDECLARE_EVENT(EVT_OPEN_PLATESETTINGSDIALOG, wxCommandEvent);
// Explanation of int param
@@ -567,6 +571,7 @@ public:
int export_3mf(const boost::filesystem::path& output_path = boost::filesystem::path(), SaveStrategy strategy = SaveStrategy::Default, int export_plate_idx = -1, Export3mfProgressFn proFn = nullptr);
//BBS
void publish_project();
void reload_from_disk();
void replace_with_stl();
@@ -601,6 +606,7 @@ public:
void send_calibration_job_finished(wxCommandEvent &evt);
void print_job_finished(wxCommandEvent &evt);
void send_job_finished(wxCommandEvent& evt);
void publish_job_finished(wxCommandEvent& evt);
void open_platesettings_dialog(wxCommandEvent& evt);
void open_filament_map_setting_dialog(wxCommandEvent &evt);
void on_change_color_mode(SimpleEvent& evt);
@@ -711,6 +717,7 @@ public:
int get_send_calibration_finished_event();
int get_print_finished_event();
int get_send_finished_event();
int get_publish_finished_event();
void set_current_canvas_as_dirty();
void unbind_canvas_event_handlers();
@@ -835,6 +842,7 @@ public:
//BBS: show object info
void show_object_info();
//BBS
bool show_publish_dialog(bool show = true);
//BBS: post process string object exception strings by warning types
void post_process_string_object_exception(StringObjectException &err);
void update_objects_position_when_select_preset(const std::function<void()> &select_prest);
+270
View File
@@ -0,0 +1,270 @@
#include "PublishDialog.hpp"
#include "GUI_App.hpp"
#include <wx/colour.h>
#include <wx/string.h>
#include "slic3r/GUI/Widgets/AMSItem.hpp"
#include "slic3r/GUI/GUI_Utils.hpp"
#include <wx/intl.h>
#include <wx/gdicmn.h>
#include <wx/toplevel.h>
#include <wx/panel.h>
#include "slic3r/GUI/Widgets/Label.hpp"
#include "slic3r/GUI/Widgets/ProgressBar.hpp"
#include "slic3r/GUI/Widgets/Button.hpp"
#include "slic3r/GUI/Widgets/StateColor.hpp"
#include <utility>
#include <wx/event.h>
#include "slic3r/GUI/Plater.hpp"
#include <wx/wx.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include "wx/evtloop.h"
#include "libslic3r/Model.hpp"
#include "libslic3r/Polygon.hpp"
#include "MainFrame.hpp"
#include "GUI_App.hpp"
static const wxColour TEXT_LIGHT_GRAY = wxColour(107, 107, 107);
namespace Slic3r {
namespace GUI {
static wxString PUBLISH_STEP_STRING[STEP_COUNT] = {
_L("Slice all plates to obtain time and filament estimation"),
_L("Packing project data into 3MF file"),
_L("Uploading 3MF"),
_L("Jump to model publish web page")
};
static wxString NOTE_STRING = _L("Note: The preparation may take several minutes. Please be patient.");
PublishDialog::PublishDialog(Plater *plater)
: DPIDialog(static_cast<wxWindow *>(wxGetApp().mainframe), wxID_ANY, _L("Publish"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
, m_plater(plater)
{
this->SetSize(wxSize(FromDIP(540),FromDIP(400)));
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
wxBoxSizer *top_sizer = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *m_main_sizer = new wxBoxSizer(wxVERTICAL);
m_main_sizer->Add(0, FromDIP(30), 0, wxEXPAND, 0);
m_step_panel = new wxPanel(this, wxID_ANY);
wxBoxSizer *step_sizer = create_publish_step_sizer();
m_step_panel->SetSizer(step_sizer);
m_step_panel->SetBackgroundColour(wxColour(248, 248, 248));
m_main_sizer->Add(m_step_panel, 1, wxEXPAND, 0);
m_main_sizer->Add(0, FromDIP(20), 0, wxEXPAND, 0);
m_text_note = new wxStaticText(this, wxID_ANY, NOTE_STRING, wxDefaultPosition, wxDefaultSize, 0);
m_text_note->SetFont(Label::Body_14);
m_text_note->SetForegroundColour(TEXT_LIGHT_GRAY);
m_text_note->Wrap(-1);
m_main_sizer->Add(m_text_note, 0, wxALL | wxEXPAND, 0);
m_main_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 0);
wxStaticLine *m_staticline = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL);
m_main_sizer->Add(m_staticline, 0, wxALL | wxEXPAND, FromDIP(0));
m_main_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 0);
wxBoxSizer *m_progress_text_sizer = new wxBoxSizer(wxHORIZONTAL);
m_text_progress = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_text_progress->Wrap(-1);
m_text_progress->SetFont(Label::Body_12);
m_text_progress->SetForegroundColour(TEXT_LIGHT_GRAY);
m_progress_text_sizer->Add(FromDIP(20), 0, 0, wxEXPAND | wxALL, 0);
m_progress_text_sizer->Add(m_text_progress, 1, wxALL | wxEXPAND, 0);
m_main_sizer->Add(m_progress_text_sizer, 0, wxALL | wxEXPAND, 0);
wxBoxSizer *m_progress_sizer = new wxBoxSizer(wxHORIZONTAL);
m_progress_sizer->Add(FromDIP(20), 0, 0, wxEXPAND | wxALL, 0);
m_progress = new ProgressBar(this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize);
m_progress->SetHeight(FromDIP(8));
m_progress->SetFont(Label::Head_10);
m_progress_sizer->Add(m_progress, 1, wxALIGN_CENTER_VERTICAL | wxALL, 0);
m_progress_sizer->Add(FromDIP(20), 0, 0, wxEXPAND, 0);
m_btn_cancel = new Button(this, _L("Cancel"));
m_progress_sizer->Add(m_btn_cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5));
StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered),
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Normal));
StateColor text_color(std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Pressed),
std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Hovered),
std::pair<wxColour, int>(TEXT_LIGHT_GRAY, StateColor::Normal));
m_btn_cancel->SetFont(Label::Body_12);
m_btn_cancel->SetBackgroundColor(btn_bg_green);
m_btn_cancel->SetBorderColor(wxColour(0, 150, 136));
m_btn_cancel->SetTextColor(text_color);
m_btn_cancel->SetSize(wxSize(FromDIP(60), FromDIP(20)));
m_btn_cancel->SetMinSize(wxSize(FromDIP(60), FromDIP(20)));
m_btn_cancel->SetCornerRadius(FromDIP(10));
m_progress_sizer->Add(FromDIP(20), 0, 0, wxEXPAND | wxALL, 0);
m_main_sizer->Add(m_progress_sizer, 0, wxEXPAND, FromDIP(0));
wxBoxSizer *m_bottom_sizer;
m_bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
m_bottom_sizer->Add(FromDIP(20), 0, 0, wxEXPAND, 0);
m_text_errors = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0);
m_text_errors->Wrap(-1);
m_text_errors->SetFont(Label::Body_12);
m_text_errors->SetForegroundColour(wxColour(255, 111, 0));
m_bottom_sizer->Add(m_text_errors, 1, wxALL, 0);
m_main_sizer->Add(m_bottom_sizer, 0, wxEXPAND, 0);
m_main_sizer->Add(0, FromDIP(10), 0, wxEXPAND, 0);
top_sizer->Add(FromDIP(30), 0, 0, wxEXPAND, 0);
top_sizer->Add(m_main_sizer, 1, wxALL | wxEXPAND, 0);
top_sizer->Add(FromDIP(30), 0, 0, wxEXPAND, 0);
this->SetSizerAndFit(top_sizer);
this->Layout();
this->Centre(wxBOTH);
m_btn_cancel->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
this->cancel();
});
Bind(wxEVT_CLOSE_WINDOW, &PublishDialog::on_close, this);
wxGetApp().UpdateDlgDarkUI(this);
}
void PublishDialog::cancel()
{
m_was_cancelled = true;
m_btn_cancel->Enable(false);
m_text_progress->SetLabelText(_L("Publish was canceled"));
wxCloseEvent evt;
this->on_close(evt);
}
void PublishDialog::start_slicing()
{
SetPublishStep(PublishStep::STEP_SLICING);
wxCommandEvent *evt = new wxCommandEvent(EVT_PUBLISH);
evt->SetInt(EVT_PUBLISHING_START);
wxQueueEvent(m_plater, evt);
}
bool PublishDialog::UpdateStatus(wxString &msg, int percent, bool yield)
{
if (m_was_cancelled) return false;
if (percent >= 0)
m_progress->SetValue(percent);
m_text_progress->SetLabelText(msg);
if (yield)
wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT);
return true;
}
void PublishDialog::Pulse(wxString &msg, bool &skip)
{
if (!msg.IsEmpty())
m_text_progress->SetLabelText(msg);
wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT);
skip = m_was_cancelled;
}
void PublishDialog::SetPublishStep(PublishStep step, bool yield, int percent)
{
m_publish_steps->SelectItem((int)step);
if (step == PublishStep::STEP_SLICING) {
m_text_progress->SetLabelText(_L("Slicing Plate 1"));
if (percent > 0)
m_progress->SetValue(percent);
else
m_progress->SetValue(0);
} else if (step == PublishStep::STEP_PACKING) {
m_text_progress->SetLabelText(_L("Packing data to 3MF"));
if (percent > 0)
m_progress->SetValue(percent);
else
m_progress->SetValue(70);
} else if (step == PublishStep::STEP_UPLOADING) {
m_text_progress->SetLabelText(_L("Uploading data"));
if (percent > 0)
m_progress->SetValue(percent);
else
m_progress->SetValue(85);
} else if (step == PublishStep::STEP_FILL_INFO) {
m_text_progress->SetLabelText(_L("Jump to webpage"));
m_progress->SetValue(100);
}
if (yield)
wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI | wxEVT_CATEGORY_USER_INPUT);
}
wxBoxSizer *PublishDialog::create_publish_step_sizer()
{
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(FromDIP(30), 0, 0, wxEXPAND, 0);
auto middle_sizer = new wxBoxSizer(wxVERTICAL);
m_publish_steps = new StepIndicator(m_step_panel, wxID_ANY);
StateColor bg_color(std::pair<wxColour, int>(wxColour(248, 248, 248), StateColor::Normal));
m_publish_steps->SetBackgroundColor(bg_color);
m_publish_steps->SetFont(Label::Body_14);
for (int i = 0; i < (int) PublishStep::STEP_PUBLISH_COUNT; i++) {
m_publish_steps->AppendItem(PUBLISH_STEP_STRING[i]);
}
middle_sizer->Add(0, FromDIP(30), 0, wxEXPAND, 0);
middle_sizer->Add(m_publish_steps, 1, wxALL | wxEXPAND, 0);
middle_sizer->Add(0, FromDIP(30), 0, wxEXPAND, 0);
sizer->Add(middle_sizer, 1, wxALL | wxEXPAND, 0);
sizer->Add(FromDIP(30), 0, 0, wxEXPAND, 0);
return sizer;
}
void PublishDialog::on_dpi_changed(const wxRect &suggested_rect)
{
Fit();
Refresh();
}
void PublishDialog::on_close(wxCloseEvent &event)
{
wxCommandEvent *evt = new wxCommandEvent(EVT_PUBLISH);
evt->SetInt(EVT_PUBLISHING_STOP);
wxQueueEvent(m_plater, evt);
}
void PublishDialog::reset()
{
m_btn_cancel->Enable();
m_was_cancelled = false;
SetPublishStep(PublishStep::STEP_SLICING);
m_text_errors->Hide();
}
} // GUI
} // Slic3r
+75
View File
@@ -0,0 +1,75 @@
#ifndef slic3r_PublishDialog_hpp_
#define slic3r_PublishDialog_hpp_
#include "I18N.hpp"
#include "slic3r/GUI/GUI_Utils.hpp"
#include <wx/event.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/panel.h>
#include <wx/gdicmn.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/gauge.h>
#include <wx/button.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/dialog.h>
#include "wxExtensions.hpp"
#include "Plater.hpp"
#include "Widgets/StepCtrl.hpp"
#include "Widgets/ProgressDialog.hpp"
#include "Widgets/Button.hpp"
#include "Widgets/ProgressBar.hpp"
namespace Slic3r {
namespace GUI {
enum PublishStep {
STEP_SLICING = 0,
STEP_PACKING,
STEP_UPLOADING,
STEP_FILL_INFO,
STEP_PUBLISH_COUNT,
};
class PublishDialog : public DPIDialog
{
public:
PublishDialog(Plater* plater = nullptr);
bool UpdateStatus(wxString &msg, int percent = -1, bool yeild = true);
void Pulse(wxString &msg, bool &skip);
void SetPublishStep(PublishStep step, bool yeild = false, int percent = -1);
void start_slicing();
void reset();
bool was_cancelled() { return m_was_cancelled; }
void cancel();
protected:
wxPanel* m_step_panel;
::StepIndicator *m_publish_steps;
wxStaticText *m_text_note;
wxStaticText *m_text_progress;
ProgressBar *m_progress;
Button* m_btn_cancel;
wxStaticText *m_text_errors;
Plater * m_plater{nullptr};
bool m_was_cancelled { false };
wxBoxSizer* create_publish_step_sizer();
void on_close(wxCloseEvent &event);
void on_dpi_changed(const wxRect &suggested_rect) override;
};
} // GUI
} // Slic3r
#endif /* slic3r_BedShapeDialog_hpp_ */