Changed Manipulation panel. (Simple mode)There is exclamation mark icon next for the object name, if it has errors.
+ some code refactoring
This commit is contained in:
parent
e9d629f248
commit
203e9e848c
@ -193,6 +193,106 @@ void ObjectList::create_popup_menus()
|
||||
create_instance_popupmenu(&m_menu_instance);
|
||||
}
|
||||
|
||||
void ObjectList::get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& input_item/* = wxDataViewItem(0)*/)
|
||||
{
|
||||
const wxDataViewItem item = input_item == wxDataViewItem(0) ? GetSelection() : input_item;
|
||||
|
||||
if (!item)
|
||||
{
|
||||
obj_idx = vol_idx = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const ItemType type = m_objects_model->GetItemType(item);
|
||||
|
||||
obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) :
|
||||
type & itVolume ? m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)) : -1;
|
||||
|
||||
vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1;
|
||||
}
|
||||
|
||||
int ObjectList::get_mesh_errors_count(const int obj_idx, const int vol_idx /*= -1*/) const
|
||||
{
|
||||
if (obj_idx < 0)
|
||||
return 0;
|
||||
|
||||
int errors = 0;
|
||||
|
||||
std::vector<ModelVolume*> volumes;
|
||||
if (vol_idx == -1)
|
||||
volumes = (*m_objects)[obj_idx]->volumes;
|
||||
else
|
||||
volumes.emplace_back((*m_objects)[obj_idx]->volumes[vol_idx]);
|
||||
|
||||
for (ModelVolume* volume : volumes)
|
||||
{
|
||||
const stl_stats& stats = volume->mesh.stl.stats;
|
||||
|
||||
errors += stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
wxString ObjectList::get_mesh_errors_list(const int obj_idx, const int vol_idx /*= -1*/) 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 = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors);
|
||||
|
||||
std::vector<ModelVolume*> volumes;
|
||||
if (vol_idx == -1)
|
||||
volumes = (*m_objects)[obj_idx]->volumes;
|
||||
else
|
||||
volumes.emplace_back((*m_objects)[obj_idx]->volumes[vol_idx]);
|
||||
|
||||
std::map<std::string, int> error_msg = {
|
||||
{L("degenerate facets") , 0},
|
||||
{L("edges fixed") , 0},
|
||||
{L("facets removed") , 0},
|
||||
{L("facets added") , 0},
|
||||
{L("facets reversed") , 0},
|
||||
{L("backwards edges") , 0}
|
||||
};
|
||||
|
||||
for (ModelVolume* volume : volumes)
|
||||
{
|
||||
const stl_stats& stats = volume->mesh.stl.stats;
|
||||
|
||||
error_msg[L("degenerate facets")] += stats.degenerate_facets;
|
||||
error_msg[L("edges fixed")] += stats.edges_fixed;
|
||||
error_msg[L("facets removed")] += stats.facets_removed;
|
||||
error_msg[L("facets added")] += stats.facets_added;
|
||||
error_msg[L("facets reversed")] += stats.facets_reversed;
|
||||
error_msg[L("backwards edges")] += stats.backwards_edges;
|
||||
}
|
||||
|
||||
for (const auto& error : error_msg)
|
||||
if (error.second > 0)
|
||||
tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first);
|
||||
|
||||
if (is_windows10())
|
||||
tooltip += _(L("Right button click the icon to fix STL through Netfabb"));
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
wxString ObjectList::get_mesh_errors_list()
|
||||
{
|
||||
if (!GetSelection())
|
||||
return "";
|
||||
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx);
|
||||
|
||||
return get_mesh_errors_list(obj_idx, vol_idx);
|
||||
}
|
||||
|
||||
void ObjectList::set_tooltip_for_item(const wxPoint& pt)
|
||||
{
|
||||
wxDataViewItem item;
|
||||
@ -202,38 +302,11 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt)
|
||||
|
||||
if (col->GetTitle() == " " && GetSelectedItemsCount()<2)
|
||||
GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings")));
|
||||
else if (col->GetTitle() == _("Name") &&
|
||||
m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) {
|
||||
int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats;
|
||||
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
|
||||
wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors);
|
||||
|
||||
std::map<std::string, int> error_msg;
|
||||
error_msg[L("degenerate facets")] = stats.degenerate_facets;
|
||||
error_msg[L("edges fixed")] = stats.edges_fixed;
|
||||
error_msg[L("facets removed")] = stats.facets_removed;
|
||||
error_msg[L("facets added")] = stats.facets_added;
|
||||
error_msg[L("facets reversed")] = stats.facets_reversed;
|
||||
error_msg[L("backwards edges")] = stats.backwards_edges;
|
||||
|
||||
for (auto error : error_msg)
|
||||
{
|
||||
if (error.second > 0)
|
||||
tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first);
|
||||
}
|
||||
// OR
|
||||
// tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, "
|
||||
// "%d facets added, %d facets reversed, %d backwards edges")),
|
||||
// stats.degenerate_facets, stats.edges_fixed, stats.facets_removed,
|
||||
// stats.facets_added, stats.facets_reversed, stats.backwards_edges);
|
||||
|
||||
if (is_windows10())
|
||||
tooltip += _(L("Right button click the icon to fix STL through Netfabb"));
|
||||
|
||||
GetMainWindow()->SetToolTip(tooltip);
|
||||
else if (col->GetTitle() == _("Name") )
|
||||
{
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx, item);
|
||||
GetMainWindow()->SetToolTip(get_mesh_errors_list(obj_idx, vol_idx));
|
||||
}
|
||||
else
|
||||
GetMainWindow()->SetToolTip(""); // hide tooltip
|
||||
@ -533,10 +606,12 @@ void ObjectList::OnContextMenu(wxDataViewEvent&)
|
||||
|
||||
if (title == " ")
|
||||
show_context_menu();
|
||||
else if (title == _("Name") && pt.x >15 &&
|
||||
m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData())
|
||||
else if (title == _("Name") && pt.x > 1.6f*wxGetApp().em_unit() && pt.x < 3.2f*wxGetApp().em_unit())
|
||||
{
|
||||
if (is_windows10())
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx, item);
|
||||
|
||||
if (is_windows10() && get_mesh_errors_count(obj_idx, vol_idx) > 0)
|
||||
fix_through_netfabb();
|
||||
}
|
||||
|
||||
@ -1729,6 +1804,7 @@ void ObjectList::parts_changed(int obj_idx)
|
||||
void ObjectList::part_selection_changed()
|
||||
{
|
||||
int obj_idx = -1;
|
||||
int volume_id = -1;
|
||||
m_config = nullptr;
|
||||
wxString og_name = wxEmptyString;
|
||||
|
||||
@ -1775,7 +1851,7 @@ void ObjectList::part_selection_changed()
|
||||
}
|
||||
else if (m_objects_model->GetItemType(item) == itVolume) {
|
||||
og_name = _(L("Part manipulation"));
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config;
|
||||
update_and_show_manipulations = true;
|
||||
}
|
||||
@ -1795,7 +1871,11 @@ void ObjectList::part_selection_changed()
|
||||
|
||||
if (update_and_show_manipulations) {
|
||||
wxGetApp().obj_manipul()->get_og()->set_name(" " + og_name + " ");
|
||||
wxGetApp().obj_manipul()->get_og()->set_value("object_name", m_objects_model->GetName(GetSelection()));
|
||||
|
||||
if (item) {
|
||||
wxGetApp().obj_manipul()->get_og()->set_value("object_name", m_objects_model->GetName(item));
|
||||
wxGetApp().obj_manipul()->update_manifold_warning_icon_state(get_mesh_errors_list(obj_idx, volume_id));
|
||||
}
|
||||
}
|
||||
|
||||
if (update_and_show_settings)
|
||||
@ -1815,16 +1895,13 @@ void ObjectList::part_selection_changed()
|
||||
void ObjectList::add_object_to_list(size_t obj_idx)
|
||||
{
|
||||
auto model_object = (*m_objects)[obj_idx];
|
||||
wxString item_name = from_u8(model_object->name);
|
||||
const wxString& item_name = from_u8(model_object->name);
|
||||
const auto item = m_objects_model->Add(item_name,
|
||||
!model_object->config.has("extruder") ? 0 :
|
||||
model_object->config.option<ConfigOptionInt>("extruder")->value);
|
||||
|
||||
// Add error icon if detected auto-repaire
|
||||
auto stats = model_object->volumes[0]->mesh.stl.stats;
|
||||
int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
if (errors > 0) {
|
||||
if (get_mesh_errors_count(obj_idx) > 0) {
|
||||
wxVariant variant;
|
||||
variant << PrusaDataViewBitmapText(item_name, m_bmp_manifold_warning);
|
||||
m_objects_model->SetValue(variant, item, 0);
|
||||
@ -2641,18 +2718,10 @@ void ObjectList::rename_item()
|
||||
update_name_in_model(item);
|
||||
}
|
||||
|
||||
void ObjectList::fix_through_netfabb() const
|
||||
void ObjectList::fix_through_netfabb()
|
||||
{
|
||||
const wxDataViewItem item = GetSelection();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
const ItemType type = m_objects_model->GetItemType(item);
|
||||
|
||||
const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) :
|
||||
type & itVolume ? m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)) : -1;
|
||||
|
||||
const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1;
|
||||
int obj_idx, vol_idx;
|
||||
get_selected_item_indexes(obj_idx, vol_idx);
|
||||
|
||||
wxGetApp().plater()->fix_through_netfabb(obj_idx, vol_idx);
|
||||
|
||||
@ -2666,16 +2735,10 @@ void ObjectList::update_item_error_icon(const int obj_idx, const int vol_idx) co
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
auto model_object = (*m_objects)[obj_idx];
|
||||
|
||||
const stl_stats& stats = model_object->volumes[vol_idx<0 ? 0 : vol_idx]->mesh.stl.stats;
|
||||
const int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
|
||||
stats.facets_added + stats.facets_reversed + stats.backwards_edges;
|
||||
|
||||
if (errors == 0) {
|
||||
if (get_mesh_errors_count(obj_idx, vol_idx) == 0) {
|
||||
// delete Error_icon if all errors are fixed
|
||||
wxVariant variant;
|
||||
variant << PrusaDataViewBitmapText(from_u8(model_object->name), wxNullBitmap);
|
||||
variant << PrusaDataViewBitmapText(from_u8((*m_objects)[obj_idx]->name), wxNullBitmap);
|
||||
m_objects_model->SetValue(variant, item, 0);
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +177,16 @@ public:
|
||||
|
||||
void init_icons();
|
||||
|
||||
// Get obj_idx and vol_idx values for the selected (by default) or an adjusted item
|
||||
void get_selected_item_indexes(int& obj_idx, int& vol_idx, const wxDataViewItem& item = wxDataViewItem(0));
|
||||
// Get count of errors in the mesh
|
||||
int get_mesh_errors_count(const int obj_idx, const int vol_idx = -1) const;
|
||||
/* Get list of errors in the mesh. Return value is a string, used for the tooltip
|
||||
* Function without parameters is for a call from Manipulation panel,
|
||||
* when we don't know parameters of selected item
|
||||
*/
|
||||
wxString get_mesh_errors_list(const int obj_idx, const int vol_idx = -1) const;
|
||||
wxString get_mesh_errors_list();
|
||||
void set_tooltip_for_item(const wxPoint& pt);
|
||||
|
||||
void selection_changed();
|
||||
@ -285,7 +295,7 @@ public:
|
||||
void instances_to_separated_objects(const int obj_idx);
|
||||
void split_instances();
|
||||
void rename_item();
|
||||
void fix_through_netfabb() const;
|
||||
void fix_through_netfabb();
|
||||
void update_item_error_icon(const int obj_idx, int vol_idx) const ;
|
||||
|
||||
void paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& volumes);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "Selection.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "slic3r/Utils/FixModelByWin10.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
@ -20,6 +21,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
||||
OG_Settings(parent, true)
|
||||
#ifndef __APPLE__
|
||||
, m_focused_option("")
|
||||
, m_manifold_warning_bmp(create_scaled_bitmap(parent, "exclamation"))
|
||||
#endif // __APPLE__
|
||||
{
|
||||
m_og->set_name(_(L("Object Manipulation")));
|
||||
@ -42,17 +44,47 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
||||
ConfigOptionDef def;
|
||||
|
||||
// Objects(sub-objects) name
|
||||
def.label = L("Name");
|
||||
// def.label = L("Name");
|
||||
// def.gui_type = "legend";
|
||||
// def.tooltip = L("Object name");
|
||||
// def.width = 21 * wxGetApp().em_unit();
|
||||
// def.default_value = new ConfigOptionString{ " " };
|
||||
// m_og->append_single_option_line(Option(def, "object_name"));
|
||||
|
||||
Line line = Line{ "Name", "Object name" };
|
||||
|
||||
auto manifold_warning_icon = [this](wxWindow* parent) {
|
||||
m_fix_throught_netfab_bitmap = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap);
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(m_fix_throught_netfab_bitmap);
|
||||
|
||||
if (is_windows10())
|
||||
m_fix_throught_netfab_bitmap->Bind(wxEVT_CONTEXT_MENU, [this](wxCommandEvent &e)
|
||||
{
|
||||
// if object/sub-object has no errors
|
||||
if (m_fix_throught_netfab_bitmap->GetBitmap().GetRefData() == wxNullBitmap.GetRefData())
|
||||
return;
|
||||
|
||||
wxGetApp().obj_list()->fix_through_netfabb();
|
||||
update_manifold_warning_icon_state(wxGetApp().obj_list()->get_mesh_errors_list());
|
||||
});
|
||||
|
||||
return sizer;
|
||||
};
|
||||
|
||||
line.append_widget(manifold_warning_icon);
|
||||
def.label = "";
|
||||
def.gui_type = "legend";
|
||||
def.tooltip = L("Object name");
|
||||
def.width = 21 * wxGetApp().em_unit();
|
||||
def.default_value = new ConfigOptionString{ " " };
|
||||
m_og->append_single_option_line(Option(def, "object_name"));
|
||||
line.append_option(Option(def, "object_name"));
|
||||
m_og->append_line(line);
|
||||
|
||||
const int field_width = 5 * wxGetApp().em_unit()/*50*/;
|
||||
|
||||
// Legend for object modification
|
||||
auto line = Line{ "", "" };
|
||||
line = Line{ "", "" };
|
||||
def.label = "";
|
||||
def.type = coString;
|
||||
def.width = field_width/*50*/;
|
||||
@ -334,6 +366,14 @@ void ObjectManipulation::emulate_kill_focus()
|
||||
else
|
||||
on_change(option, 0);
|
||||
}
|
||||
|
||||
void ObjectManipulation::update_manifold_warning_icon_state(const wxString& tooltip)
|
||||
{
|
||||
m_fix_throught_netfab_bitmap->SetBitmap(tooltip.IsEmpty() ? wxNullBitmap : m_manifold_warning_bmp);
|
||||
|
||||
m_fix_throught_netfab_bitmap->SetToolTip(tooltip);
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
void ObjectManipulation::reset_settings_value()
|
||||
|
@ -78,6 +78,9 @@ class ObjectManipulation : public OG_Settings
|
||||
bool m_uniform_scale {true};
|
||||
PrusaLockButton* m_lock_bnt{ nullptr };
|
||||
|
||||
wxBitmap m_manifold_warning_bmp;
|
||||
wxStaticBitmap* m_fix_throught_netfab_bitmap;
|
||||
|
||||
#ifndef __APPLE__
|
||||
// Currently focused option name (empty if none)
|
||||
std::string m_focused_option;
|
||||
@ -107,6 +110,8 @@ public:
|
||||
void emulate_kill_focus();
|
||||
#endif // __APPLE__
|
||||
|
||||
void update_manifold_warning_icon_state(const wxString& tooltip);
|
||||
|
||||
private:
|
||||
void reset_settings_value();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user