Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_sinking_objects_collision
This commit is contained in:
commit
982172b878
@ -48,6 +48,7 @@
|
||||
# enabled_tags = ...
|
||||
# disabled_tags = ...
|
||||
# supported tags are: simple; advanced; expert; FFF; MMU; SLA; Windows; Linux; OSX;
|
||||
# and all filament types: PLA; PET; ABS; ASA; FLEX; HIPS; EDGE; NGEN; NYLON; PVA; PC; PP; PEI; PEEK; PEKK; POM; PSU; PVDF; SCAFF;
|
||||
# Tags are case sensitive.
|
||||
# FFF is affirmative for both one or more extruder printers.
|
||||
# Algorithm shows hint only if ALL enabled tags are affirmative. (so never do enabled_tags = FFF; SLA;)
|
||||
|
@ -1639,12 +1639,13 @@ void visit_antipodals (Idx& ia, Idx &ib, Fn &&fn)
|
||||
// Set current caliper direction to be the lower edge angle from X axis
|
||||
int cmp = cmp_angles(ia.prev_dir(), ia.dir(), ib.dir());
|
||||
Idx *current = cmp <= 0 ? &ia : &ib, *other = cmp <= 0 ? &ib : &ia;
|
||||
Idx *initial = current;
|
||||
bool visitor_continue = true;
|
||||
|
||||
size_t a_start = ia.idx(), b_start = ib.idx();
|
||||
bool a_finished = false, b_finished = false;
|
||||
size_t start = initial->idx();
|
||||
bool finished = false;
|
||||
|
||||
while (visitor_continue && !(a_finished && b_finished)) {
|
||||
while (visitor_continue && !finished) {
|
||||
Point current_dir_a = current == &ia ? current->dir() : -current->dir();
|
||||
visitor_continue = fn(ia.idx(), ib.idx(), current_dir_a);
|
||||
|
||||
@ -1664,8 +1665,7 @@ void visit_antipodals (Idx& ia, Idx &ib, Fn &&fn)
|
||||
std::swap(current, other);
|
||||
}
|
||||
|
||||
if (ia.idx() == a_start) a_finished = true;
|
||||
if (ib.idx() == b_start) b_finished = true;
|
||||
if (initial->idx() == start) finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1702,8 +1702,8 @@ bool intersects(const Polygon &A, const Polygon &B)
|
||||
BoundingBox bbA{{A[bA.xmin].x(), A[bA.ymin].y()}, {A[bA.xmax].x(), A[bA.ymax].y()}};
|
||||
BoundingBox bbB{{B[bB.xmin].x(), B[bB.ymin].y()}, {B[bB.xmax].x(), B[bB.ymax].y()}};
|
||||
|
||||
if (!bbA.overlap(bbB))
|
||||
return false;
|
||||
// if (!bbA.overlap(bbB))
|
||||
// return false;
|
||||
|
||||
// Establish starting antipodals as extreme vertex pairs in X or Y direction
|
||||
// which reside on different polygons. If no such pair is found, the two
|
||||
|
@ -3203,6 +3203,14 @@ void GCodeViewer::render_shells()
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
|
||||
// when the background processing is enabled, it may happen that the shells data have been loaded
|
||||
// before opengl has been initialized for the preview canvas.
|
||||
// when this happens, the volumes' data have not been sent to gpu yet.
|
||||
for (GLVolume* v : m_shells.volumes.volumes) {
|
||||
if (!v->indexed_vertex_array.has_VBOs())
|
||||
v->finalize_geometry(true);
|
||||
}
|
||||
|
||||
// glsafe(::glDepthMask(GL_FALSE));
|
||||
|
||||
shader->start_using();
|
||||
|
@ -382,46 +382,57 @@ int ObjectList::get_mesh_errors_count(const int obj_idx, const int vol_idx /*= -
|
||||
|
||||
static std::string get_warning_icon_name(const TriangleMeshStats& stats)
|
||||
{
|
||||
return stats.repaired() ? (stats.manifold() ? "exclamation_manifold" : "exclamation") : "";
|
||||
return stats.manifold() ? (stats.repaired() ? "exclamation_manifold" : "") : "exclamation";
|
||||
}
|
||||
|
||||
std::pair<wxString, std::string> ObjectList::get_mesh_errors(const int obj_idx, const int vol_idx /*= -1*/, bool from_plater /*= false*/) const
|
||||
std::pair<wxString, std::string> ObjectList::get_mesh_errors(const int obj_idx, const int vol_idx /*= -1*/, wxString* sidebar_info /*= nullptr*/) const
|
||||
{
|
||||
const int errors = get_mesh_errors_count(obj_idx, vol_idx);
|
||||
|
||||
if (errors == 0)
|
||||
return { {}, {} }; // hide tooltip
|
||||
|
||||
// Create tooltip string, if there are errors
|
||||
wxString tooltip = format_wxstr(_L_PLURAL("Auto-repaired %1$d error", "Auto-repaired %1$d errors", errors), errors) + ":\n";
|
||||
|
||||
const TriangleMeshStats& stats = vol_idx == -1 ?
|
||||
(*m_objects)[obj_idx]->get_object_stl_stats() :
|
||||
(*m_objects)[obj_idx]->volumes[vol_idx]->mesh().stats();
|
||||
|
||||
if (stats.degenerate_facets > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d degenerate facet", "%1$d degenerate facets", stats.degenerate_facets), stats.degenerate_facets) + "\n";
|
||||
if (stats.edges_fixed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d edge fixed", "%1$d edges fixed", stats.edges_fixed), stats.edges_fixed) + "\n";
|
||||
if (stats.facets_removed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet removed", "%1$d facets removed", stats.facets_removed), stats.facets_removed) + "\n";
|
||||
if (stats.facets_reversed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet reversed", "%1$d facets reversed", stats.facets_reversed), stats.facets_reversed) + "\n";
|
||||
if (stats.backwards_edges > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d backwards edge", "%1$d backwards edges", stats.backwards_edges), stats.backwards_edges) + "\n";
|
||||
if (!stats.repaired() && stats.manifold()) {
|
||||
if (sidebar_info)
|
||||
*sidebar_info = _L("No errors detected");
|
||||
return { {}, {} }; // hide tooltip
|
||||
}
|
||||
|
||||
wxString tooltip, auto_repaired_info, remaining_info;
|
||||
|
||||
// Create tooltip string, if there are errors
|
||||
if (stats.repaired()) {
|
||||
const int errors = get_mesh_errors_count(obj_idx, vol_idx);
|
||||
auto_repaired_info = format_wxstr(_L_PLURAL("Auto-repaired %1$d error", "Auto-repaired %1$d errors", errors), errors);
|
||||
tooltip += auto_repaired_info +":\n";
|
||||
|
||||
if (stats.degenerate_facets > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d degenerate facet", "%1$d degenerate facets", stats.degenerate_facets), stats.degenerate_facets) + "\n";
|
||||
if (stats.edges_fixed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d edge fixed", "%1$d edges fixed", stats.edges_fixed), stats.edges_fixed) + "\n";
|
||||
if (stats.facets_removed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet removed", "%1$d facets removed", stats.facets_removed), stats.facets_removed) + "\n";
|
||||
if (stats.facets_reversed > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d facet reversed", "%1$d facets reversed", stats.facets_reversed), stats.facets_reversed) + "\n";
|
||||
if (stats.backwards_edges > 0)
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d backwards edge", "%1$d backwards edges", stats.backwards_edges), stats.backwards_edges) + "\n";
|
||||
}
|
||||
if (!stats.manifold()) {
|
||||
remaining_info = format_wxstr(_L_PLURAL("Remaining %1$d open edge", "Remaining %1$d open edges", stats.open_edges), stats.open_edges);
|
||||
|
||||
tooltip += _L("Remaning errors") + ":\n";
|
||||
tooltip += "\t" + format_wxstr(_L_PLURAL("%1$d open edge", "%1$d open edges", stats.open_edges), stats.open_edges) + "\n";
|
||||
}
|
||||
|
||||
if (is_windows10() && !from_plater)
|
||||
if (sidebar_info)
|
||||
*sidebar_info = stats.manifold() ? auto_repaired_info : (remaining_info + (stats.repaired() ? ("\n" + auto_repaired_info) : ""));
|
||||
|
||||
if (is_windows10() && !sidebar_info)
|
||||
tooltip += "\n" + _L("Right button click the icon to fix STL through Netfabb");
|
||||
|
||||
return { tooltip, get_warning_icon_name(stats) };
|
||||
}
|
||||
|
||||
std::pair<wxString, std::string> ObjectList::get_mesh_errors(bool from_plater /*= false*/)
|
||||
std::pair<wxString, std::string> ObjectList::get_mesh_errors(wxString* sidebar_info /*= nullptr*/)
|
||||
{
|
||||
if (!GetSelection())
|
||||
return { "", "" };
|
||||
@ -429,7 +440,7 @@ std::pair<wxString, std::string> ObjectList::get_mesh_errors(bool from_plater /*
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx);
|
||||
|
||||
return get_mesh_errors(obj_idx, vol_idx, from_plater);
|
||||
return get_mesh_errors(obj_idx, vol_idx, sidebar_info);
|
||||
}
|
||||
|
||||
void ObjectList::set_tooltip_for_item(const wxPoint& pt)
|
||||
|
@ -217,8 +217,8 @@ public:
|
||||
// Return value is a pair <Tooltip, warning_icon_name>, used for the tooltip and related warning icon
|
||||
// Function without parameters is for a call from Manipulation panel,
|
||||
// when we don't know parameters of selected item
|
||||
std::pair<wxString, std::string> get_mesh_errors(const int obj_idx, const int vol_idx = -1, bool from_plater = false) const;
|
||||
std::pair<wxString, std::string> get_mesh_errors(bool from_plater = false);
|
||||
std::pair<wxString, std::string> get_mesh_errors(const int obj_idx, const int vol_idx = -1, wxString* sidebar_info = nullptr) const;
|
||||
std::pair<wxString, std::string> get_mesh_errors(wxString* sidebar_info = nullptr);
|
||||
void set_tooltip_for_item(const wxPoint& pt);
|
||||
|
||||
void selection_changed();
|
||||
|
@ -962,10 +962,9 @@ void Preview::load_print_as_fff(bool keep_z_range)
|
||||
if (0 <= type && type < static_cast<int>(GCodeViewer::EViewType::Count)) {
|
||||
m_choice_view_type->SetSelection(type);
|
||||
m_canvas->set_gcode_view_preview_type(static_cast<GCodeViewer::EViewType>(type));
|
||||
if (wxGetApp().is_gcode_viewer()) {
|
||||
if (wxGetApp().is_gcode_viewer())
|
||||
m_keep_current_preview_type = true;
|
||||
refresh_print();
|
||||
}
|
||||
refresh_print();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,14 @@
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "GLCanvas3D.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
#include "Tab.hpp"
|
||||
#include "libslic3r/AppConfig.hpp"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/PresetBundle.hpp"
|
||||
#include "libslic3r/Preset.hpp"
|
||||
#include "libslic3r/Config.hpp"
|
||||
#include "libslic3r/PrintConfig.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
@ -159,6 +163,33 @@ TagCheckResult tag_check_system(const std::string& tag)
|
||||
return TagCheckNotCompatible;
|
||||
}
|
||||
|
||||
TagCheckResult tag_check_material(const std::string& tag)
|
||||
{
|
||||
if (const GUI::Tab* tab = wxGetApp().get_tab(Preset::Type::TYPE_FILAMENT)) {
|
||||
// search PrintConfig filament_type to find if allowed tag
|
||||
if (wxGetApp().app_config->get("filament_type").find(tag)) {
|
||||
const Preset& preset = tab->m_presets->get_edited_preset();
|
||||
const auto* opt = preset.config.opt<ConfigOptionStrings>("filament_type");
|
||||
if (opt->values[0] == tag)
|
||||
return TagCheckAffirmative;
|
||||
return TagCheckNegative;
|
||||
}
|
||||
return TagCheckNotCompatible;
|
||||
}
|
||||
/* TODO: SLA materials
|
||||
else if (const GUI::Tab* tab = wxGetApp().get_tab(Preset::Type::TYPE_SLA_MATERIAL)) {
|
||||
//if (wxGetApp().app_config->get("material_type").find(tag)) {
|
||||
const Preset& preset = tab->m_presets->get_edited_preset();
|
||||
const auto* opt = preset.config.opt<ConfigOptionStrings>("material_type");
|
||||
if (opt->values[0] == tag)
|
||||
return TagCheckAffirmative;
|
||||
return TagCheckNegative;
|
||||
//}
|
||||
return TagCheckNotCompatible;
|
||||
}*/
|
||||
return TagCheckNotCompatible;
|
||||
}
|
||||
|
||||
// return true if NOT in disabled mode.
|
||||
bool tags_check(const std::string& disabled_tags, const std::string& enabled_tags)
|
||||
{
|
||||
@ -189,6 +220,11 @@ bool tags_check(const std::string& disabled_tags, const std::string& enabled_tag
|
||||
if (result == TagCheckResult::TagCheckAffirmative)
|
||||
continue;
|
||||
result = tag_check_system(tag);
|
||||
if (result == TagCheckResult::TagCheckNegative)
|
||||
return false;
|
||||
if (result == TagCheckResult::TagCheckAffirmative)
|
||||
continue;
|
||||
result = tag_check_material(tag);
|
||||
if (result == TagCheckResult::TagCheckNegative)
|
||||
return false;
|
||||
if (result == TagCheckResult::TagCheckAffirmative)
|
||||
@ -225,6 +261,11 @@ bool tags_check(const std::string& disabled_tags, const std::string& enabled_tag
|
||||
if (result == TagCheckResult::TagCheckAffirmative)
|
||||
return false;
|
||||
result = tag_check_system(tag);
|
||||
if (result == TagCheckResult::TagCheckAffirmative)
|
||||
return false;
|
||||
if (result == TagCheckResult::TagCheckNegative)
|
||||
continue;
|
||||
result = tag_check_material(tag);
|
||||
if (result == TagCheckResult::TagCheckAffirmative)
|
||||
return false;
|
||||
if (result == TagCheckResult::TagCheckNegative)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <wx/numdlg.h>
|
||||
#include <wx/debug.h>
|
||||
#include <wx/busyinfo.h>
|
||||
#include <wx/richtooltip.h>
|
||||
|
||||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Format/STL.hpp"
|
||||
@ -173,13 +174,10 @@ ObjectInfo::ObjectInfo(wxWindow *parent) :
|
||||
label_materials = init_info_label(&info_materials, _L("Materials"));
|
||||
Add(grid_sizer, 0, wxEXPAND);
|
||||
|
||||
auto *info_manifold_text = new wxStaticText(parent, wxID_ANY, _L("Manifold") + ":");
|
||||
info_manifold_text->SetFont(wxGetApp().small_font());
|
||||
info_manifold = new wxStaticText(parent, wxID_ANY, "");
|
||||
info_manifold->SetFont(wxGetApp().small_font());
|
||||
manifold_warning_icon = new wxStaticBitmap(parent, wxID_ANY, create_scaled_bitmap(m_warning_icon_name));
|
||||
auto *sizer_manifold = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer_manifold->Add(info_manifold_text, 0);
|
||||
sizer_manifold->Add(manifold_warning_icon, 0, wxLEFT, 2);
|
||||
sizer_manifold->Add(info_manifold, 0, wxLEFT, 2);
|
||||
Add(sizer_manifold, 0, wxEXPAND | wxTOP, 4);
|
||||
@ -201,10 +199,10 @@ void ObjectInfo::msw_rescale()
|
||||
|
||||
void ObjectInfo::update_warning_icon(const std::string& warning_icon_name)
|
||||
{
|
||||
if (warning_icon_name.empty())
|
||||
return;
|
||||
m_warning_icon_name = warning_icon_name;
|
||||
manifold_warning_icon->SetBitmap(create_scaled_bitmap(m_warning_icon_name));
|
||||
if (showing_manifold_warning_icon = !warning_icon_name.empty()) {
|
||||
m_warning_icon_name = warning_icon_name;
|
||||
manifold_warning_icon->SetBitmap(create_scaled_bitmap(m_warning_icon_name));
|
||||
}
|
||||
}
|
||||
|
||||
enum SlicedInfoIdx
|
||||
@ -611,6 +609,7 @@ struct Sidebar::priv
|
||||
|
||||
wxButton *btn_export_gcode;
|
||||
wxButton *btn_reslice;
|
||||
wxString btn_reslice_tip;
|
||||
ScalableButton *btn_send_gcode;
|
||||
//ScalableButton *btn_eject_device;
|
||||
ScalableButton* btn_export_gcode_removable; //exports to removable drives (appears only if removable drive is connected)
|
||||
@ -622,6 +621,7 @@ struct Sidebar::priv
|
||||
~priv();
|
||||
|
||||
void show_preset_comboboxes();
|
||||
void show_rich_tip(const wxString& tooltip, wxButton* btn);
|
||||
};
|
||||
|
||||
Sidebar::priv::~priv()
|
||||
@ -650,6 +650,18 @@ void Sidebar::priv::show_preset_comboboxes()
|
||||
scrolled->Refresh();
|
||||
}
|
||||
|
||||
void Sidebar::priv::show_rich_tip(const wxString& tooltip, wxButton* btn)
|
||||
{
|
||||
if (tooltip.IsEmpty())
|
||||
return;
|
||||
wxRichToolTip tip(tooltip, "");
|
||||
tip.SetIcon(wxICON_NONE);
|
||||
tip.SetTipKind(wxTipKind_BottomRight);
|
||||
tip.SetTitleFont(wxGetApp().normal_font());
|
||||
tip.SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
tip.SetTimeout(1200);
|
||||
tip.ShowFor(btn);
|
||||
}
|
||||
|
||||
// Sidebar / public
|
||||
|
||||
@ -784,7 +796,11 @@ Sidebar::Sidebar(Plater *parent)
|
||||
#endif //__APPLE__
|
||||
ScalableBitmap bmp = ScalableBitmap(this, icon_name, bmp_px_cnt);
|
||||
*btn = new ScalableButton(this, wxID_ANY, bmp, "", wxBU_EXACTFIT);
|
||||
(*btn)->SetToolTip(tooltip);
|
||||
|
||||
(*btn)->Bind(wxEVT_ENTER_WINDOW, [tooltip, btn, this](wxMouseEvent& event) {
|
||||
p->show_rich_tip(tooltip, *btn);
|
||||
event.Skip();
|
||||
});
|
||||
(*btn)->Hide();
|
||||
};
|
||||
|
||||
@ -843,6 +859,11 @@ Sidebar::Sidebar(Plater *parent)
|
||||
p->plater->reslice();
|
||||
p->plater->select_view_3D("Preview");
|
||||
});
|
||||
|
||||
p->btn_reslice->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& event) {
|
||||
p->show_rich_tip(p->btn_reslice_tip, p->btn_reslice);
|
||||
event.Skip();
|
||||
});
|
||||
p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); });
|
||||
// p->btn_eject_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); });
|
||||
p->btn_export_gcode_removable->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->export_gcode(true); });
|
||||
@ -970,7 +991,7 @@ void Sidebar::update_reslice_btn_tooltip() const
|
||||
wxString tooltip = wxString("Slice") + " [" + GUI::shortkey_ctrl_prefix() + "R]";
|
||||
if (m_mode != comSimple)
|
||||
tooltip += wxString("\n") + _L("Hold Shift to Slice & Export G-code");
|
||||
p->btn_reslice->SetToolTip(tooltip);
|
||||
p->btn_reslice_tip = tooltip;
|
||||
}
|
||||
|
||||
void Sidebar::msw_rescale()
|
||||
@ -1144,24 +1165,13 @@ void Sidebar::show_info_sizer()
|
||||
p->object_info->info_facets->SetLabel(format_wxstr(_L_PLURAL("%1% (%2$d shell)", "%1% (%2$d shells)", stats.number_of_parts),
|
||||
static_cast<int>(model_object->facets_count()), stats.number_of_parts));
|
||||
|
||||
if (stats.repaired()) {
|
||||
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + stats.facets_reversed + stats.backwards_edges;
|
||||
p->object_info->info_manifold->SetLabel(format_wxstr(_L_PLURAL("Auto-repaired %1$d error", "Auto-repaired %1$d errors", errors), errors));
|
||||
|
||||
auto mesh_errors = obj_list()->get_mesh_errors(true);
|
||||
wxString tooltip = mesh_errors.first;
|
||||
|
||||
p->object_info->update_warning_icon(mesh_errors.second);
|
||||
p->object_info->showing_manifold_warning_icon = true;
|
||||
p->object_info->info_manifold->SetToolTip(tooltip);
|
||||
p->object_info->manifold_warning_icon->SetToolTip(tooltip);
|
||||
}
|
||||
else {
|
||||
p->object_info->info_manifold->SetLabel(_L("Yes"));
|
||||
p->object_info->showing_manifold_warning_icon = false;
|
||||
p->object_info->info_manifold->SetToolTip("");
|
||||
p->object_info->manifold_warning_icon->SetToolTip("");
|
||||
}
|
||||
wxString info_manifold_label;
|
||||
auto mesh_errors = obj_list()->get_mesh_errors(&info_manifold_label);
|
||||
wxString tooltip = mesh_errors.first;
|
||||
p->object_info->update_warning_icon(mesh_errors.second);
|
||||
p->object_info->info_manifold->SetLabel(info_manifold_label);
|
||||
p->object_info->info_manifold->SetToolTip(tooltip);
|
||||
p->object_info->manifold_warning_icon->SetToolTip(tooltip);
|
||||
|
||||
p->object_info->show_sizer(true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user