diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2dee58136e..146cdd75fb 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2094,20 +2094,6 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, contained_min_one && !m_model->objects.empty() && state != ModelInstance::PVS_Partly_Outside)); - -// #ys_FIXME_delete_after_testing -// bool contained = m_volumes.check_outside_state(m_config, &state); -// if (!contained) -// { -// _set_warning_texture(WarningTexture::ObjectOutside, true); -// post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, state == ModelInstance::PVS_Fully_Outside)); -// } -// else -// { -// m_volumes.reset_outside_state(); -// _set_warning_texture(WarningTexture::ObjectOutside, false); -// post_event(Event(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, !m_model->objects.empty())); -// } } else { @@ -4748,6 +4734,8 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c // Maximum size of an allocation block: 32MB / sizeof(float) BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start" << m_volumes.log_memory_info() << log_memory_info(); + const bool is_selected_separate_extruder = m_selected_extruder > 0 && ctxt.color_by_color_print(); + //FIXME Improve the heuristics for a grain size. size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1)); tbb::spin_mutex new_volume_mutex; @@ -4765,7 +4753,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c const size_t volumes_cnt_initial = m_volumes.volumes.size(); tbb::parallel_for( tbb::blocked_range(0, ctxt.layers.size(), grain_size), - [&ctxt, &new_volume](const tbb::blocked_range& range) { + [&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) { GLVolumePtrs vols; std::vector color_print_layer_to_glvolume; auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { @@ -4801,6 +4789,26 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c vol->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6); for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) { const Layer *layer = ctxt.layers[idx_layer]; + + if (is_selected_separate_extruder) + { + bool at_least_one_has_correct_extruder = false; + for (const LayerRegion* layerm : layer->regions()) + { + if (layerm->slices.surfaces.empty()) + continue; + const PrintRegionConfig& cfg = layerm->region()->config(); + if (cfg.perimeter_extruder.value == m_selected_extruder || + cfg.infill_extruder.value == m_selected_extruder || + cfg.solid_infill_extruder.value == m_selected_extruder ) { + at_least_one_has_correct_extruder = true; + break; + } + } + if (!at_least_one_has_correct_extruder) + continue; + } + for (GLVolume *vol : vols) if (vol->print_zs.empty() || vol->print_zs.back() != layer->print_z) { vol->print_zs.push_back(layer->print_z); @@ -4809,6 +4817,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c } for (const Point © : *ctxt.shifted_copies) { for (const LayerRegion *layerm : layer->regions()) { + if (is_selected_separate_extruder) + { + const PrintRegionConfig& cfg = layerm->region()->config(); + if (cfg.perimeter_extruder.value != m_selected_extruder || + cfg.infill_extruder.value != m_selected_extruder || + cfg.solid_infill_extruder.value != m_selected_extruder) + continue; + } if (ctxt.has_perimeters) _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy, volume(idx_layer, layerm->region()->config().perimeter_extruder.value, 0)); @@ -5157,10 +5173,13 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - populate volumes" << m_volumes.log_memory_info() << log_memory_info(); // populates volumes + const bool is_selected_separate_extruder = m_selected_extruder > 0 && preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint; for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers) { for (const GCodePreviewData::Extrusion::Path& path : layer.paths) { + if (is_selected_separate_extruder && path.extruder_id != m_selected_extruder - 1) + continue; std::vector> &filters = roles_filters[size_t(path.extrusion_role)]; auto key = std::make_pair(Helper::path_filter(preview_data.extrusion.view_type, path), nullptr); auto it_filter = std::lower_bound(filters.begin(), filters.end(), key); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 2c2676ae77..e5e845304c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -436,6 +436,7 @@ private: #endif // ENABLE_RENDER_STATISTICS int m_imgui_undo_redo_hovered_pos{ -1 }; + int m_selected_extruder; public: GLCanvas3D(wxGLCanvas* canvas, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar); @@ -578,6 +579,7 @@ public: int get_move_volume_id() const { return m_mouse.drag.move_volume_idx; } int get_first_hover_volume_idx() const { return m_hover_volume_idxs.empty() ? -1 : m_hover_volume_idxs.front(); } + void set_selected_extruder(int extruder) { m_selected_extruder = extruder;} class WipeTowerInfo { protected: diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index e462e7c1d8..18ddb65bac 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -490,11 +490,14 @@ void Preview::show_hide_ui_elements(const std::string& what) m_choice_view_type->Show(visible); } -void Preview::reset_sliders() +void Preview::reset_sliders(bool reset_all) { m_enabled = false; // reset_double_slider(); - m_double_slider_sizer->Hide((size_t)0); + if (reset_all) + m_double_slider_sizer->Hide((size_t)0); + else + m_double_slider_sizer->GetItem(size_t(0))->GetSizer()->Hide(1); } void Preview::update_sliders(const std::vector& layers_z, bool keep_z_range) @@ -503,11 +506,11 @@ void Preview::update_sliders(const std::vector& layers_z, bool keep_z_ra // update extruder selector if (wxGetApp().extruders_edited_cnt() != m_extruder_selector->GetCount()-1) { - int selection = m_extruder_selector->GetSelection(); + m_selected_extruder = m_extruder_selector->GetSelection(); update_extruder_selector(); - if (selection >= m_extruder_selector->GetCount()) - selection = 0; - m_extruder_selector->SetSelection(selection); + if (m_selected_extruder >= m_extruder_selector->GetCount()) + m_selected_extruder = 0; + m_extruder_selector->SetSelection(m_selected_extruder); } update_double_slider(layers_z, keep_z_range); @@ -615,12 +618,23 @@ void Preview::create_double_slider() m_extruder_selector->SetSelection(0); m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) { - m_slider->SetManipulationState(m_extruder_selector->GetSelection() == 0 ? + m_selected_extruder = m_extruder_selector->GetSelection(); + m_slider->SetManipulationState(m_selected_extruder == 0 ? DoubleSlider::msMultiExtruderWholePrint : DoubleSlider::msMultiExtruder); + + int type = m_choice_view_type->FindString(_(L("Color Print"))); + + if (m_choice_view_type->GetSelection() != type) { + m_choice_view_type->SetSelection(type); + if (0 <= type && type < (int)GCodePreviewData::Extrusion::Num_View_Types) + m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; + m_preferred_color_mode = "feature"; + } + reload_print(); + evt.StopPropagation(); }); - m_extruder_selector->Disable(); // temporary disabled to suppress extruder selection auto sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_extruder_selector, 0, wxEXPAND, 0); @@ -834,7 +848,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (! has_layers) { - reset_sliders(); + reset_sliders(true); m_canvas->reset_legend_texture(); m_canvas_widget->Refresh(); return; @@ -896,6 +910,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (IsShown()) { + m_canvas->set_selected_extruder(m_selected_extruder); if (gcode_preview_data_valid) { // Load the real G-code preview. m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); @@ -913,7 +928,7 @@ void Preview::load_print_as_fff(bool keep_z_range) std::vector zs = m_canvas->get_current_print_zs(true); if (zs.empty()) { // all layers filtered out - reset_sliders(); + reset_sliders(m_selected_extruder==0); m_canvas_widget->Refresh(); } else update_sliders(zs, keep_z_range); @@ -944,7 +959,7 @@ void Preview::load_print_as_sla() n_layers = (unsigned int)zs.size(); if (n_layers == 0) { - reset_sliders(); + reset_sliders(true); m_canvas_widget->Refresh(); } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 64b8baa7fc..7a11e334cf 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -105,6 +105,7 @@ class Preview : public wxPanel DoubleSlider* m_slider {nullptr}; wxBitmapComboBox* m_extruder_selector {nullptr}; + int m_selected_extruder {0}; // 0 means "Whole print" public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, @@ -144,7 +145,7 @@ private: void show_hide_ui_elements(const std::string& what); - void reset_sliders(); + void reset_sliders(bool reset_all); void update_sliders(const std::vector& layers_z, bool keep_z_range = false); void on_size(wxSizeEvent& evt);