mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-24 01:01:15 -06:00
Merge branch 'master' of https://github.com/prusa3d/Slic3r
This commit is contained in:
commit
69f81120e0
22 changed files with 1709 additions and 1361 deletions
|
|
@ -28,6 +28,7 @@
|
|||
#include <boost/filesystem.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include "I18N.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
|
@ -81,13 +82,14 @@ void BackgroundSlicingProcess::process_fff()
|
|||
std::string export_path = m_fff_print->print_statistics().finalize_output_path(m_export_path);
|
||||
if (copy_file(m_temp_output_path, export_path) != 0)
|
||||
throw std::runtime_error("Copying of the temporary G-code to the output G-code failed");
|
||||
m_print->set_status(95, "Running post-processing scripts");
|
||||
m_print->set_status(95, L("Running post-processing scripts"));
|
||||
run_post_process_scripts(export_path, m_fff_print->config());
|
||||
m_print->set_status(100, "G-code file exported to " + export_path);
|
||||
// #ys_FIXME_localization
|
||||
m_print->set_status(100, L("G-code file exported to ") + export_path);
|
||||
} else if (! m_upload_job.empty()) {
|
||||
prepare_upload();
|
||||
} else {
|
||||
m_print->set_status(100, "Slicing complete");
|
||||
m_print->set_status(100, L("Slicing complete"));
|
||||
}
|
||||
this->set_step_done(bspsGCodeFinalize);
|
||||
}
|
||||
|
|
@ -101,11 +103,12 @@ void BackgroundSlicingProcess::process_sla()
|
|||
if (! m_export_path.empty()) {
|
||||
const std::string export_path = m_sla_print->print_statistics().finalize_output_path(m_export_path);
|
||||
m_sla_print->export_raster(export_path);
|
||||
m_print->set_status(100, "Masked SLA file exported to " + export_path);
|
||||
// #ys_FIXME_localization
|
||||
m_print->set_status(100, L("Masked SLA file exported to ") + export_path);
|
||||
} else if (! m_upload_job.empty()) {
|
||||
prepare_upload();
|
||||
} else {
|
||||
m_print->set_status(100, "Slicing complete");
|
||||
m_print->set_status(100, L("Slicing complete"));
|
||||
}
|
||||
this->set_step_done(bspsGCodeFinalize);
|
||||
}
|
||||
|
|
@ -394,7 +397,7 @@ void BackgroundSlicingProcess::prepare_upload()
|
|||
/ boost::filesystem::unique_path("." SLIC3R_APP_KEY ".upload.%%%%-%%%%-%%%%-%%%%");
|
||||
|
||||
if (m_print == m_fff_print) {
|
||||
m_print->set_status(95, "Running post-processing scripts");
|
||||
m_print->set_status(95, L("Running post-processing scripts"));
|
||||
if (copy_file(m_temp_output_path, source_path.string()) != 0) {
|
||||
throw std::runtime_error("Copying of the temporary G-code to the output G-code failed");
|
||||
}
|
||||
|
|
@ -405,7 +408,8 @@ void BackgroundSlicingProcess::prepare_upload()
|
|||
m_sla_print->export_raster(source_path.string(), m_upload_job.upload_data.upload_path.string());
|
||||
}
|
||||
|
||||
m_print->set_status(100, (boost::format("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue") % m_upload_job.printhost->get_host()).str());
|
||||
// #ys_FIXME_localization
|
||||
m_print->set_status(100, (boost::format(L("Scheduling upload to `%1%`. See Window -> Print Host Upload Queue")) % m_upload_job.printhost->get_host()).str());
|
||||
|
||||
m_upload_job.upload_data.source_path = std::move(source_path);
|
||||
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
|
|||
// Maximum height of an object changes when the object gets rotated or scaled.
|
||||
// Changing maximum height of an object will invalidate the layer heigth editing profile.
|
||||
// m_model_object->raw_bounding_box() is cached, therefore it is cheap even if this method is called frequently.
|
||||
float new_max_z = (m_model_object == nullptr) ? 0.f : m_model_object->raw_bounding_box().size().z();
|
||||
float new_max_z = (model_object_new == nullptr) ? 0.f : model_object_new->raw_bounding_box().size().z();
|
||||
if (m_model_object != model_object_new || this->last_object_id != object_id || m_object_max_z != new_max_z ||
|
||||
(model_object_new != nullptr && m_model_object->id() != model_object_new->id())) {
|
||||
m_layer_height_profile.clear();
|
||||
|
|
@ -795,7 +795,7 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GL
|
|||
if (msg_utf8.empty())
|
||||
return false;
|
||||
|
||||
wxString msg = GUI::from_u8(msg_utf8);
|
||||
wxString msg = _(msg_utf8);//GUI::from_u8(msg_utf8);
|
||||
|
||||
wxMemoryDC memDC;
|
||||
|
||||
|
|
|
|||
|
|
@ -311,13 +311,13 @@ bool GUI_App::dark_mode_menus()
|
|||
void GUI_App::init_label_colours()
|
||||
{
|
||||
if (dark_mode()) {
|
||||
m_color_label_modified = wxColour(252, 77, 1);
|
||||
m_color_label_sys = wxColour(26, 132, 57);
|
||||
}
|
||||
else {
|
||||
m_color_label_modified = wxColour(253, 111, 40);
|
||||
m_color_label_sys = wxColour(115, 220, 103);
|
||||
}
|
||||
else {
|
||||
m_color_label_modified = wxColour(252, 77, 1);
|
||||
m_color_label_sys = wxColour(26, 132, 57);
|
||||
}
|
||||
m_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,6 +193,76 @@ 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;
|
||||
|
||||
return (*m_objects)[obj_idx]->get_mesh_errors_count(vol_idx);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
const stl_stats& stats = vol_idx == -1 ?
|
||||
(*m_objects)[obj_idx]->get_object_stl_stats() :
|
||||
(*m_objects)[obj_idx]->volumes[vol_idx]->mesh.stl.stats;
|
||||
|
||||
std::map<std::string, int> error_msg = {
|
||||
{ L("degenerate facets"), stats.degenerate_facets },
|
||||
{ L("edges fixed"), stats.edges_fixed },
|
||||
{ L("facets removed"), stats.facets_removed },
|
||||
{ L("facets added"), stats.facets_added },
|
||||
{ L("facets reversed"), stats.facets_reversed },
|
||||
{ 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;
|
||||
|
|
@ -200,40 +270,24 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt)
|
|||
HitTest(pt, item, col);
|
||||
if (!item) return;
|
||||
|
||||
/* GetMainWindow() return window, associated with wxDataViewCtrl.
|
||||
* And for this window we should to set tooltips.
|
||||
* Just this->SetToolTip(tooltip) => has no effect.
|
||||
*/
|
||||
|
||||
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.bmp().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);
|
||||
else if (col->GetTitle() == _("Name"))
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
if (pt.x < 2 * wxGetApp().em_unit() || pt.x > 4 * wxGetApp().em_unit()) {
|
||||
GetMainWindow()->SetToolTip(""); // hide tooltip
|
||||
return;
|
||||
}
|
||||
// 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);
|
||||
#endif //__WXMSW__
|
||||
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
|
||||
|
|
@ -395,8 +449,8 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const
|
|||
|
||||
void ObjectList::init_icons()
|
||||
{
|
||||
m_bmp_modifiermesh = ScalableBitmap(nullptr, "add_modifier"); // Add part
|
||||
m_bmp_solidmesh = ScalableBitmap(nullptr, "add_part"); // Add modifier
|
||||
m_bmp_solidmesh = ScalableBitmap(nullptr, "add_part"); // Add part
|
||||
m_bmp_modifiermesh = ScalableBitmap(nullptr, "add_modifier"); // Add modifier
|
||||
m_bmp_support_enforcer = ScalableBitmap(nullptr, "support_enforcer");// Add support enforcer
|
||||
m_bmp_support_blocker = ScalableBitmap(nullptr, "support_blocker"); // Add support blocker
|
||||
|
||||
|
|
@ -412,6 +466,8 @@ void ObjectList::init_icons()
|
|||
|
||||
// init icon for manifold warning
|
||||
m_bmp_manifold_warning = ScalableBitmap(nullptr, "exclamation");
|
||||
// Set warning bitmap for the model
|
||||
m_objects_model->SetWarningBitmap(&m_bmp_manifold_warning.bmp());
|
||||
|
||||
// init bitmap for "Split to sub-objects" context menu
|
||||
m_bmp_split = ScalableBitmap(nullptr, "split_parts_SMALL");
|
||||
|
|
@ -425,8 +481,8 @@ void ObjectList::rescale_icons()
|
|||
m_bmp_vector.clear();
|
||||
m_bmp_vector.reserve(4); // bitmaps for different types of parts
|
||||
for (ScalableBitmap* bitmap : std::vector<ScalableBitmap*> {
|
||||
&m_bmp_modifiermesh, // Add part
|
||||
&m_bmp_solidmesh, // Add modifier
|
||||
&m_bmp_solidmesh, // Add part
|
||||
&m_bmp_modifiermesh, // Add modifier
|
||||
&m_bmp_support_enforcer, // Add support enforcer
|
||||
&m_bmp_support_blocker }) // Add support blocker
|
||||
{
|
||||
|
|
@ -437,6 +493,9 @@ void ObjectList::rescale_icons()
|
|||
m_objects_model->SetVolumeBitmaps(m_bmp_vector);
|
||||
|
||||
m_bmp_manifold_warning.msw_rescale();
|
||||
// Set warning bitmap for the model
|
||||
m_objects_model->SetWarningBitmap(&m_bmp_manifold_warning.bmp());
|
||||
|
||||
m_bmp_split.msw_rescale();
|
||||
m_bmp_cog.msw_rescale();
|
||||
|
||||
|
|
@ -498,7 +557,8 @@ void ObjectList::paste_volumes_into_list(int obj_idx, const ModelVolumePtrs& vol
|
|||
|
||||
for (const ModelVolume* volume : volumes)
|
||||
{
|
||||
auto vol_item = m_objects_model->AddVolumeChild(object_item, volume->name, volume->type(),
|
||||
const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(object_item, volume->name, volume->type(),
|
||||
volume->get_mesh_errors_count()>0 ,
|
||||
volume->config.has("extruder") ? volume->config.option<ConfigOptionInt>("extruder")->value : 0);
|
||||
auto opt_keys = volume->config.keys();
|
||||
if (!opt_keys.empty() && !((opt_keys.size() == 1) && (opt_keys[0] == "extruder")))
|
||||
|
|
@ -574,10 +634,13 @@ 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.bmp().GetRefData())
|
||||
else if (title == _("Name"))
|
||||
{
|
||||
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 &&
|
||||
pt.x > 2*wxGetApp().em_unit() && pt.x < 4*wxGetApp().em_unit() )
|
||||
fix_through_netfabb();
|
||||
}
|
||||
|
||||
|
|
@ -937,6 +1000,7 @@ void ObjectList::get_freq_settings_choice(const wxString& bundle_name)
|
|||
{
|
||||
const std::vector<std::string>& options = get_options_for_bundle(bundle_name);
|
||||
|
||||
assert(m_config);
|
||||
auto opt_keys = m_config->keys();
|
||||
|
||||
const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
|
|
@ -966,6 +1030,10 @@ void ObjectList::update_settings_item()
|
|||
const auto settings_item = m_objects_model->IsSettingsItem(item) ? item : m_objects_model->GetSettingsItem(item);
|
||||
select_item(settings_item ? settings_item :
|
||||
m_objects_model->AddSettingsChild(item));
|
||||
|
||||
// update object selection on Plater
|
||||
if (!m_prevent_canvas_selection_update)
|
||||
update_selections_on_canvas();
|
||||
}
|
||||
else {
|
||||
auto panel = wxGetApp().sidebar().scrolled_panel();
|
||||
|
|
@ -1135,13 +1203,15 @@ void ObjectList::append_menu_items_osx(wxMenu* menu)
|
|||
menu->AppendSeparator();
|
||||
}
|
||||
|
||||
void ObjectList::append_menu_item_fix_through_netfabb(wxMenu* menu)
|
||||
wxMenuItem* ObjectList::append_menu_item_fix_through_netfabb(wxMenu* menu)
|
||||
{
|
||||
if (!is_windows10())
|
||||
return;
|
||||
append_menu_item(menu, wxID_ANY, _(L("Fix through the Netfabb")), "",
|
||||
return nullptr;
|
||||
wxMenuItem* menu_item = append_menu_item(menu, wxID_ANY, _(L("Fix through the Netfabb")), "",
|
||||
[this](wxCommandEvent&) { fix_through_netfabb(); }, "", menu);
|
||||
menu->AppendSeparator();
|
||||
|
||||
return menu_item;
|
||||
}
|
||||
|
||||
void ObjectList::append_menu_item_export_stl(wxMenu* menu) const
|
||||
|
|
@ -1327,21 +1397,23 @@ void ObjectList::load_subobject(ModelVolumeType type)
|
|||
int obj_idx = m_objects_model->GetIdByItem(item);
|
||||
|
||||
if (obj_idx < 0) return;
|
||||
wxArrayString part_names;
|
||||
load_part((*m_objects)[obj_idx], part_names, type);
|
||||
|
||||
std::vector<std::pair<wxString, bool>> volumes_info;
|
||||
load_part((*m_objects)[obj_idx], volumes_info, type);
|
||||
|
||||
|
||||
changed_object(obj_idx);
|
||||
|
||||
for (int i = 0; i < part_names.size(); ++i) {
|
||||
const wxDataViewItem sel_item = m_objects_model->AddVolumeChild(item, part_names.Item(i), type);
|
||||
|
||||
if (i == part_names.size() - 1)
|
||||
select_item(sel_item);
|
||||
}
|
||||
wxDataViewItem sel_item;
|
||||
for (const auto& volume : volumes_info )
|
||||
sel_item = m_objects_model->AddVolumeChild(item, volume.first, type, volume.second);
|
||||
|
||||
if (sel_item)
|
||||
select_item(sel_item);
|
||||
}
|
||||
|
||||
void ObjectList::load_part( ModelObject* model_object,
|
||||
wxArrayString& part_names,
|
||||
std::vector<std::pair<wxString, bool>> &volumes_info,
|
||||
ModelVolumeType type)
|
||||
{
|
||||
wxWindow* parent = wxGetApp().tab_panel()->GetPage(0);
|
||||
|
|
@ -1377,7 +1449,7 @@ void ObjectList::load_part( ModelObject* model_object,
|
|||
new_volume->set_type(type);
|
||||
new_volume->name = boost::filesystem::path(input_file).filename().string();
|
||||
|
||||
part_names.Add(from_u8(new_volume->name));
|
||||
volumes_info.push_back(std::make_pair(from_u8(new_volume->name), new_volume->get_mesh_errors_count()>0));
|
||||
|
||||
// set a default extruder value, since user can't add it manually
|
||||
new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||
|
|
@ -1533,7 +1605,8 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
|
|||
changed_object(obj_idx);
|
||||
|
||||
const auto object_item = m_objects_model->GetTopParent(GetSelection());
|
||||
select_item(m_objects_model->AddVolumeChild(object_item, name, type));
|
||||
select_item(m_objects_model->AddVolumeChild(object_item, name, type,
|
||||
new_volume->get_mesh_errors_count()>0));
|
||||
#ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
|
||||
selection_changed();
|
||||
#endif //no __WXOSX__ //__WXMSW__
|
||||
|
|
@ -1565,6 +1638,10 @@ void ObjectList::del_subobject_item(wxDataViewItem& item)
|
|||
else if (!del_subobject_from_object(obj_idx, idx, type))
|
||||
return;
|
||||
|
||||
// If last volume item with warning was deleted, unmark object item
|
||||
if (type == itVolume && (*m_objects)[obj_idx]->get_mesh_errors_count() == 0)
|
||||
m_objects_model->DeleteWarningIcon(m_objects_model->GetParent(item));
|
||||
|
||||
m_objects_model->Delete(item);
|
||||
}
|
||||
|
||||
|
|
@ -1671,18 +1748,18 @@ void ObjectList::split()
|
|||
else
|
||||
parent = item;
|
||||
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++) {
|
||||
const auto vol_item = m_objects_model->AddVolumeChild(parent, from_u8(model_object->volumes[id]->name),
|
||||
model_object->volumes[id]->is_modifier() ?
|
||||
ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
|
||||
model_object->volumes[id]->config.has("extruder") ?
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||
for (const ModelVolume* volume : model_object->volumes) {
|
||||
const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(parent, from_u8(volume->name),
|
||||
volume->is_modifier() ? ModelVolumeType::PARAMETER_MODIFIER : ModelVolumeType::MODEL_PART,
|
||||
volume->get_mesh_errors_count()>0,
|
||||
volume->config.has("extruder") ?
|
||||
volume->config.option<ConfigOptionInt>("extruder")->value : 0,
|
||||
false);
|
||||
// add settings to the part, if it has those
|
||||
auto opt_keys = model_object->volumes[id]->config.keys();
|
||||
auto opt_keys = volume->config.keys();
|
||||
if ( !(opt_keys.size() == 1 && opt_keys[0] == "extruder") ) {
|
||||
select_item(m_objects_model->AddSettingsChild(vol_item));
|
||||
/*Collapse*/Expand(vol_item);
|
||||
Expand(vol_item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1755,6 +1832,7 @@ void ObjectList::changed_object(const int obj_idx/* = -1*/) const
|
|||
void ObjectList::part_selection_changed()
|
||||
{
|
||||
int obj_idx = -1;
|
||||
int volume_id = -1;
|
||||
m_config = nullptr;
|
||||
wxString og_name = wxEmptyString;
|
||||
|
||||
|
|
@ -1801,7 +1879,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;
|
||||
}
|
||||
|
|
@ -1821,7 +1899,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_warning_icon_state(get_mesh_errors_list(obj_idx, volume_id));
|
||||
}
|
||||
}
|
||||
|
||||
if (update_and_show_settings)
|
||||
|
|
@ -1841,34 +1923,26 @@ 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) {
|
||||
wxVariant variant;
|
||||
variant << DataViewBitmapText(item_name, m_bmp_manifold_warning.bmp());
|
||||
m_objects_model->SetValue(variant, item, 0);
|
||||
}
|
||||
model_object->config.option<ConfigOptionInt>("extruder")->value,
|
||||
get_mesh_errors_count(obj_idx) > 0);
|
||||
|
||||
// add volumes to the object
|
||||
if (model_object->volumes.size() > 1) {
|
||||
for (auto id = 0; id < model_object->volumes.size(); id++) {
|
||||
auto vol_item = m_objects_model->AddVolumeChild(item,
|
||||
from_u8(model_object->volumes[id]->name),
|
||||
model_object->volumes[id]->type(),
|
||||
!model_object->volumes[id]->config.has("extruder") ? 0 :
|
||||
model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
|
||||
for (const ModelVolume* volume : model_object->volumes) {
|
||||
const wxDataViewItem& vol_item = m_objects_model->AddVolumeChild(item,
|
||||
from_u8(volume->name),
|
||||
volume->type(),
|
||||
volume->get_mesh_errors_count()>0,
|
||||
!volume->config.has("extruder") ? 0 :
|
||||
volume->config.option<ConfigOptionInt>("extruder")->value,
|
||||
false);
|
||||
auto opt_keys = model_object->volumes[id]->config.keys();
|
||||
auto opt_keys = volume->config.keys();
|
||||
if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) {
|
||||
select_item(m_objects_model->AddSettingsChild(vol_item));
|
||||
/*Collapse*/Expand(vol_item);
|
||||
Expand(vol_item);
|
||||
}
|
||||
}
|
||||
Expand(item);
|
||||
|
|
@ -1882,7 +1956,7 @@ void ObjectList::add_object_to_list(size_t obj_idx)
|
|||
auto opt_keys = model_object->config.keys();
|
||||
if (!opt_keys.empty() && !(opt_keys.size() == 1 && opt_keys[0] == "extruder")) {
|
||||
select_item(m_objects_model->AddSettingsChild(item));
|
||||
/*Collapse*/Expand(item);
|
||||
Expand(item);
|
||||
}
|
||||
|
||||
#ifndef __WXOSX__
|
||||
|
|
@ -2076,6 +2150,11 @@ void ObjectList::update_selections()
|
|||
if (m_objects_model->GetVolumeIdByItem(m_objects_model->GetParent(item)) == gl_vol->volume_idx())
|
||||
return;
|
||||
}
|
||||
|
||||
// but if there is selected only one of several instances by context menu,
|
||||
// then select this instance in ObjectList
|
||||
if (selection.is_single_full_instance())
|
||||
sels.Add(m_objects_model->GetItemByInstanceId(selection.get_object_idx(), selection.get_instance_idx()));
|
||||
}
|
||||
else if (selection.is_single_full_object() || selection.is_multiple_full_object())
|
||||
{
|
||||
|
|
@ -2666,18 +2745,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);
|
||||
|
||||
|
|
@ -2691,28 +2762,27 @@ 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) {
|
||||
// delete Error_icon if all errors are fixed
|
||||
wxVariant variant;
|
||||
variant << DataViewBitmapText(from_u8(model_object->name), wxNullBitmap);
|
||||
m_objects_model->SetValue(variant, item, 0);
|
||||
if (get_mesh_errors_count(obj_idx, vol_idx) == 0)
|
||||
{
|
||||
// if whole object has no errors more,
|
||||
if (get_mesh_errors_count(obj_idx) == 0)
|
||||
// unmark all items in the object
|
||||
m_objects_model->DeleteWarningIcon(vol_idx >= 0 ? m_objects_model->GetParent(item) : item, true);
|
||||
else
|
||||
// unmark fixed item only
|
||||
m_objects_model->DeleteWarningIcon(item);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectList::msw_rescale()
|
||||
{
|
||||
const int em = wxGetApp().em_unit();
|
||||
// update min size !!! A width of control shouldn't be a wxDefaultCoord
|
||||
SetMinSize(wxSize(1, 15 * wxGetApp().em_unit()));
|
||||
SetMinSize(wxSize(1, 15 * em));
|
||||
|
||||
GetColumn(0)->SetWidth(19 * wxGetApp().em_unit());
|
||||
GetColumn(1)->SetWidth(8 * wxGetApp().em_unit());
|
||||
GetColumn(2)->SetWidth(int(2 * wxGetApp().em_unit()));
|
||||
GetColumn(0)->SetWidth(19 * em);
|
||||
GetColumn(1)->SetWidth( 8 * em);
|
||||
GetColumn(2)->SetWidth( 2 * em);
|
||||
|
||||
// rescale all icons, used by ObjectList
|
||||
rescale_icons();
|
||||
|
|
|
|||
|
|
@ -175,6 +175,16 @@ public:
|
|||
void init_icons();
|
||||
void rescale_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();
|
||||
|
|
@ -192,7 +202,7 @@ public:
|
|||
wxMenuItem* append_menu_item_change_type(wxMenu* menu);
|
||||
wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu);
|
||||
void append_menu_items_osx(wxMenu* menu);
|
||||
void append_menu_item_fix_through_netfabb(wxMenu* menu);
|
||||
wxMenuItem* append_menu_item_fix_through_netfabb(wxMenu* menu);
|
||||
void append_menu_item_export_stl(wxMenu* menu) const ;
|
||||
void append_menu_item_change_extruder(wxMenu* menu) const;
|
||||
void append_menu_item_delete(wxMenu* menu);
|
||||
|
|
@ -206,7 +216,7 @@ public:
|
|||
void update_opt_keys(t_config_option_keys& t_optopt_keys);
|
||||
|
||||
void load_subobject(ModelVolumeType type);
|
||||
void load_part(ModelObject* model_object, wxArrayString& part_names, ModelVolumeType type);
|
||||
void load_part(ModelObject* model_object, std::vector<std::pair<wxString, bool>> &volumes_info, ModelVolumeType type);
|
||||
void load_generic_subobject(const std::string& type_name, const ModelVolumeType type);
|
||||
void del_object(const int obj_idx);
|
||||
void del_subobject_item(wxDataViewItem& item);
|
||||
|
|
@ -280,7 +290,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
|
||||
{
|
||||
|
|
@ -22,6 +23,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
, m_focused_option("")
|
||||
#endif // __APPLE__
|
||||
{
|
||||
m_manifold_warning_bmp = ScalableBitmap(parent, "exclamation");
|
||||
m_og->set_name(_(L("Object Manipulation")));
|
||||
m_og->label_width = 12;//125;
|
||||
m_og->set_grid_vgap(5);
|
||||
|
|
@ -42,17 +44,50 @@ 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_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;
|
||||
#ifdef __APPLE__
|
||||
def.width = 19;
|
||||
#endif
|
||||
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;
|
||||
|
||||
// Legend for object modification
|
||||
auto line = Line{ "", "" };
|
||||
line = Line{ "", "" };
|
||||
def.label = "";
|
||||
def.type = coString;
|
||||
def.width = field_width/*50*/;
|
||||
|
|
@ -334,6 +369,12 @@ void ObjectManipulation::emulate_kill_focus()
|
|||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
void ObjectManipulation::update_warning_icon_state(const wxString& tooltip)
|
||||
{
|
||||
m_fix_throught_netfab_bitmap->SetBitmap(tooltip.IsEmpty() ? wxNullBitmap : m_manifold_warning_bmp.bmp());
|
||||
m_fix_throught_netfab_bitmap->SetToolTip(tooltip);
|
||||
}
|
||||
|
||||
void ObjectManipulation::reset_settings_value()
|
||||
{
|
||||
m_new_position = Vec3d::Zero();
|
||||
|
|
@ -519,5 +560,13 @@ void ObjectManipulation::on_fill_empty_value(const std::string& opt_key)
|
|||
m_og->set_value(opt_key, double_to_string(value));
|
||||
}
|
||||
|
||||
void ObjectManipulation::msw_rescale()
|
||||
{
|
||||
m_manifold_warning_bmp.msw_rescale();
|
||||
m_fix_throught_netfab_bitmap->SetBitmap(m_manifold_warning_bmp.bmp());
|
||||
|
||||
get_og()->msw_rescale();
|
||||
}
|
||||
|
||||
} //namespace GUI
|
||||
} //namespace Slic3r
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
class wxStaticText;
|
||||
class LockButton;
|
||||
class wxStaticBitmap;
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
|
@ -78,6 +79,9 @@ class ObjectManipulation : public OG_Settings
|
|||
bool m_uniform_scale {true};
|
||||
LockButton* m_lock_bnt{ nullptr };
|
||||
|
||||
ScalableBitmap 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 +111,9 @@ public:
|
|||
void emulate_kill_focus();
|
||||
#endif // __APPLE__
|
||||
|
||||
void update_warning_icon_state(const wxString& tooltip);
|
||||
void msw_rescale();
|
||||
|
||||
private:
|
||||
void reset_settings_value();
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ void ObjectSettings::update_settings_list()
|
|||
if (cat.second.size() == 1 && cat.second[0] == "extruder")
|
||||
continue;
|
||||
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), cat.first, config, false, extra_column);
|
||||
auto optgroup = std::make_shared<ConfigOptionsGroup>(m_og->ctrl_parent(), _(cat.first), config, false, extra_column);
|
||||
optgroup->label_width = 15;
|
||||
optgroup->sidetext_width = 5.5;
|
||||
|
||||
|
|
|
|||
|
|
@ -923,7 +923,7 @@ RENDER_AGAIN:
|
|||
// Following is rendered in both editing and non-editing mode:
|
||||
m_imgui->text("");
|
||||
if (m_clipping_plane_distance == 0.f)
|
||||
m_imgui->text("Clipping of view: ");
|
||||
m_imgui->text(_(L("Clipping of view:"))+ " ");
|
||||
else {
|
||||
if (m_imgui->button(_(L("Reset direction")))) {
|
||||
wxGetApp().CallAfter([this](){
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@ KBShortcutsDialog::KBShortcutsDialog()
|
|||
m_head_bitmaps.reserve(m_full_shortcuts.size());
|
||||
const wxSize topic_size = wxSize(10 * wxGetApp().em_unit(), -1);
|
||||
|
||||
for (auto& sc : m_full_shortcuts)
|
||||
for (auto& shortcut : m_full_shortcuts)
|
||||
{
|
||||
auto sizer = sc.second.second == szLeft ? l_sizer : r_sizer;
|
||||
auto sizer = shortcut.second.second == szLeft ? l_sizer : r_sizer;
|
||||
wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(hsizer, 0, wxEXPAND | wxTOP | wxBOTTOM, 10);
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ KBShortcutsDialog::KBShortcutsDialog()
|
|||
hsizer->Add(m_head_bitmaps.back(), 0, wxEXPAND | wxLEFT | wxRIGHT, 15);
|
||||
|
||||
// head
|
||||
wxStaticText* head = new wxStaticText(panel, wxID_ANY, sc.first, wxDefaultPosition, topic_size);
|
||||
wxStaticText* head = new wxStaticText(panel, wxID_ANY, shortcut.first, wxDefaultPosition, topic_size);
|
||||
head->SetFont(head_font);
|
||||
hsizer->Add(head, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ KBShortcutsDialog::KBShortcutsDialog()
|
|||
auto grid_sizer = new wxFlexGridSizer(2, 5, 15);
|
||||
sizer->Add(grid_sizer, 0, wxEXPAND | wxLEFT| wxRIGHT, 15);
|
||||
|
||||
for (auto pair : sc.second.first)
|
||||
for (auto pair : shortcut.second.first)
|
||||
{
|
||||
auto shortcut = new wxStaticText(panel, wxID_ANY, _(pair.first));
|
||||
shortcut->SetFont(bold_font);
|
||||
|
|
@ -124,7 +124,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
|||
main_shortcuts.push_back(Shortcut("+" ,L("Add Instance to selected object ")));
|
||||
main_shortcuts.push_back(Shortcut("-" ,L("Remove Instance from selected object")));
|
||||
main_shortcuts.push_back(Shortcut("?" ,L("Show keyboard shortcuts list")));
|
||||
main_shortcuts.push_back(Shortcut(ctrl+"LeftMouse" ,L("Select multiple object/Move multiple object")));
|
||||
main_shortcuts.push_back(Shortcut(ctrl/*+"LeftMouse"*/,L("Press to select multiple object or move multiple object with mouse")));
|
||||
|
||||
m_full_shortcuts.push_back(std::make_pair(_(L("Main Shortcuts")), std::make_pair(main_shortcuts, szLeft)));
|
||||
|
||||
|
|
|
|||
|
|
@ -518,7 +518,9 @@ void MainFrame::init_menubar()
|
|||
// The camera control accelerators are captured by GLCanvas3D::on_char().
|
||||
wxMenuItem* item_iso = append_menu_item(viewMenu, wxID_ANY, _(L("Iso")) + sep + "&0", _(L("Iso View")), [this](wxCommandEvent&) { select_view("iso"); });
|
||||
viewMenu->AppendSeparator();
|
||||
//TRN To be shown in the main menu View->Top
|
||||
wxMenuItem* item_top = append_menu_item(viewMenu, wxID_ANY, _(L("Top")) + sep + "&1", _(L("Top View")), [this](wxCommandEvent&) { select_view("top"); });
|
||||
//TRN To be shown in the main menu View->Bottom
|
||||
wxMenuItem* item_bottom = append_menu_item(viewMenu, wxID_ANY, _(L("Bottom")) + sep + "&2", _(L("Bottom View")), [this](wxCommandEvent&) { select_view("bottom"); });
|
||||
wxMenuItem* item_front = append_menu_item(viewMenu, wxID_ANY, _(L("Front")) + sep + "&3", _(L("Front View")), [this](wxCommandEvent&) { select_view("front"); });
|
||||
wxMenuItem* item_rear = append_menu_item(viewMenu, wxID_ANY, _(L("Rear")) + sep + "&4", _(L("Rear View")), [this](wxCommandEvent&) { select_view("rear"); });
|
||||
|
|
|
|||
|
|
@ -724,7 +724,7 @@ Sidebar::Sidebar(Plater *parent)
|
|||
|
||||
auto init_btn = [this](wxButton **btn, wxString label) {
|
||||
*btn = new wxButton(this, wxID_ANY, label, wxDefaultPosition,
|
||||
wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
|
||||
wxDefaultSize, wxBU_EXACTFIT);
|
||||
(*btn)->SetFont(wxGetApp().bold_font());
|
||||
};
|
||||
|
||||
|
|
@ -896,8 +896,7 @@ void Sidebar::msw_rescale()
|
|||
p->frequently_changed_parameters->get_og(false)->msw_rescale();
|
||||
|
||||
p->object_list->msw_rescale();
|
||||
|
||||
p->object_manipulation->get_og()->msw_rescale();
|
||||
p->object_manipulation->msw_rescale();
|
||||
p->object_settings->msw_rescale();
|
||||
|
||||
p->object_info->msw_rescale();
|
||||
|
|
@ -970,7 +969,7 @@ void Sidebar::show_info_sizer()
|
|||
p->object_info->info_size->SetLabel(wxString::Format("%.2f x %.2f x %.2f",size(0), size(1), size(2)));
|
||||
p->object_info->info_materials->SetLabel(wxString::Format("%d", static_cast<int>(model_object->materials_count())));
|
||||
|
||||
auto& stats = model_object->volumes.front()->mesh.stl.stats;
|
||||
const auto& stats = model_object->get_object_stl_stats();//model_object->volumes.front()->mesh.stl.stats;
|
||||
p->object_info->info_volume->SetLabel(wxString::Format("%.2f", stats.volume));
|
||||
p->object_info->info_facets->SetLabel(wxString::Format(_(L("%d (%d shells)")), static_cast<int>(model_object->facets_count()), stats.number_of_parts));
|
||||
|
||||
|
|
@ -990,7 +989,7 @@ void Sidebar::show_info_sizer()
|
|||
p->object_info->manifold_warning_icon->SetToolTip(tooltip);
|
||||
}
|
||||
else {
|
||||
p->object_info->info_manifold->SetLabel(L("Yes"));
|
||||
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("");
|
||||
|
|
@ -1328,6 +1327,7 @@ struct Plater::priv
|
|||
bool can_split_to_volumes() const;
|
||||
bool can_arrange() const;
|
||||
bool can_layers_editing() const;
|
||||
bool can_fix_through_netfabb() const;
|
||||
|
||||
private:
|
||||
bool init_object_menu();
|
||||
|
|
@ -2403,7 +2403,7 @@ unsigned int Plater::priv::update_background_process(bool force_validation)
|
|||
// Background data is valid.
|
||||
if ((return_state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 ||
|
||||
(return_state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) != 0 )
|
||||
this->statusbar()->set_status_text(L("Ready to slice"));
|
||||
this->statusbar()->set_status_text(_(L("Ready to slice")));
|
||||
|
||||
sidebar->set_btn_label(ActionButtonType::abExport, _(label_btn_export));
|
||||
sidebar->set_btn_label(ActionButtonType::abSendGCode, _(label_btn_send));
|
||||
|
|
@ -2441,7 +2441,7 @@ bool Plater::priv::restart_background_process(unsigned int state)
|
|||
// The print is valid and it can be started.
|
||||
if (this->background_process.start()) {
|
||||
this->statusbar()->set_cancel_callback([this]() {
|
||||
this->statusbar()->set_status_text(L("Cancelling"));
|
||||
this->statusbar()->set_status_text(_(L("Cancelling")));
|
||||
this->background_process.stop();
|
||||
});
|
||||
return true;
|
||||
|
|
@ -2665,7 +2665,7 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
|
|||
}
|
||||
|
||||
this->statusbar()->set_progress(evt.status.percent);
|
||||
this->statusbar()->set_status_text(_(L(evt.status.text)) + wxString::FromUTF8("…"));
|
||||
this->statusbar()->set_status_text(_(evt.status.text) + wxString::FromUTF8("…"));
|
||||
}
|
||||
if (evt.status.flags & (PrintBase::SlicingStatus::RELOAD_SCENE || PrintBase::SlicingStatus::RELOAD_SLA_SUPPORT_POINTS)) {
|
||||
switch (this->printer_technology) {
|
||||
|
|
@ -2724,7 +2724,7 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
|
|||
this->statusbar()->set_status_text(message);
|
||||
}
|
||||
if (canceled)
|
||||
this->statusbar()->set_status_text(L("Cancelled"));
|
||||
this->statusbar()->set_status_text(_(L("Cancelled")));
|
||||
|
||||
this->sidebar->show_sliced_info_sizer(success);
|
||||
|
||||
|
|
@ -2930,7 +2930,7 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
|||
menu->AppendSeparator();
|
||||
}
|
||||
|
||||
sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu);
|
||||
wxMenuItem* item_fix_through_netfabb = sidebar->obj_list()->append_menu_item_fix_through_netfabb(menu);
|
||||
|
||||
wxMenu* mirror_menu = new wxMenu();
|
||||
if (mirror_menu == nullptr)
|
||||
|
|
@ -2950,6 +2950,8 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
|
|||
{
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_mirror()); }, item_mirror->GetId());
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete()); }, item_delete->GetId());
|
||||
if (item_fix_through_netfabb)
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_fix_through_netfabb()); }, item_fix_through_netfabb->GetId());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -3119,6 +3121,15 @@ bool Plater::priv::can_delete_all() const
|
|||
return !model.objects.empty();
|
||||
}
|
||||
|
||||
bool Plater::priv::can_fix_through_netfabb() const
|
||||
{
|
||||
int obj_idx = get_selected_object_idx();
|
||||
if (obj_idx < 0)
|
||||
return false;
|
||||
|
||||
return model.objects[obj_idx]->get_mesh_errors_count() > 0;
|
||||
}
|
||||
|
||||
bool Plater::priv::can_increase_instances() const
|
||||
{
|
||||
if (arranging || rotoptimizing) {
|
||||
|
|
|
|||
|
|
@ -1678,7 +1678,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup)
|
|||
}
|
||||
|
||||
auto printhost_browse = [=](wxWindow* parent) {
|
||||
add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L(" Browse ")) + dots, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
add_scaled_button(parent, &m_printhost_browse_btn, "browse", _(L("Browse")) + " "+ dots, wxBU_LEFT | wxBU_EXACTFIT);
|
||||
ScalableButton* btn = m_printhost_browse_btn;
|
||||
btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
|
||||
|
|
@ -2057,7 +2057,7 @@ void TabPrinter::build_sla()
|
|||
optgroup->append_single_option_line("area_fill");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Corrections")));
|
||||
line = Line{ m_config->def()->get("relative_correction")->full_label, "" };
|
||||
line = Line{ _(m_config->def()->get("relative_correction")->full_label), "" };
|
||||
// std::vector<std::string> axes{ "X", "Y", "Z" };
|
||||
std::vector<std::string> axes{ "XY", "Z" };
|
||||
int id = 0;
|
||||
|
|
@ -3313,7 +3313,7 @@ void TabSLAMaterial::build()
|
|||
// std::vector<std::string> axes{ "X", "Y", "Z" };
|
||||
std::vector<std::string> axes{ "XY", "Z" };
|
||||
for (auto& opt_key : corrections) {
|
||||
auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
|
||||
auto line = Line{ _(m_config->def()->get(opt_key)->full_label), "" };
|
||||
int id = 0;
|
||||
for (auto& axis : axes) {
|
||||
auto opt = optgroup->get_option(opt_key, id);
|
||||
|
|
|
|||
|
|
@ -346,6 +346,28 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, con
|
|||
// ObjectDataViewModelNode
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type) :
|
||||
m_parent(parent),
|
||||
m_type(type),
|
||||
m_extruder(wxEmptyString)
|
||||
{
|
||||
if (type == itSettings) {
|
||||
m_name = "Settings to modified";
|
||||
}
|
||||
else if (type == itInstanceRoot) {
|
||||
m_name = _(L("Instances"));
|
||||
#ifdef __WXGTK__
|
||||
m_container = true;
|
||||
#endif //__WXGTK__
|
||||
}
|
||||
else if (type == itInstance) {
|
||||
m_idx = parent->GetChildCount();
|
||||
m_name = wxString::Format(_(L("Instance_%d")), m_idx + 1);
|
||||
|
||||
set_action_icon();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectDataViewModelNode::set_action_icon()
|
||||
{
|
||||
m_action_icon_name = m_type == itObject ? "advanced_plus" :
|
||||
|
|
@ -384,7 +406,7 @@ bool ObjectDataViewModelNode::update_settings_digest(const std::vector<std::stri
|
|||
m_name = wxEmptyString;
|
||||
|
||||
for (auto& cat : m_opt_categories)
|
||||
m_name += cat + "; ";
|
||||
m_name += _(cat) + "; ";
|
||||
if (!m_name.IsEmpty())
|
||||
m_name.erase(m_name.Length()-2, 2); // Delete last "; "
|
||||
|
||||
|
|
@ -420,14 +442,21 @@ ObjectDataViewModel::~ObjectDataViewModel()
|
|||
m_bitmap_cache = nullptr;
|
||||
}
|
||||
|
||||
wxDataViewItem ObjectDataViewModel::Add(const wxString &name, const int extruder)
|
||||
wxDataViewItem ObjectDataViewModel::Add(const wxString &name,
|
||||
const int extruder,
|
||||
const bool has_errors/* = false*/)
|
||||
{
|
||||
const wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder);
|
||||
auto root = new ObjectDataViewModelNode(name, extruder_str);
|
||||
// Add error icon if detected auto-repaire
|
||||
if (has_errors)
|
||||
root->m_bmp = *m_warning_bmp;
|
||||
|
||||
m_objects.push_back(root);
|
||||
// notify control
|
||||
wxDataViewItem child((void*)root);
|
||||
wxDataViewItem parent((void*)NULL);
|
||||
|
||||
ItemAdded(parent, child);
|
||||
return child;
|
||||
}
|
||||
|
|
@ -435,6 +464,7 @@ wxDataViewItem ObjectDataViewModel::Add(const wxString &name, const int extruder
|
|||
wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent_item,
|
||||
const wxString &name,
|
||||
const Slic3r::ModelVolumeType volume_type,
|
||||
const bool has_errors/* = false*/,
|
||||
const int extruder/* = 0*/,
|
||||
const bool create_frst_child/* = true*/)
|
||||
{
|
||||
|
|
@ -448,9 +478,14 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
|
|||
if (insert_position < 0 || root->GetNthChild(insert_position)->m_type != itInstanceRoot)
|
||||
insert_position = -1;
|
||||
|
||||
const bool obj_errors = root->m_bmp.IsOk();
|
||||
|
||||
if (create_frst_child && root->m_volumes_cnt == 0)
|
||||
{
|
||||
const auto node = new ObjectDataViewModelNode(root, root->m_name, *m_volume_bmps[0], extruder_str, 0);
|
||||
const Slic3r::ModelVolumeType type = Slic3r::ModelVolumeType::MODEL_PART;
|
||||
const auto node = new ObjectDataViewModelNode(root, root->m_name, GetVolumeIcon(type, obj_errors), extruder_str, 0);
|
||||
node->m_volume_type = type;
|
||||
|
||||
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
|
||||
// notify control
|
||||
const wxDataViewItem child((void*)node);
|
||||
|
|
@ -458,12 +493,15 @@ wxDataViewItem ObjectDataViewModel::AddVolumeChild( const wxDataViewItem &parent
|
|||
|
||||
root->m_volumes_cnt++;
|
||||
if (insert_position > 0) insert_position++;
|
||||
|
||||
node->m_volume_type = volume_type;
|
||||
}
|
||||
|
||||
const auto node = new ObjectDataViewModelNode(root, name, *m_volume_bmps[int(volume_type)], extruder_str, root->m_volumes_cnt);
|
||||
const auto node = new ObjectDataViewModelNode(root, name, GetVolumeIcon(volume_type, has_errors), extruder_str, root->m_volumes_cnt);
|
||||
insert_position < 0 ? root->Append(node) : root->Insert(node, insert_position);
|
||||
|
||||
// if part with errors is added, but object wasn't marked, then mark it
|
||||
if (!obj_errors && has_errors)
|
||||
root->SetBitmap(*m_warning_bmp);
|
||||
|
||||
// notify control
|
||||
const wxDataViewItem child((void*)node);
|
||||
ItemAdded(parent_item, child);
|
||||
|
|
@ -1228,15 +1266,61 @@ void ObjectDataViewModel::Rescale()
|
|||
node->msw_rescale();
|
||||
|
||||
if (node->m_type & itVolume)
|
||||
node->m_bmp = *m_volume_bmps[node->volume_type()];
|
||||
node->m_bmp = GetVolumeIcon(node->m_volume_type, node->m_bmp.GetWidth() != node->m_bmp.GetHeight());
|
||||
|
||||
if (node->m_type & itObject && node->m_bmp.IsOk())
|
||||
node->m_bmp = create_scaled_bitmap(nullptr, "exclamation");
|
||||
node->m_bmp = *m_warning_bmp;
|
||||
|
||||
ItemChanged(item);
|
||||
}
|
||||
}
|
||||
|
||||
wxBitmap ObjectDataViewModel::GetVolumeIcon(const Slic3r::ModelVolumeType vol_type, const bool is_marked/* = false*/)
|
||||
{
|
||||
if (!is_marked)
|
||||
return *m_volume_bmps[static_cast<int>(vol_type)];
|
||||
|
||||
std::string scaled_bitmap_name = "warning" + std::to_string(static_cast<int>(vol_type));
|
||||
scaled_bitmap_name += "-em" + std::to_string(Slic3r::GUI::wxGetApp().em_unit());
|
||||
|
||||
wxBitmap *bmp = m_bitmap_cache->find(scaled_bitmap_name);
|
||||
if (bmp == nullptr) {
|
||||
std::vector<wxBitmap> bmps;
|
||||
|
||||
bmps.emplace_back(*m_warning_bmp);
|
||||
bmps.emplace_back(*m_volume_bmps[static_cast<int>(vol_type)]);
|
||||
|
||||
bmp = m_bitmap_cache->insert(scaled_bitmap_name, bmps);
|
||||
}
|
||||
|
||||
return *bmp;
|
||||
}
|
||||
|
||||
void ObjectDataViewModel::DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object/* = false*/)
|
||||
{
|
||||
if (!item.IsOk())
|
||||
return;
|
||||
|
||||
ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID();
|
||||
|
||||
if (!node->GetBitmap().IsOk() || !(node->GetType() & (itVolume | itObject)))
|
||||
return;
|
||||
|
||||
if (node->GetType() & itVolume) {
|
||||
node->SetBitmap(*m_volume_bmps[static_cast<int>(node->volume_type())]);
|
||||
return;
|
||||
}
|
||||
|
||||
node->SetBitmap(wxNullBitmap);
|
||||
if (unmark_object)
|
||||
{
|
||||
wxDataViewItemArray children;
|
||||
GetChildren(item, children);
|
||||
for (const wxDataViewItem& child : children)
|
||||
DeleteWarningIcon(child);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// PrusaDataViewBitmapText
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2379,11 +2463,7 @@ ModeSizer::ModeSizer(wxWindow *parent, int hgap/* = 10*/) :
|
|||
|
||||
m_mode_btns.reserve(3);
|
||||
for (const auto& button : buttons) {
|
||||
// int x, y;
|
||||
// parent->GetTextExtent(button.first, &x, &y, nullptr, nullptr, &Slic3r::GUI::wxGetApp().bold_font());
|
||||
// const wxSize size = wxSize(x + button.second.GetWidth() + Slic3r::GUI::wxGetApp().em_unit(),
|
||||
// y + Slic3r::GUI::wxGetApp().em_unit());
|
||||
m_mode_btns.push_back(new ModeButton(parent, wxID_ANY, button.second, button.first/*, size*/));
|
||||
m_mode_btns.push_back(new ModeButton(parent, wxID_ANY, button.second, button.first));
|
||||
}
|
||||
|
||||
for (auto btn : m_mode_btns)
|
||||
|
|
|
|||
|
|
@ -219,28 +219,7 @@ public:
|
|||
set_action_icon();
|
||||
}
|
||||
|
||||
ObjectDataViewModelNode(ObjectDataViewModelNode* parent,
|
||||
const ItemType type) :
|
||||
m_parent(parent),
|
||||
m_type(type),
|
||||
m_extruder(wxEmptyString)
|
||||
{
|
||||
if (type == itSettings) {
|
||||
m_name = "Settings to modified";
|
||||
}
|
||||
else if (type == itInstanceRoot) {
|
||||
m_name = "Instances";
|
||||
#ifdef __WXGTK__
|
||||
m_container = true;
|
||||
#endif //__WXGTK__
|
||||
}
|
||||
else if (type == itInstance) {
|
||||
m_idx = parent->GetChildCount();
|
||||
m_name = wxString::Format("Instance_%d", m_idx+1);
|
||||
|
||||
set_action_icon();
|
||||
}
|
||||
}
|
||||
ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type);
|
||||
|
||||
~ObjectDataViewModelNode()
|
||||
{
|
||||
|
|
@ -323,14 +302,10 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void SetBitmap(const wxBitmap &icon)
|
||||
{
|
||||
m_bmp = icon;
|
||||
}
|
||||
|
||||
ItemType GetType() const {
|
||||
return m_type;
|
||||
}
|
||||
void SetBitmap(const wxBitmap &icon) { m_bmp = icon; }
|
||||
const wxBitmap& GetBitmap() const { return m_bmp; }
|
||||
const wxString& GetName() const { return m_name; }
|
||||
ItemType GetType() const { return m_type; }
|
||||
|
||||
void SetIdx(const int& idx) {
|
||||
m_idx = idx;
|
||||
|
|
@ -339,9 +314,7 @@ public:
|
|||
m_name = wxString::Format("Instance_%d", m_idx + 1);
|
||||
}
|
||||
|
||||
int GetIdx() const {
|
||||
return m_idx;
|
||||
}
|
||||
int GetIdx() const { return m_idx; }
|
||||
|
||||
// use this function only for childrens
|
||||
void AssignAllVal(ObjectDataViewModelNode& from_node)
|
||||
|
|
@ -374,10 +347,10 @@ public:
|
|||
// Set action icons for node
|
||||
void set_action_icon();
|
||||
|
||||
void update_settings_digest_bitmaps();
|
||||
bool update_settings_digest(const std::vector<std::string>& categories);
|
||||
int volume_type() const { return int(m_volume_type); }
|
||||
void msw_rescale();
|
||||
void update_settings_digest_bitmaps();
|
||||
bool update_settings_digest(const std::vector<std::string>& categories);
|
||||
int volume_type() const { return int(m_volume_type); }
|
||||
void msw_rescale();
|
||||
private:
|
||||
friend class ObjectDataViewModel;
|
||||
};
|
||||
|
|
@ -393,6 +366,7 @@ class ObjectDataViewModel :public wxDataViewModel
|
|||
{
|
||||
std::vector<ObjectDataViewModelNode*> m_objects;
|
||||
std::vector<wxBitmap*> m_volume_bmps;
|
||||
wxBitmap* m_warning_bmp;
|
||||
|
||||
wxDataViewCtrl* m_ctrl{ nullptr };
|
||||
|
||||
|
|
@ -400,10 +374,13 @@ public:
|
|||
ObjectDataViewModel();
|
||||
~ObjectDataViewModel();
|
||||
|
||||
wxDataViewItem Add(const wxString &name, const int extruder);
|
||||
wxDataViewItem Add( const wxString &name,
|
||||
const int extruder,
|
||||
const bool has_errors = false);
|
||||
wxDataViewItem AddVolumeChild( const wxDataViewItem &parent_item,
|
||||
const wxString &name,
|
||||
const Slic3r::ModelVolumeType volume_type,
|
||||
const bool has_errors = false,
|
||||
const int extruder = 0,
|
||||
const bool create_frst_child = true);
|
||||
wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item);
|
||||
|
|
@ -475,11 +452,16 @@ public:
|
|||
const std::vector<std::string>& categories);
|
||||
|
||||
void SetVolumeBitmaps(const std::vector<wxBitmap*>& volume_bmps) { m_volume_bmps = volume_bmps; }
|
||||
void SetWarningBitmap(wxBitmap* bitmap) { m_warning_bmp = bitmap; }
|
||||
void SetVolumeType(const wxDataViewItem &item, const Slic3r::ModelVolumeType type);
|
||||
|
||||
void SetAssociatedControl(wxDataViewCtrl* ctrl) { m_ctrl = ctrl; }
|
||||
// Rescale bitmaps for existing Items
|
||||
void Rescale();
|
||||
|
||||
wxBitmap GetVolumeIcon(const Slic3r::ModelVolumeType vol_type,
|
||||
const bool is_marked = false);
|
||||
void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue