mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11: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
	
	 Enrico Turri
						Enrico Turri