Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_gcode_window

This commit is contained in:
enricoturri1966 2021-03-22 08:39:44 +01:00
commit b6470c3390
32 changed files with 1612 additions and 994 deletions

View file

@ -328,7 +328,12 @@ double Control::get_double_value(const SelectedSlider& selection)
int Control::get_tick_from_value(double value)
{
auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon());
std::vector<double>::iterator it;
if (m_is_smart_wipe_tower)
it = std::find_if(m_values.begin(), m_values.end(),
[value](const double & val) { return fabs(value - val) <= epsilon(); });
else
it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon());
if (it == m_values.end())
return -1;
@ -391,6 +396,16 @@ void Control::SetLayersTimes(const std::vector<float>& layers_times)
m_layers_times[0] = layers_times[0];
for (size_t i = 1; i < layers_times.size(); i++)
m_layers_times[i] = m_layers_times[i - 1] + layers_times[i];
// Erase duplicates values from m_values and save it to the m_layers_values
// They will be used for show the correct estimated time for MM print, when "No sparce layer" is enabled
// See https://github.com/prusa3d/PrusaSlicer/issues/6232
m_is_smart_wipe_tower = m_values.size() != m_layers_times.size();
if (m_is_smart_wipe_tower) {
m_layers_values = m_values;
sort(m_layers_values.begin(), m_layers_values.end());
m_layers_values.erase(unique(m_layers_values.begin(), m_layers_values.end()), m_layers_values.end());
}
}
void Control::SetLayersTimes(const std::vector<double>& layers_times)
@ -424,6 +439,22 @@ void Control::SetExtruderColors( const std::vector<std::string>& extruder_colors
m_extruder_colors = extruder_colors;
}
bool Control::IsNewPrint()
{
if (GUI::wxGetApp().plater()->printer_technology() == ptSLA)
return false;
const Print& print = GUI::wxGetApp().plater()->fff_print();
std::string idxs;
for (auto object : print.objects())
idxs += std::to_string(object->id().id) + "_";
if (idxs == m_print_obj_idxs)
return false;
m_print_obj_idxs = idxs;
return true;
}
void Control::get_lower_and_higher_position(int& lower_pos, int& higher_pos)
{
const double step = get_scroll_step();
@ -495,6 +526,18 @@ void Control::render()
}
}
bool Control::is_wipe_tower_layer(int tick) const
{
if (!m_is_smart_wipe_tower || tick >= (int)m_values.size())
return false;
if (tick == 0 || (tick == (int)m_values.size() - 1 && m_values[tick] > m_values[tick - 1]))
return false;
if (m_values[tick - 1] == m_values[tick + 1] && m_values[tick] < m_values[tick + 1])
return true;
return false;
}
void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end)
{
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
@ -506,6 +549,11 @@ void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_
if (tick == 0)
return;
if (is_wipe_tower_layer(tick)) {
m_rect_tick_action = wxRect();
return;
}
wxBitmap* icon = m_focus == fiActionIcon ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
if (m_ticks.ticks.find(TickCode{tick}) != m_ticks.ticks.end())
icon = m_focus == fiActionIcon ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
@ -654,6 +702,21 @@ wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer
if (value >= m_values.size())
return "ErrVal";
// When "Print Settings -> Multiple Extruders -> No sparse layer" is enabled, then "Smart" Wipe Tower is used for wiping.
// As a result, each layer with tool changes is splited for min 3 parts: first tool, wiping, second tool ...
// So, vertical slider have to respect to this case.
// see https://github.com/prusa3d/PrusaSlicer/issues/6232.
// m_values contains data for all layer's parts,
// but m_layers_values contains just unique Z values.
// Use this function for correct conversion slider position to number of printed layer
auto get_layer_number = [this](int value) {
double layer_print_z = m_values[is_wipe_tower_layer(value) ? std::max<int>(value - 1, 0) : value];
auto it = std::lower_bound(m_layers_values.begin(), m_layers_values.end(), layer_print_z - epsilon());
if (it == m_layers_values.end())
return -1;
return int(it - m_layers_values.begin());
};
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
if (m_draw_mode == dmSequentialGCodeView) {
return (Slic3r::GUI::get_app_config()->get("seq_top_gcode_indices") == "1") ?
@ -666,15 +729,21 @@ wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
else {
if (label_type == ltEstimatedTime) {
return (value < m_layers_times.size()) ? short_and_splitted_time(get_time_dhms(m_layers_times[value])) : "";
if (m_is_smart_wipe_tower) {
int layer_number = get_layer_number(value);
return layer_number < 0 ? "" : short_and_splitted_time(get_time_dhms(m_layers_times[layer_number]));
}
return value < m_layers_times.size() ? short_and_splitted_time(get_time_dhms(m_layers_times[value])) : "";
}
wxString str = m_values.empty() ?
wxString::Format("%.*f", 2, m_label_koef * value) :
wxString::Format("%.*f", 2, m_values[value]);
if (label_type == ltHeight)
return str;
if (label_type == ltHeightWithLayer)
return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1);
if (label_type == ltHeightWithLayer) {
size_t layer_number = m_is_smart_wipe_tower ? (size_t)get_layer_number(value) : (m_values.empty() ? value : value + 1);
return format_wxstr("%1%\n(%2%)", str, layer_number);
}
}
return wxEmptyString;
@ -709,10 +778,17 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, LabelType l
text_pos = wxPoint(std::max(2, pos.x - text_width - 1 - m_thumb_size.x), pos.y - 0.5 * text_height + 1);
}
wxColour old_clr = dc.GetTextForeground();
const wxPen& pen = is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ? DARK_ORANGE_PEN : wxPen(old_clr);
dc.SetPen(pen);
dc.SetTextForeground(pen.GetColour());
if (label_type == ltEstimatedTime)
dc.DrawLabel(label, wxRect(text_pos, wxSize(text_width, text_height)), wxALIGN_RIGHT);
else
dc.DrawText(label, text_pos);
dc.SetTextForeground(old_clr);
}
void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const
@ -1275,6 +1351,8 @@ wxString Control::get_tooltip(int tick/*=-1*/)
if (m_focus == fiColorBand)
return m_mode != SingleExtruder ? "" :
_L("Edit current color - Right click the colored slider segment");
if (m_focus == fiSmartWipeTower)
return _L("This is wipe tower layer");
if (m_draw_mode == dmSlaPrint)
return ""; // no drawn ticks and no tooltips for them in SlaPrinting mode
@ -1408,8 +1486,14 @@ void Control::OnMotion(wxMouseEvent& event)
else if (is_point_in_rect(pos, m_rect_higher_thumb))
m_focus = fiHigherThumb;
else {
m_focus = fiTick;
tick = get_tick_near_point(pos);
if (tick < 0 && m_is_smart_wipe_tower) {
tick = get_value_from_position(pos);
m_focus = tick > 0 && is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ?
fiSmartWipeTower : fiTick;
}
else
m_focus = fiTick;
}
m_moving_pos = pos;
}
@ -1938,6 +2022,9 @@ void Control::auto_color_change()
Layer* layer = object->get_layer(i);
double cur_area = area(layer->lslices);
if (cur_area > prev_area)
break;
if (prev_area - cur_area > delta_area) {
int tick = get_tick_from_value(layer->print_z);
if (tick >= 0 && !m_ticks.has_tick(tick)) {
@ -1951,6 +2038,10 @@ void Control::auto_color_change()
extruder = 1;
}
}
// allow max 3 auto color changes
if (m_ticks.ticks.size() == 3)
break;
}
prev_area = cur_area;

View file

@ -43,6 +43,7 @@ enum FocusedItem {
fiActionIcon,
fiLowerThumb,
fiHigherThumb,
fiSmartWipeTower,
fiTick
};
@ -233,6 +234,8 @@ public:
void SetModeAndOnlyExtruder(const bool is_one_extruder_printed_model, const int only_extruder);
void SetExtruderColors(const std::vector<std::string>& extruder_colors);
bool IsNewPrint();
void set_render_as_disabled(bool value) { m_render_as_disabled = value; }
bool is_rendering_as_disabled() const { return m_render_as_disabled; }
@ -303,6 +306,7 @@ protected:
void correct_higher_value();
void move_current_thumb(const bool condition);
void enter_window(wxMouseEvent& event, const bool enter);
bool is_wipe_tower_layer(int tick) const;
private:
@ -366,6 +370,7 @@ private:
bool m_is_focused = false;
bool m_force_mode_apply = true;
bool m_enable_action_icon = true;
bool m_is_smart_wipe_tower = false; //This flag indicates that for current print is used "smart" wipe tower (Print Settings->Multiple Extruders->No sparse layer is enabled)
DrawMode m_draw_mode = dmRegular;
@ -394,7 +399,9 @@ private:
std::vector<double> m_values;
TickCodeInfo m_ticks;
std::vector<double> m_layers_times;
std::vector<double> m_layers_values;
std::vector<std::string> m_extruder_colors;
std::string m_print_obj_idxs;
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
std::vector<double> m_alternate_values;

View file

@ -9,7 +9,6 @@
#include "slic3r/GUI/format.hpp"
#include "slic3r/GUI/MainFrame.hpp"
#include "slic3r/GUI/Plater.hpp"
#include "slic3r/Utils/Platform.hpp"
// To show a message box if GUI initialization ends up with an exception thrown.
#include <wx/msgdlg.h>
@ -37,8 +36,6 @@ int GUI_Run(GUI_InitParams &params)
signal(SIGCHLD, SIG_DFL);
#endif // __APPLE__
detect_platform();
try {
GUI::GUI_App* gui = new GUI::GUI_App(params.start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor);
if (gui->get_app_mode() != GUI::GUI_App::EAppMode::GCodeViewer) {

View file

@ -1,3 +1,4 @@
//#include "stdlib.h"
#include "libslic3r/libslic3r.h"
#include "libslic3r/Layer.hpp"
#include "GUI_Preview.hpp"
@ -642,26 +643,26 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
m_layers_slider->SetLayersTimes(m_gcode_result->time_statistics.modes.front().layers_times);
// Suggest the auto color change, if model looks like sign
if (ticks_info_from_model.gcodes.empty())
if (m_layers_slider->IsNewPrint())
{
NotificationManager* notif_mngr = wxGetApp().plater()->get_notification_manager();
notif_mngr->close_notification_of_type(NotificationType::SignDetected);
const Print& print = wxGetApp().plater()->fff_print();
double delta_area = scale_(scale_(25)); // equal to 25 mm2
//bool is_possible_auto_color_change = false;
for (auto object : print.objects()) {
// bottom layer have to be a biggest, so control relation between bottom lazer and object size
const ExPolygons& bottom = object->get_layer(0)->lslices;
double bottom_area = area(bottom);
if (bottom_area < double(object->size().x()) * double(object->size().y()))
continue;
// if it's sign, than object have not to be a too height
double height = object->height();
coord_t longer_side = std::max(object->size().x(), object->size().y());
if (height / longer_side > 0.3)
continue;
const ExPolygons& bottom = object->get_layer(0)->lslices;
if (bottom.size() > 1 || !bottom[0].holes.empty())
continue;
double bottom_area = area(bottom);
// at least 30% of object's height have to be a solid
int i;
for (i = 1; i < int(0.3 * object->layers().size()); i++)
if (area(object->get_layer(1)->lslices) != bottom_area)
@ -671,17 +672,17 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
double top_area = area(object->get_layer(int(object->layers().size()) - 1)->lslices);
if( bottom_area - top_area > delta_area) {
NotificationManager* notif_mngr = wxGetApp().plater()->get_notification_manager();
notif_mngr->push_notification(
NotificationType::SignDetected, NotificationManager::NotificationLevel::RegularNotification,
_u8L("NOTE:") + "\n" + _u8L("Sliced object looks like the sign") + "\n",
_u8L("Apply auto color change to print"),
[this, notif_mngr](wxEvtHandler*) {
notif_mngr->close_notification_of_type(NotificationType::SignDetected);
[this](wxEvtHandler*) {
m_layers_slider->auto_color_change();
return true;
});
notif_mngr->set_in_preview(true);
notif_mngr->apply_in_preview();
break;
}

View file

@ -122,9 +122,10 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
glsafe(::glMultMatrixd(instance_matrix.data()));
float render_color[4];
std::array<float, 4> render_color;
const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
size_t cache_size = drain_holes.size();
for (size_t i = 0; i < cache_size; ++i)
{
const sla::DrainHole& drain_hole = drain_holes[i];
@ -136,26 +137,27 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking) cons
// First decide about the color of the point.
if (picking) {
std::array<float, 4> color = picking_color_component(i);
render_color[0] = color[0];
render_color[1] = color[1];
render_color[2] = color[2];
render_color[3] = color[3];
render_color = color;
}
else {
render_color[3] = 1.f;
if (size_t(m_hover_id) == i) {
render_color[0] = 0.f;
render_color[1] = 1.0f;
render_color[2] = 1.0f;
render_color = {0.f, 1.f, 1.f, 1.f};
} else if (m_c->hollowed_mesh() &&
i < m_c->hollowed_mesh()->get_drainholes().size() &&
m_c->hollowed_mesh()->get_drainholes()[i].failed) {
render_color = {1.f, 0.f, 0.f, .5f};
}
else { // neigher hover nor picking
render_color[0] = point_selected ? 1.0f : 0.7f;
render_color[1] = point_selected ? 0.3f : 0.7f;
render_color[2] = point_selected ? 0.3f : 0.7f;
render_color[3] = 0.5f;
}
}
glsafe(::glColor4fv(render_color));
glsafe(::glColor4fv(render_color.data()));
float render_color_emissive[4] = { 0.5f * render_color[0], 0.5f * render_color[1], 0.5f * render_color[2], 1.f};
glsafe(::glMaterialfv(GL_FRONT, GL_EMISSION, render_color_emissive));

View file

@ -205,6 +205,7 @@ void HollowedMesh::on_update()
m_hollowed_mesh_transformed.reset(new TriangleMesh(backend_mesh));
Transform3d trafo_inv = canvas->sla_print()->sla_trafo(*mo).inverse();
m_hollowed_mesh_transformed->transform(trafo_inv);
m_drainholes = print_object->model_object()->sla_drain_holes;
m_old_hollowing_timestamp = timestamp;
const TriangleMesh &interior = print_object->hollowed_interior_mesh();
@ -215,8 +216,9 @@ void HollowedMesh::on_update()
m_hollowed_interior_transformed->transform(trafo_inv);
}
}
else
else {
m_hollowed_mesh_transformed.reset(nullptr);
}
}
}
else

View file

@ -5,6 +5,7 @@
#include <map>
#include "slic3r/GUI/MeshUtils.hpp"
#include "libslic3r/SLA/Hollowing.hpp"
namespace Slic3r {
@ -198,6 +199,8 @@ public:
CommonGizmosDataID get_dependencies() const override { return CommonGizmosDataID::SelectionInfo; }
#endif // NDEBUG
const sla::DrainHoles &get_drainholes() const { return m_drainholes; }
const TriangleMesh* get_hollowed_mesh() const;
const TriangleMesh* get_hollowed_interior() const;
@ -211,6 +214,7 @@ private:
size_t m_old_hollowing_timestamp = 0;
int m_print_object_idx = -1;
int m_print_objects_count = 0;
sla::DrainHoles m_drainholes;
};

View file

@ -672,7 +672,7 @@ bool MainFrame::is_active_and_shown_tab(Tab* tab)
bool MainFrame::can_start_new_project() const
{
return (m_plater != nullptr) && !m_plater->model().objects.empty();
return (m_plater != nullptr) && (!m_plater->get_project_filename(".3mf").IsEmpty() || !m_plater->model().objects.empty());
}
bool MainFrame::can_save() const
@ -1217,9 +1217,14 @@ void MainFrame::init_menubar_as_editor()
append_menu_check_item(viewMenu, wxID_ANY, _L("&Collapse sidebar") + sep + "Shift+" + sep_space + "Tab", _L("Collapse sidebar"),
[this](wxCommandEvent&) { m_plater->collapse_sidebar(!m_plater->is_sidebar_collapsed()); }, this,
[]() { return true; }, [this]() { return m_plater->is_sidebar_collapsed(); }, this);
#ifndef __APPLE__
// OSX adds its own menu item to toggle fullscreen.
append_menu_check_item(viewMenu, wxID_ANY, _L("&Full screen") + "\t" + "F11", _L("Full screen"),
[this](wxCommandEvent&) { this->ShowFullScreen(!this->IsFullScreen()); }, this,
[]() { return true; }, [this]() { return this->IsFullScreen(); }, this);
[this](wxCommandEvent&) { this->ShowFullScreen(!this->IsFullScreen(),
// wxFULLSCREEN_ALL: wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR | wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION
wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER | wxFULLSCREEN_NOCAPTION); },
this, []() { return true; }, [this]() { return this->IsFullScreen(); }, this);
#endif // __APPLE__
}
// Help menu

View file

@ -5,6 +5,7 @@
#include "ImGuiWrapper.hpp"
#include "PrintHostDialogs.hpp"
#include "wxExtensions.hpp"
#include "../Utils/PrintHost.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/log/trivial.hpp>
@ -827,8 +828,6 @@ void NotificationManager::ProgressBarNotification::render_bar(ImGuiWrapper& imgu
//------PrintHostUploadNotification----------------
void NotificationManager::PrintHostUploadNotification::set_percentage(float percent)
{
if (m_uj_state == UploadJobState::PB_CANCELLED)
return;
m_percentage = percent;
if (percent >= 1.0f) {
m_uj_state = UploadJobState::PB_COMPLETED;
@ -914,11 +913,7 @@ void NotificationManager::PrintHostUploadNotification::render_cancel_button(ImGu
ImGui::SetCursorPosY(win_size.y / 2 - button_size.y);
if (imgui.button(button_text.c_str(), button_size.x, button_size.y))
{
assert(m_evt_handler != nullptr);
if (m_evt_handler != nullptr) {
auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_CANCEL, m_job_id, m_job_id);
wxQueueEvent(m_evt_handler, evt);
}
wxGetApp().printhost_job_queue().cancel(m_job_id - 1);
}
//invisible large button
@ -926,11 +921,7 @@ void NotificationManager::PrintHostUploadNotification::render_cancel_button(ImGu
ImGui::SetCursorPosY(0);
if (imgui.button(" ", m_line_height * 2.f, win_size.y))
{
assert(m_evt_handler != nullptr);
if (m_evt_handler != nullptr) {
auto evt = new PrintHostQueueDialog::Event(GUI::EVT_PRINTHOST_CANCEL, m_job_id, m_job_id);
wxQueueEvent(m_evt_handler, evt);
}
wxGetApp().printhost_job_queue().cancel(m_job_id - 1);
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
@ -1023,7 +1014,7 @@ void NotificationManager::push_plater_warning_notification(const std::string& te
auto notification = std::make_unique<NotificationManager::PlaterWarningNotification>(data, m_id_provider, m_evt_handler);
push_notification_data(std::move(notification), 0);
// dissaper if in preview
set_in_preview(m_in_preview);
apply_in_preview();
}
void NotificationManager::close_plater_warning_notification(const std::string& text)
@ -1129,28 +1120,21 @@ void NotificationManager::push_exporting_finished_notification(const std::string
push_notification_data(std::make_unique<NotificationManager::ExportFinishedNotification>(data, m_id_provider, m_evt_handler, on_removable, path, dir_path), 0);
}
void NotificationManager::push_upload_job_notification(wxEvtHandler* evt_handler, int id, float filesize, const std::string& filename, const std::string& host, float percentage)
void NotificationManager::push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage)
{
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
NotificationData data{ NotificationType::PrintHostUpload, NotificationLevel::ProgressBarNotification, 0, text };
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, evt_handler, 0, id, filesize), 0);
push_notification_data(std::make_unique<NotificationManager::PrintHostUploadNotification>(data, m_id_provider, m_evt_handler, 0, id, filesize), 0);
}
void NotificationManager::set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage)
{
std::string text = PrintHostUploadNotification::get_upload_job_text(id, filename, host);
// bool found = false;
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::ProgressBar && notification->compare_text(text)) {
if (notification->get_type() == NotificationType::PrintHostUpload && notification->compare_text(text)) {
dynamic_cast<PrintHostUploadNotification*>(notification.get())->set_percentage(percentage);
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
// found = true;
}
}
/*
if (!found) {
push_upload_job_notification(id, filename, host, percentage);
}
*/
}
void NotificationManager::upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host)
{

View file

@ -147,7 +147,7 @@ public:
// Exporting finished, show this information with path, button to open containing folder and if ejectable - eject button
void push_exporting_finished_notification(const std::string& path, const std::string& dir_path, bool on_removable);
// notification with progress bar
void push_upload_job_notification(wxEvtHandler* evt_handler, int id, float filesize, const std::string& filename, const std::string& host, float percentage = 0);
void push_upload_job_notification(int id, float filesize, const std::string& filename, const std::string& host, float percentage = 0);
void set_upload_job_notification_percentage(int id, const std::string& filename, const std::string& host, float percentage);
void upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host);
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
@ -159,8 +159,10 @@ public:
void render_notifications(GLCanvas3D& canvas, float overlay_width);
// finds and closes all notifications of given type
void close_notification_of_type(const NotificationType type);
// Which view is active? Plater or G-code preview? Hide warnings in G-code preview.
// Hides warnings in G-code preview. Should be called from plater only when 3d view/ preview is changed
void set_in_preview(bool preview);
// Calls set_in_preview to apply appearing or disappearing of some notificatons;
void apply_in_preview() { set_in_preview(m_in_preview); }
// Move to left to avoid colision with variable layer height gizmo.
void set_move_from_overlay(bool move) { m_move_from_overlay = move; }
// perform update_state on each notification and ask for more frames if needed, return true for render needed
@ -319,7 +321,7 @@ private:
void set_large(bool l);
bool get_large() { return m_is_large; }
void set_print_info(const std::string &info);
virtual void render(GLCanvas3D& canvas, float initial_y, bool move_from_overlay, float overlay_width)
virtual void render(GLCanvas3D& canvas, float initial_y, bool move_from_overlay, float overlay_width) override
{
// This notification is always hidden if !large (means side bar is collapsed)
if (!get_large() && !is_finished())
@ -348,9 +350,9 @@ private:
{
public:
PlaterWarningNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler) : PopNotification(n, id_provider, evt_handler) {}
virtual void close() { if(is_finished()) return; m_state = EState::Hidden; wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); }
void real_close() { m_state = EState::ClosePending; wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); }
void show() { m_state = EState::Unknown; }
virtual void close() override { if(is_finished()) return; m_state = EState::Hidden; wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); }
void real_close() { m_state = EState::ClosePending; wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0); }
void show() { m_state = EState::Unknown; }
};
@ -365,10 +367,10 @@ private:
virtual void count_spaces() override;
virtual void render_text(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
const float win_pos_x, const float win_pos_y) override;
virtual void render_bar(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
const float win_pos_x, const float win_pos_y) ;
virtual void render_cancel_button(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y)
@ -400,16 +402,16 @@ private:
m_has_cancel_button = true;
}
static std::string get_upload_job_text(int id, const std::string& filename, const std::string& host) { return "[" + std::to_string(id) + "] " + filename + " -> " + host; }
virtual void set_percentage(float percent);
virtual void set_percentage(float percent) override;
void cancel() { m_uj_state = UploadJobState::PB_CANCELLED; m_has_cancel_button = false; }
void error() { m_uj_state = UploadJobState::PB_ERROR; m_has_cancel_button = false; }
protected:
virtual void render_bar(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
const float win_pos_x, const float win_pos_y) override;
virtual void render_cancel_button(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
const float win_pos_x, const float win_pos_y) override;
// Identifies job in cancel callback
int m_job_id;
// Size of uploaded size to be displayed in MB

View file

@ -4,7 +4,8 @@
#include "GUI.hpp"
#include "I18N.hpp"
#include "3DScene.hpp"
#include "slic3r/Utils/Platform.hpp"
#include "libslic3r/Platform.hpp"
#include <GL/glew.h>
@ -324,7 +325,7 @@ void OpenGLManager::detect_multisample(int* attribList)
enable_multisample &&
// Disable multi-sampling on ChromeOS, as the OpenGL virtualization swaps Red/Blue channels with multi-sampling enabled,
// at least on some platforms.
(platform() != Platform::Linux || platform_flavor() != PlatformFlavor::LinuxOnChromium) &&
platform_flavor() != PlatformFlavor::LinuxOnChromium &&
wxGLCanvas::IsDisplaySupported(attribList)
? EMultisampleState::Enabled : EMultisampleState::Disabled;
// Alternative method: it was working on previous version of wxWidgets but not with the latest, at least on Windows

View file

@ -76,7 +76,6 @@
#include "../Utils/FixModelByWin10.hpp"
#include "../Utils/UndoRedo.hpp"
#include "../Utils/PresetUpdater.hpp"
#include "../Utils/Platform.hpp"
#include "../Utils/Process.hpp"
#include "RemovableDriveManager.hpp"
#include "InstanceCheck.hpp"
@ -89,7 +88,9 @@
#include <wx/glcanvas.h> // Needs to be last because reasons :-/
#include "WipeTowerDialog.hpp"
#include "libslic3r/CustomGCode.hpp"
#include "libslic3r/Platform.hpp"
using boost::optional;
namespace fs = boost::filesystem;
@ -3660,7 +3661,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
show_action_buttons(false);
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path,
// Don't offer the "Eject" button on ChromeOS, the Linux side has no control over it.
platform() != Platform::Linux || platform_flavor() != PlatformFlavor::LinuxOnChromium);
platform_flavor() != PlatformFlavor::LinuxOnChromium);
wxGetApp().removable_drive_manager()->set_exporting_finished(true);
}else if (exporting_status == ExportingStatus::EXPORTING_TO_LOCAL && !has_error)
notification_manager->push_exporting_finished_notification(last_output_path, last_output_dir_path, false);
@ -4788,7 +4789,8 @@ void Plater::remove(size_t obj_idx) { p->remove(obj_idx); }
void Plater::reset() { p->reset(); }
void Plater::reset_with_confirm()
{
if (wxMessageDialog(static_cast<wxWindow*>(this), _L("All objects will be removed, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES)
if (p->model.objects.empty() ||
wxMessageDialog(static_cast<wxWindow*>(this), _L("All objects will be removed, continue?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Delete all"), wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES)
reset();
}

View file

@ -139,7 +139,6 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle
const ConfigOptionFloatOrPercent *first_layer_extrusion_width_ptr = (first_layer && first_layer_extrusion_width.value > 0) ?
&first_layer_extrusion_width : nullptr;
const float lh = float(first_layer ? first_layer_height : layer_height);
const float bfr = bridging ? bridge_flow_ratio : 0.f;
double max_flow = 0.;
std::string max_flow_extrusion_type;
auto limit_by_first_layer_speed = [&first_layer_speed, first_layer](double speed_normal, double speed_max) {

View file

@ -224,8 +224,8 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
std::vector<int> size;
SetSize(load_user_data(UDT_SIZE, size) ? wxSize(size[0] * em, size[1] * em) : wxSize(HEIGHT * em, WIDTH * em));
Bind(wxEVT_SIZE, [this, em](wxSizeEvent& evt) {
OnSize(evt);
Bind(wxEVT_SIZE, [this](wxSizeEvent& evt) {
OnSize(evt);
save_user_data(UDT_SIZE | UDT_POSITION | UDT_COLS);
});
@ -233,7 +233,7 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
if (load_user_data(UDT_POSITION, pos))
SetPosition(wxPoint(pos[0], pos[1]));
Bind(wxEVT_MOVE, [this, em](wxMoveEvent& evt) {
Bind(wxEVT_MOVE, [this](wxMoveEvent& evt) {
save_user_data(UDT_SIZE | UDT_POSITION | UDT_COLS);
});
@ -245,7 +245,6 @@ PrintHostQueueDialog::PrintHostQueueDialog(wxWindow *parent)
const JobState state = get_state(selected);
if (state < ST_ERROR) {
// TODO: cancel
GUI::wxGetApp().printhost_job_queue().cancel(selected);
}
});
@ -282,7 +281,7 @@ void PrintHostQueueDialog::append_job(const PrintHostJob &job)
// Both strings are UTF-8 encoded.
upload_names.emplace_back(job.printhost->get_host(), job.upload_data.upload_path.string());
//wxGetApp().notification_manager()->push_upload_job_notification(this, job_list->GetItemCount(), 0, job.upload_data.upload_path.string(), job.printhost->get_host());
wxGetApp().notification_manager()->push_upload_job_notification(job_list->GetItemCount(), (float)size_i / 1024 / 1024, job.upload_data.upload_path.string(), job.printhost->get_host());
}
void PrintHostQueueDialog::on_dpi_changed(const wxRect &suggested_rect)
@ -354,7 +353,7 @@ void PrintHostQueueDialog::on_progress(Event &evt)
wxVariant nm, hst;
job_list->GetValue(nm, evt.job_id, COL_FILENAME);
job_list->GetValue(hst, evt.job_id, COL_HOST);
wxGetApp().notification_manager()->set_upload_job_notification_percentage(evt.job_id + 1, boost::nowide::narrow(nm.GetString()), boost::nowide::narrow(hst.GetString()), 100 / evt.progress);
wxGetApp().notification_manager()->set_upload_job_notification_percentage(evt.job_id + 1, boost::nowide::narrow(nm.GetString()), boost::nowide::narrow(hst.GetString()), evt.progress / 100.f);
}
}
@ -409,7 +408,6 @@ void PrintHostQueueDialog::get_active_jobs(std::vector<std::pair<std::string, st
void PrintHostQueueDialog::save_user_data(int udt)
{
const auto em = GetTextExtent("m").x;
BOOST_LOG_TRIVIAL(error) << "save" << this->GetSize().x / em << " " << this->GetSize().y / em << " " << this->GetPosition().x << " " << this->GetPosition().y;
auto *app_config = wxGetApp().app_config;
if (udt & UserDataType::UDT_SIZE) {

View file

@ -1,5 +1,5 @@
#include "RemovableDriveManager.hpp"
#include "slic3r/Utils/Platform.hpp"
#include "libslic3r/Platform.hpp"
#include <libslic3r/libslic3r.h>
#include <boost/nowide/convert.hpp>
@ -186,8 +186,13 @@ namespace search_for_drives_internal
{
//confirms if the file is removable drive and adds it to vector
//if not same file system - could be removable drive
if (! compare_filesystem_id(path, parent_path)) {
if (
#ifdef __linux__
// Chromium mounts removable drives in a way that produces the same device ID.
platform_flavor() == PlatformFlavor::LinuxOnChromium ||
#endif
// If not same file system - could be removable drive.
! compare_filesystem_id(path, parent_path)) {
//free space
boost::system::error_code ec;
boost::filesystem::space_info si = boost::filesystem::space(path, ec);
@ -232,7 +237,7 @@ std::vector<DriveData> RemovableDriveManager::search_for_removable_drives() cons
#else
if (platform() == Platform::Linux && platform_flavor() == PlatformFlavor::LinuxOnChromium) {
if (platform_flavor() == PlatformFlavor::LinuxOnChromium) {
// ChromeOS specific: search /mnt/chromeos/removable/* folder
search_for_drives_internal::search_path("/mnt/chromeos/removable/*", "/mnt/chromeos/removable", current_drives);
} else {
@ -452,7 +457,7 @@ RemovableDriveManager::RemovableDrivesStatus RemovableDriveManager::status()
tbb::mutex::scoped_lock lock(m_drives_mutex);
out.has_eject =
// Cannot control eject on Chromium.
(platform() != Platform::Linux || platform_flavor() != PlatformFlavor::LinuxOnChromium) &&
platform_flavor() != PlatformFlavor::LinuxOnChromium &&
this->find_last_save_path_drive_data() != m_current_drives.end();
out.has_removable_drives = ! m_current_drives.empty();
}

View file

@ -1443,7 +1443,7 @@ void TabPrint::build()
optgroup = page->new_optgroup(L("Fuzzy skin (experimental)"));
Option option = optgroup->get_option("fuzzy_skin");
option.opt.width = 30;
// option.opt.width = 30;
optgroup->append_single_option_line(option);
optgroup->append_single_option_line(optgroup->get_option("fuzzy_skin_thickness"));
optgroup->append_single_option_line(optgroup->get_option("fuzzy_skin_point_dist"));
@ -3841,7 +3841,7 @@ bool Tab::validate_custom_gcodes()
assert(opt_group->opt_map().size() == 1);
std::string key = opt_group->opt_map().begin()->first;
std::string value = boost::any_cast<std::string>(opt_group->get_value(key));
std::string config_value = m_config->opt_string(key);
std::string config_value = m_type == Preset::TYPE_FILAMENT ? m_config->opt_string(key, 0u) : m_config->opt_string(key);
valid &= validate_custom_gcode(opt_group->title, value);
Field* field = opt_group->get_field(key);
TextCtrl* text_ctrl = dynamic_cast<TextCtrl*>(field);