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

This commit is contained in:
enricoturri1966 2021-12-09 09:03:20 +01:00
commit f958c14db8
13 changed files with 98 additions and 37 deletions

View File

@ -498,7 +498,7 @@ Point SeamPlacer::calculate_seam(const Layer& layer, const SeamPosition seam_pos
else if (seam_position == spRear) { else if (seam_position == spRear) {
// Object is centered around (0,0) in its current coordinate system. // Object is centered around (0,0) in its current coordinate system.
last_pos.x() = 0; last_pos.x() = 0;
last_pos.y() += coord_t(3. * po->bounding_box().radius()); last_pos.y() = coord_t(3. * po->bounding_box().radius());
last_pos_weight = 5.f; last_pos_weight = 5.f;
} if (seam_position == spNearest) { } if (seam_position == spNearest) {
// last_pos already contains current nozzle position // last_pos already contains current nozzle position

View File

@ -92,6 +92,25 @@ void Layer::restore_untyped_slices()
} }
} }
// Similar to Layer::restore_untyped_slices()
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
// Only resetting layerm->slices if Slice::extra_perimeters is always zero or it will not be used anymore
// after the perimeter generator.
void Layer::restore_untyped_slices_no_extra_perimeters()
{
if (layer_needs_raw_backup(this)) {
for (LayerRegion *layerm : m_regions)
if (! layerm->region().config().extra_perimeters.value)
layerm->slices.set(layerm->raw_slices, stInternal);
} else {
assert(m_regions.size() == 1);
LayerRegion *layerm = m_regions.front();
// This optimization is correct, as extra_perimeters are only reused by prepare_infill() with multi-regions.
//if (! layerm->region().config().extra_perimeters.value)
layerm->slices.set(this->lslices, stInternal);
}
}
ExPolygons Layer::merged(float offset_scaled) const ExPolygons Layer::merged(float offset_scaled) const
{ {
assert(offset_scaled >= 0.f); assert(offset_scaled >= 0.f);
@ -179,7 +198,7 @@ void Layer::make_perimeters()
// group slices (surfaces) according to number of extra perimeters // group slices (surfaces) according to number of extra perimeters
std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ] std::map<unsigned short, Surfaces> slices; // extra_perimeters => [ surface, surface... ]
for (LayerRegion *layerm : layerms) { for (LayerRegion *layerm : layerms) {
for (Surface &surface : layerm->slices.surfaces) for (const Surface &surface : layerm->slices.surfaces)
slices[surface.extra_perimeters].emplace_back(surface); slices[surface.extra_perimeters].emplace_back(surface);
if (layerm->region().config().fill_density > layerm_config->region().config().fill_density) if (layerm->region().config().fill_density > layerm_config->region().config().fill_density)
layerm_config = layerm; layerm_config = layerm;

View File

@ -137,6 +137,8 @@ public:
//FIXME Review whether not to simplify the code by keeping the raw_slices all the time. //FIXME Review whether not to simplify the code by keeping the raw_slices all the time.
void backup_untyped_slices(); void backup_untyped_slices();
void restore_untyped_slices(); void restore_untyped_slices();
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
void restore_untyped_slices_no_extra_perimeters();
// Slices merged into islands, to be used by the elephant foot compensation to trim the individual surfaces with the shrunk merged slices. // Slices merged into islands, to be used by the elephant foot compensation to trim the individual surfaces with the shrunk merged slices.
ExPolygons merged(float offset) const; ExPolygons merged(float offset) const;
template <class T> bool any_internal_region_slice_contains(const T &item) const { template <class T> bool any_internal_region_slice_contains(const T &item) const {

View File

@ -51,8 +51,7 @@ void LayerRegion::slices_to_fill_surfaces_clipped()
// so we're safe. This guarantees idempotence of prepare_infill() also in case // so we're safe. This guarantees idempotence of prepare_infill() also in case
// that combine_infill() turns some fill_surface into VOID surfaces. // that combine_infill() turns some fill_surface into VOID surfaces.
// Collect polygons per surface type. // Collect polygons per surface type.
std::vector<SurfacesPtr> by_surface; std::array<SurfacesPtr, size_t(stCount)> by_surface;
by_surface.assign(size_t(stCount), SurfacesPtr());
for (Surface &surface : this->slices.surfaces) for (Surface &surface : this->slices.surfaces)
by_surface[size_t(surface.surface_type)].emplace_back(&surface); by_surface[size_t(surface.surface_type)].emplace_back(&surface);
// Trim surfaces by the fill_boundaries. // Trim surfaces by the fill_boundaries.

View File

@ -3773,7 +3773,7 @@ void PrintConfigDef::init_sla_params()
def->enum_labels.push_back(L("Slow")); def->enum_labels.push_back(L("Slow"));
def->enum_labels.push_back(L("Fast")); def->enum_labels.push_back(L("Fast"));
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<SLAMaterialSpeed>(slamsSlow)); def->set_default_value(new ConfigOptionEnum<SLAMaterialSpeed>(slamsFast));
} }
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value) void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)

View File

@ -227,6 +227,17 @@ void PrintObject::prepare_infill()
m_print->set_status(30, L("Preparing infill")); m_print->set_status(30, L("Preparing infill"));
if (m_typed_slices) {
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
// The preceding step (perimeter generator) only modifies extra_perimeters and the extra perimeters are only used by discover_vertical_shells()
// with more than a single region. If this step does not use Surface::extra_perimeters or Surface::extra_perimeters is always zero, it is safe
// to reset to the untyped slices before re-runnning detect_surfaces_type().
for (Layer* layer : m_layers) {
layer->restore_untyped_slices_no_extra_perimeters();
m_print->throw_if_canceled();
}
}
// This will assign a type (top/bottom/internal) to $layerm->slices. // This will assign a type (top/bottom/internal) to $layerm->slices.
// Then the classifcation of $layerm->slices is transfered onto // Then the classifcation of $layerm->slices is transfered onto
// the $layerm->fill_surfaces by clipping $layerm->fill_surfaces // the $layerm->fill_surfaces by clipping $layerm->fill_surfaces

View File

@ -550,24 +550,24 @@ RENDER_AGAIN:
ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x);
ImGui::PushItemWidth(window_width - settings_sliders_left); ImGui::PushItemWidth(window_width - settings_sliders_left);
m_imgui->slider_float("##offset", &offset, offset_min, offset_max, "%.1f mm"); m_imgui->slider_float("##offset", &offset, offset_min, offset_max, "%.1f mm");
if (ImGui::IsItemHovered()) if (m_imgui->get_last_slider_status().hovered)
m_imgui->tooltip((_utf8(opts[0].second->tooltip)).c_str(), max_tooltip_width); m_imgui->tooltip((_utf8(opts[0].second->tooltip)).c_str(), max_tooltip_width);
bool slider_clicked = ImGui::IsItemClicked(); // someone clicked the slider bool slider_clicked = m_imgui->get_last_slider_status().clicked; // someone clicked the slider
bool slider_edited = ImGui::IsItemEdited(); // someone is dragging the slider bool slider_edited =m_imgui->get_last_slider_status().edited; // someone is dragging the slider
bool slider_released = ImGui::IsItemDeactivatedAfterEdit(); // someone has just released the slider bool slider_released =m_imgui->get_last_slider_status().deactivated_after_edit; // someone has just released the slider
if (current_mode >= quality_mode) { if (current_mode >= quality_mode) {
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("quality")); m_imgui->text(m_desc.at("quality"));
ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x);
m_imgui->slider_float("##quality", &quality, quality_min, quality_max, "%.1f"); m_imgui->slider_float("##quality", &quality, quality_min, quality_max, "%.1f");
if (ImGui::IsItemHovered()) if (m_imgui->get_last_slider_status().hovered)
m_imgui->tooltip((_utf8(opts[1].second->tooltip)).c_str(), max_tooltip_width); m_imgui->tooltip((_utf8(opts[1].second->tooltip)).c_str(), max_tooltip_width);
slider_clicked |= ImGui::IsItemClicked(); slider_clicked |= m_imgui->get_last_slider_status().clicked;
slider_edited |= ImGui::IsItemEdited(); slider_edited |= m_imgui->get_last_slider_status().edited;
slider_released |= ImGui::IsItemDeactivatedAfterEdit(); slider_released |= m_imgui->get_last_slider_status().deactivated_after_edit;
} }
if (current_mode >= closing_d_mode) { if (current_mode >= closing_d_mode) {
@ -575,12 +575,12 @@ RENDER_AGAIN:
m_imgui->text(m_desc.at("closing_distance")); m_imgui->text(m_desc.at("closing_distance"));
ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x); ImGui::SameLine(settings_sliders_left, m_imgui->get_item_spacing().x);
m_imgui->slider_float("##closing_distance", &closing_d, closing_d_min, closing_d_max, "%.1f mm"); m_imgui->slider_float("##closing_distance", &closing_d, closing_d_min, closing_d_max, "%.1f mm");
if (ImGui::IsItemHovered()) if (m_imgui->get_last_slider_status().hovered)
m_imgui->tooltip((_utf8(opts[2].second->tooltip)).c_str(), max_tooltip_width); m_imgui->tooltip((_utf8(opts[2].second->tooltip)).c_str(), max_tooltip_width);
slider_clicked |= ImGui::IsItemClicked(); slider_clicked |= m_imgui->get_last_slider_status().clicked;
slider_edited |= ImGui::IsItemEdited(); slider_edited |= m_imgui->get_last_slider_status().edited;
slider_released |= ImGui::IsItemDeactivatedAfterEdit(); slider_released |= m_imgui->get_last_slider_status().deactivated_after_edit;
} }
if (slider_clicked) { if (slider_clicked) {
@ -627,9 +627,9 @@ RENDER_AGAIN:
//complete non-sense. //complete non-sense.
diam = std::clamp(diam, 0.1f, diameter_upper_cap); diam = std::clamp(diam, 0.1f, diameter_upper_cap);
m_new_hole_radius = diam / 2.f; m_new_hole_radius = diam / 2.f;
bool clicked = ImGui::IsItemClicked(); bool clicked = m_imgui->get_last_slider_status().clicked;
bool edited = ImGui::IsItemEdited(); bool edited = m_imgui->get_last_slider_status().edited;
bool deactivated = ImGui::IsItemDeactivatedAfterEdit(); bool deactivated = m_imgui->get_last_slider_status().deactivated_after_edit;
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc["hole_depth"]); m_imgui->text(m_desc["hole_depth"]);
@ -638,9 +638,9 @@ RENDER_AGAIN:
// Same as above: // Same as above:
m_new_hole_height = std::clamp(m_new_hole_height, 0.f, 100.f); m_new_hole_height = std::clamp(m_new_hole_height, 0.f, 100.f);
clicked |= ImGui::IsItemClicked(); clicked |= m_imgui->get_last_slider_status().clicked;
edited |= ImGui::IsItemEdited(); edited |= m_imgui->get_last_slider_status().edited;
deactivated |= ImGui::IsItemDeactivatedAfterEdit(); deactivated |= m_imgui->get_last_slider_status().deactivated_after_edit;;
// Following is a nasty way to: // Following is a nasty way to:
// - save the initial value of the slider before one starts messing with it // - save the initial value of the slider before one starts messing with it

View File

@ -859,9 +859,9 @@ void GLPaintContour::finalize_geometry()
if (!this->contour_indices.empty()) { if (!this->contour_indices.empty()) {
glsafe(::glGenBuffers(1, &this->m_contour_EBO_id)); glsafe(::glGenBuffers(1, &this->m_contour_EBO_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_contour_EBO_id)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_contour_EBO_id));
glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_indices.size() * sizeof(unsigned int), this->contour_indices.data(), GL_STATIC_DRAW)); glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->contour_indices.size() * sizeof(unsigned int), this->contour_indices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
this->contour_indices.clear(); this->contour_indices.clear();
} }
} }

View File

@ -687,16 +687,16 @@ RENDER_AGAIN:
// - take correct undo/redo snapshot after the user is done with moving the slider // - take correct undo/redo snapshot after the user is done with moving the slider
float initial_value = m_new_point_head_diameter; float initial_value = m_new_point_head_diameter;
m_imgui->slider_float("##head_diameter", &m_new_point_head_diameter, 0.1f, diameter_upper_cap, "%.1f"); m_imgui->slider_float("##head_diameter", &m_new_point_head_diameter, 0.1f, diameter_upper_cap, "%.1f");
if (ImGui::IsItemClicked()) { if (m_imgui->get_last_slider_status().clicked) {
if (m_old_point_head_diameter == 0.f) if (m_old_point_head_diameter == 0.f)
m_old_point_head_diameter = initial_value; m_old_point_head_diameter = initial_value;
} }
if (ImGui::IsItemEdited()) { if (m_imgui->get_last_slider_status().edited) {
for (auto& cache_entry : m_editing_cache) for (auto& cache_entry : m_editing_cache)
if (cache_entry.selected) if (cache_entry.selected)
cache_entry.support_point.head_front_radius = m_new_point_head_diameter / 2.f; cache_entry.support_point.head_front_radius = m_new_point_head_diameter / 2.f;
} }
if (ImGui::IsItemDeactivatedAfterEdit()) { if (m_imgui->get_last_slider_status().deactivated_after_edit) {
// momentarily restore the old value to take snapshot // momentarily restore the old value to take snapshot
for (auto& cache_entry : m_editing_cache) for (auto& cache_entry : m_editing_cache)
if (cache_entry.selected) if (cache_entry.selected)
@ -747,18 +747,18 @@ RENDER_AGAIN:
float minimal_point_distance = static_cast<const ConfigOptionFloat*>(opts[1])->value; float minimal_point_distance = static_cast<const ConfigOptionFloat*>(opts[1])->value;
m_imgui->slider_float("##minimal_point_distance", &minimal_point_distance, 0.f, 20.f, "%.f mm"); m_imgui->slider_float("##minimal_point_distance", &minimal_point_distance, 0.f, 20.f, "%.f mm");
bool slider_clicked = ImGui::IsItemClicked(); // someone clicked the slider bool slider_clicked = m_imgui->get_last_slider_status().clicked; // someone clicked the slider
bool slider_edited = ImGui::IsItemEdited(); // someone is dragging the slider bool slider_edited = m_imgui->get_last_slider_status().edited; // someone is dragging the slider
bool slider_released = ImGui::IsItemDeactivatedAfterEdit(); // someone has just released the slider bool slider_released = m_imgui->get_last_slider_status().deactivated_after_edit; // someone has just released the slider
ImGui::AlignTextToFramePadding(); ImGui::AlignTextToFramePadding();
m_imgui->text(m_desc.at("points_density")); m_imgui->text(m_desc.at("points_density"));
ImGui::SameLine(settings_sliders_left); ImGui::SameLine(settings_sliders_left);
m_imgui->slider_float("##points_density", &density, 0.f, 200.f, "%.f %%"); m_imgui->slider_float("##points_density", &density, 0.f, 200.f, "%.f %%");
slider_clicked |= ImGui::IsItemClicked(); slider_clicked |= m_imgui->get_last_slider_status().clicked;
slider_edited |= ImGui::IsItemEdited(); slider_edited |= m_imgui->get_last_slider_status().edited;
slider_released |= ImGui::IsItemDeactivatedAfterEdit(); slider_released |= m_imgui->get_last_slider_status().deactivated_after_edit;
if (slider_clicked) { // stash the values of the settings so we know what to revert to after undo if (slider_clicked) { // stash the values of the settings so we know what to revert to after undo
m_minimal_point_distance_stash = minimal_point_distance; m_minimal_point_distance_stash = minimal_point_distance;

View File

@ -551,6 +551,12 @@ bool ImGuiWrapper::slider_float(const char* label, float* v, float v_min, float
bool slider_editing = ImGui::GetCurrentWindow()->GetID(str_label.c_str()) == ImGui::GetActiveID(); bool slider_editing = ImGui::GetCurrentWindow()->GetID(str_label.c_str()) == ImGui::GetActiveID();
bool ret = ImGui::SliderFloat(str_label.c_str(), v, v_min, v_max, format, power); bool ret = ImGui::SliderFloat(str_label.c_str(), v, v_min, v_max, format, power);
m_last_slider_status.hovered = ImGui::IsItemHovered();
m_last_slider_status.edited = ImGui::IsItemEdited();
m_last_slider_status.clicked = ImGui::IsItemClicked();
m_last_slider_status.deactivated_after_edit = ImGui::IsItemDeactivatedAfterEdit();
if (!tooltip.empty() && ImGui::IsItemHovered()) if (!tooltip.empty() && ImGui::IsItemHovered())
this->tooltip(into_u8(tooltip).c_str(), max_tooltip_width); this->tooltip(into_u8(tooltip).c_str(), max_tooltip_width);

View File

@ -45,6 +45,13 @@ class ImGuiWrapper
std::string m_clipboard_text; std::string m_clipboard_text;
public: public:
struct LastSliderStatus {
bool hovered { false };
bool edited { false };
bool clicked { false };
bool deactivated_after_edit { false };
};
ImGuiWrapper(); ImGuiWrapper();
~ImGuiWrapper(); ~ImGuiWrapper();
@ -69,6 +76,7 @@ public:
ImVec2 get_item_spacing() const; ImVec2 get_item_spacing() const;
float get_slider_float_height() const; float get_slider_float_height() const;
const LastSliderStatus& get_last_slider_status() const { return m_last_slider_status; }
void set_next_window_pos(float x, float y, int flag, float pivot_x = 0.0f, float pivot_y = 0.0f); void set_next_window_pos(float x, float y, int flag, float pivot_x = 0.0f, float pivot_y = 0.0f);
void set_next_window_bg_alpha(float alpha); void set_next_window_bg_alpha(float alpha);
@ -161,6 +169,8 @@ private:
static const char* clipboard_get(void* user_data); static const char* clipboard_get(void* user_data);
static void clipboard_set(void* user_data, const char* text); static void clipboard_set(void* user_data, const char* text);
LastSliderStatus m_last_slider_status;
}; };

View File

@ -2,11 +2,13 @@
#include "ConfigExceptions.hpp" #include "ConfigExceptions.hpp"
#include "Plater.hpp" #include "Plater.hpp"
#include "GUI_App.hpp" #include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "OG_CustomCtrl.hpp" #include "OG_CustomCtrl.hpp"
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
#include "format.hpp" #include "format.hpp"
#include <utility> #include <utility>
#include <wx/bookctrl.h>
#include <wx/numformatter.h> #include <wx/numformatter.h>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
@ -978,7 +980,8 @@ bool OptionsGroup::launch_browser(const std::string& path_end)
bool launch = true; bool launch = true;
if (get_app_config()->get("suppress_hyperlinks").empty()) { if (get_app_config()->get("suppress_hyperlinks").empty()) {
RichMessageDialog dialog(nullptr, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxYES_NO); wxWindow* parent = wxGetApp().mainframe->m_tabpanel;
RichMessageDialog dialog(parent, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxYES_NO);
dialog.ShowCheckBox(_L("Remember my choice")); dialog.ShowCheckBox(_L("Remember my choice"));
int answer = dialog.ShowModal(); int answer = dialog.ShowModal();
@ -989,7 +992,7 @@ bool OptionsGroup::launch_browser(const std::string& path_end)
_L("You will not be asked about it again on label hovering.") + "\n\n" + _L("You will not be asked about it again on label hovering.") + "\n\n" +
format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item); format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item);
MessageDialog msg_dlg(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION); MessageDialog msg_dlg(parent, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
if (msg_dlg.ShowModal() == wxID_CANCEL) if (msg_dlg.ShowModal() == wxID_CANCEL)
return false; return false;

View File

@ -885,6 +885,10 @@ void Tab::on_roll_back_value(const bool to_sys /*= true*/)
} }
m_postpone_update_ui = false; m_postpone_update_ui = false;
// When all values are rolled, then we hane to update whole tab in respect to the reverted values
update();
update_changed_ui(); update_changed_ui();
} }
@ -1148,6 +1152,13 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
if (opt_key == "extruders_count") if (opt_key == "extruders_count")
wxGetApp().plater()->on_extruders_change(boost::any_cast<size_t>(value)); wxGetApp().plater()->on_extruders_change(boost::any_cast<size_t>(value));
if (m_postpone_update_ui) {
// It means that not all values are rolled to the system/last saved values jet.
// And call of the update() can causes a redundant check of the config values,
// see https://github.com/prusa3d/PrusaSlicer/issues/7146
return;
}
update(); update();
} }