OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::TextureImportDialog Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/TextureImportDialog.hpp>

Inheritance diagram for Slic3r::GUI::TextureImportDialog:
Collaboration diagram for Slic3r::GUI::TextureImportDialog:

Public Member Functions

 TextureImportDialog (wxWindow *parent, const Slic3r::TexturedMesh &textured_mesh, const std::vector< TextureFilamentEntry > &filament_entries, std::function< bool()> initial_cancel_callback={}, std::function< bool(int)> initial_progress_callback={})
 ~TextureImportDialog ()
int ShowModal () override
void on_dpi_changed (const wxRect &suggested_rect) override
Slic3r::PaintedMesh get_painted_mesh () const
std::vector< Slic3r::FilamentMatch > get_matches () const
bool was_skipped () const
bool fallback_to_geometry_only () const
const std::vector< std::array< float, 4 > > & get_new_filament_colors () const
const std::vector< std::string > & get_new_filament_preset_names () const
const std::vector< TextureNewMixedFilament > & get_new_mixed_filaments () const
const std::vector< TextureFilamentEntry > & get_filament_entries () const
size_t get_existing_filament_count () const
void EndModal (int retCode) override
float scale_factor () const
float prev_scale_factor () const
void set_scale_factor (float v)
void set_prev_scale_factor (float v)
void set_em_unit (int v)
bool force_rescale () const
int em_unit () const
const wxFont & normal_font () const
void enable_force_rescale ()

Protected Member Functions

virtual void on_sys_color_changed ()

Private Member Functions

void build_ui ()
void build_preview_panel (wxWindow *parent, wxSizer *sizer)
void build_params_panel (wxWindow *parent, wxSizer *sizer)
void build_mapping_panel (wxWindow *parent, wxSizer *sizer)
void build_bottom_buttons (wxSizer *sizer)
void set_state (TextureImportState new_state)
void update_ui_for_state ()
void start_computation (bool auto_color=false, bool initial=false)
void cancel_computation ()
void on_computation_complete (wxCommandEvent &evt)
void on_computation_progress (wxCommandEvent &evt)
void on_computation_error (wxCommandEvent &evt)
void on_mesh_repair_decision_required (wxCommandEvent &evt)
void rebuild_mapping_rows ()
void do_auto_match ()
void sort_current_matches_by_filament_index ()
void restore_current_match_order (const std::vector< Slic3r::FilamentMatch > &previous_matches)
std::vector< Slic3r::FilamentMatch > build_matches_from_rows () const
void update_filament_color_map ()
void show_filament_popup (size_t row_index)
void dismiss_filament_popup ()
void dismiss_filament_popup_on_wheel (wxMouseEvent &evt)
void show_auto_mix_popup ()
void dismiss_auto_mix_popup ()
void set_auto_mix_mode (TextureAutoMixMode mode)
void apply_auto_standard_mix (TextureAutoMixMode mode)
void reset_auto_mix ()
void update_auto_mix_reset_visibility ()
bool add_decomposed_mixed_filament (size_t row_index)
int add_virtual_filament (const std::array< float, 4 > &rgba, const std::string &hex, const std::string &preset_name=std::string())
int add_virtual_mixed_filament (const std::string &color_hex, const std::vector< int > &component_dialog_indices, const std::vector< int > &ratios)
size_t max_filament_count () const
bool can_add_virtual_filament () const
void update_drop_warning_visibility ()
void compact_used_virtual_filaments ()
int find_closest_filament_index (const std::array< std::size_t, 3 > &color) const
std::vector< int > compute_display_numbers () const
void on_color_preset_clicked (wxCommandEvent &evt)
void on_color_slider_changed (wxCommandEvent &evt)
void on_color_spin_changed (wxCommandEvent &evt)
void on_color_spin_text_changed (wxCommandEvent &evt)
void on_smooth_slider_changed (wxCommandEvent &evt)
void on_smooth_spin_changed (wxCommandEvent &evt)
void on_smooth_spin_text_changed (wxCommandEvent &evt)
void on_apply_clicked (wxCommandEvent &evt)
void on_auto_merge_toggled (wxCommandEvent &evt)
void highlight_view_button (int view_index)
void on_skip_clicked (wxCommandEvent &evt)
void on_ok_clicked (wxCommandEvent &evt)
void set_color_count_value (int value, bool update_spin)
void set_smooth_value (int value, bool update_spin)
void preview_spin_text_value (SpinInput *spin, AccentSlider *slider, int &param, int min_value, int max_value, const wxString &text, std::function< void()> on_value_changed={})
void update_color_count_preset_buttons ()
bool has_valid_result () const
bool is_params_dirty () const
void update_confirm_button_state ()
void style_confirm_button (bool dirty)
 wxDECLARE_EVENT_TABLE ()
void update_em_unit ()
bool is_new_scale_factor () const
void rescale (const wxRect &suggested_rect)

Private Attributes

Slic3r::TexturedMesh m_textured_mesh
std::vector< std::string > m_filament_color_strs
std::vector< std::string > m_filament_names
std::vector< std::array< float, 4 > > m_filament_colors_rgba
std::vector< TextureFilamentEntry > m_filament_entries
size_t m_existing_filament_count = 0
std::vector< std::array< float, 4 > > m_new_filament_colors
std::vector< std::string > m_new_filament_preset_names
std::vector< TextureNewMixedFilament > m_new_mixed_filaments
std::string m_default_virtual_filament_preset_name
TextureImportState m_state = TextureImportState::Idle
bool m_skipped = false
bool m_fallback_to_geometry_only = false
bool m_filaments_dropped = false
bool m_auto_merge_enabled = true
TextureAutoMixMode m_auto_mix_mode = TextureAutoMixMode::CMYW
int m_auto_mix_font_point_size = 10
Slic3r::PaintedMesh m_painted
std::vector< Slic3r::FilamentMatch > m_current_matches
std::unique_ptr< std::thread > m_worker
std::atomic< bool > m_cancel_flag {false}
std::mutex m_result_mutex
Slic3r::PaintedMesh m_pending_result
std::function< bool()> m_initial_cancel_callback
std::function< bool(int)> m_initial_progress_callback
bool m_current_computation_initial = false
bool m_initial_computation_pending = false
bool m_initial_computation_cancelled = false
bool m_initial_computation_failed = false
bool m_initial_tooltips_set = false
bool m_current_computation_auto_color = false
Slic3r::TexturePaintingSettings::MeshRepairDecision m_mesh_repair_decision
Button * m_btn_color_4 = nullptr
Button * m_btn_color_8 = nullptr
Button * m_btn_color_16 = nullptr
Button * m_btn_color_auto = nullptr
AccentSlider * m_color_slider = nullptr
SpinInput * m_color_spin = nullptr
AccentSlider * m_smooth_slider = nullptr
SpinInput * m_smooth_spin = nullptr
Button * m_btn_apply = nullptr
wxCheckBox * m_auto_merge_cb = nullptr
Button * m_btn_auto_mix = nullptr
Button * m_btn_mix_reset = nullptr
bool m_auto_mix_applied = false
AutoMixSelectPopup * m_auto_mix_popup = nullptr
wxScrolledWindow * m_mapping_scroll = nullptr
wxBoxSizer * m_mapping_sizer = nullptr
std::vector< FilamentMappingRow > m_mapping_rows
FilamentSelectPopup * m_filament_popup = nullptr
int m_filament_popup_row = -1
int m_skip_next_filament_popup_row = -1
TexturePreviewCanvas * m_preview_canvas = nullptr
wxPanel * m_tab_panel = nullptr
Button * m_btn_view_original = nullptr
Button * m_btn_view_multicolor = nullptr
ProgressDialog * m_progress_dlg = nullptr
Button * m_btn_skip = nullptr
Button * m_btn_ok = nullptr
wxStaticText * m_drop_warning_label = nullptr
int m_param_color_count = 4
int m_param_smooth = 5
int m_applied_color_count = -1
int m_applied_smooth = -1
wxStaticText * m_hint_label = nullptr
float m_scale_factor
int m_em_unit
wxFont m_normal_font
float m_prev_scale_factor
bool m_can_rescale
bool m_force_rescale
int m_new_font_point_size

Static Private Attributes

static const int ID_COLOR_4 = wxID_HIGHEST + 200
static const int ID_COLOR_8 = wxID_HIGHEST + 201
static const int ID_COLOR_16 = wxID_HIGHEST + 202
static const int ID_COLOR_AUTO = wxID_HIGHEST + 203
static const int ID_BTN_APPLY = wxID_HIGHEST + 204
static const int ID_BTN_SKIP = wxID_HIGHEST + 205
static const int ID_VIEW_ORIGINAL = wxID_HIGHEST + 206
static const int ID_VIEW_MULTICOLOR = wxID_HIGHEST + 207

Detailed Description

Constructor & Destructor Documentation

◆ TextureImportDialog()

Slic3r::GUI::TextureImportDialog::TextureImportDialog ( wxWindow * parent,
const Slic3r::TexturedMesh & textured_mesh,
const std::vector< TextureFilamentEntry > & filament_entries,
std::function< bool()> initial_cancel_callback = {},
std::function< bool(int)> initial_progress_callback = {} )

◆ ~TextureImportDialog()

Slic3r::GUI::TextureImportDialog::~TextureImportDialog ( )
1868{
1871 m_cancel_flag = true;
1872 if (m_worker && m_worker->joinable())
1873 m_worker->join();
1874}
std::atomic< bool > m_cancel_flag
Definition TextureImportDialog.hpp:344
void dismiss_auto_mix_popup()
Definition TextureImportDialog.cpp:3082
void dismiss_filament_popup()
Definition TextureImportDialog.cpp:3028
std::unique_ptr< std::thread > m_worker
Definition TextureImportDialog.hpp:343

References dismiss_auto_mix_popup(), dismiss_filament_popup(), m_cancel_flag, and m_worker.

Here is the call graph for this function:

Member Function Documentation

◆ add_decomposed_mixed_filament()

bool Slic3r::GUI::TextureImportDialog::add_decomposed_mixed_filament ( size_t row_index)
private
3245{
3246 if (row_index >= m_mapping_rows.size())
3247 return false;
3248
3249 std::vector<std::string> physical_colors;
3250 std::vector<std::string> physical_names;
3251 std::vector<std::string> physical_types;
3252 std::vector<int> physical_dialog_indices;
3253 std::vector<size_t> physical_config_indices;
3254 auto& preset_bundle = *wxGetApp().preset_bundle;
3255 for (const auto& entry : m_filament_entries) {
3256 if (entry.kind != TextureFilamentKind::ExistingPhysical)
3257 continue;
3258 physical_colors.push_back(entry.color_hex);
3259 physical_names.push_back(entry.name);
3260 const size_t cfg_idx = entry.project_config_index;
3261 Preset* preset = nullptr;
3262 if (cfg_idx < preset_bundle.filament_presets.size())
3263 preset = preset_bundle.filaments.find_preset(preset_bundle.filament_presets[cfg_idx]);
3264 physical_types.push_back(filament_type_for_color_decompose(preset));
3265 physical_dialog_indices.push_back(entry.dialog_index);
3266 physical_config_indices.push_back(cfg_idx);
3267 }
3268 if (physical_colors.empty())
3269 return false;
3270
3271 wxColour target(m_mapping_rows[row_index].source_hex);
3272 ColorDecomposeDialog dlg(this, -1, target, physical_colors, physical_names, physical_types,
3274 std::move(physical_config_indices));
3275 // Count "new physical filaments" with the exact reuse rule of the write-back
3276 // loop below: a base color is only new if no existing OR virtual official
3277 // Bambu Basic filament already carries that color. This keeps the dialog's
3278 // filament-limit pre-check consistent with what add_decomposed_mixed_filament
3279 // will actually create, so already-present virtual base colors are not
3280 // double counted (which previously could wrongly disable OK).
3281 dlg.set_missing_physical_calculator([this](const ColorDecomposeResult& result) -> size_t {
3282 size_t missing = 0;
3283 for (const DecomposeComponent& comp : result.components) {
3284 if (comp.filament_index > 0)
3285 continue; // reuses a physical slot passed to the dialog, no new filament
3286 const std::string comp_hex = texture_normalize_color_hex(
3287 comp.colour.GetAsString(wxC2S_HTML_SYNTAX).ToStdString());
3288 bool found = false;
3289 for (const auto& entry : m_filament_entries) {
3290 if (!texture_entry_is_physical(entry.kind))
3291 continue;
3292 if (texture_normalize_color_hex(entry.color_hex) != comp_hex)
3293 continue;
3294 if (texture_entry_official_basic(entry)) {
3295 found = true;
3296 break;
3297 }
3298 }
3299 if (!found)
3300 ++missing;
3301 }
3302 return missing;
3303 });
3304 if (dlg.ShowModal() != wxID_OK)
3305 return false;
3306
3307 ColorDecomposeResult result = dlg.get_result();
3308 std::vector<int> component_dialog_indices;
3309 std::vector<int> ratios;
3310 for (const DecomposeComponent& comp : result.components) {
3311 ratios.push_back(comp.ratio);
3312 if (comp.filament_index > 0) {
3313 const size_t physical_idx = (size_t)(comp.filament_index - 1);
3314 if (physical_idx >= physical_dialog_indices.size())
3315 return false;
3316 component_dialog_indices.push_back(physical_dialog_indices[physical_idx]);
3317 continue;
3318 }
3319
3320 const std::string comp_hex = texture_normalize_color_hex(comp.colour.GetAsString(wxC2S_HTML_SYNTAX).ToStdString());
3321 int existing_idx = -1;
3322 for (const auto& entry : m_filament_entries) {
3323 if (!texture_entry_is_physical(entry.kind))
3324 continue;
3325 if (texture_normalize_color_hex(entry.color_hex) != comp_hex)
3326 continue;
3327 if (texture_entry_official_basic(entry)) {
3328 existing_idx = entry.dialog_index;
3329 break;
3330 }
3331 }
3332 if (existing_idx < 0) {
3333 std::array<float, 4> rgba = parse_color_string(comp_hex);
3334 existing_idx = add_virtual_filament(rgba, comp_hex);
3335 if (existing_idx < 0)
3336 return false;
3337 }
3338 component_dialog_indices.push_back(existing_idx);
3339 }
3340
3341 if (component_dialog_indices.size() < 2 || component_dialog_indices.size() != ratios.size())
3342 return false;
3343
3344 const std::string mixed_hex = texture_normalize_color_hex(
3345 result.matched_color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString());
3346 int mixed_idx = add_virtual_mixed_filament(mixed_hex, component_dialog_indices, ratios);
3347 if (mixed_idx < 0)
3348 return false;
3349
3350 m_mapping_rows[row_index].target_filament_idx = mixed_idx;
3351 if (row_index < m_current_matches.size())
3352 m_current_matches[row_index].filament_index = mixed_idx;
3355 return true;
3356}
void update_filament_color_map()
Definition TextureImportDialog.cpp:2615
int add_virtual_mixed_filament(const std::string &color_hex, const std::vector< int > &component_dialog_indices, const std::vector< int > &ratios)
Definition TextureImportDialog.cpp:2754
int add_virtual_filament(const std::array< float, 4 > &rgba, const std::string &hex, const std::string &preset_name=std::string())
Definition TextureImportDialog.cpp:2717
std::vector< Slic3r::FilamentMatch > m_current_matches
Definition TextureImportDialog.hpp:341
std::vector< TextureFilamentEntry > m_filament_entries
Definition TextureImportDialog.hpp:319
size_t max_filament_count() const
Definition TextureImportDialog.cpp:2692
void rebuild_mapping_rows()
Definition TextureImportDialog.cpp:3611
std::vector< FilamentMappingRow > m_mapping_rows
Definition TextureImportDialog.hpp:375
std::string filament_type_for_color_decompose(Preset *preset)
Definition ColorDecomposeSupport.cpp:221
static bool texture_entry_official_basic(const TextureFilamentEntry &entry)
Definition TextureImportDialog.cpp:419
static std::string texture_normalize_color_hex(std::string hex)
Definition TextureImportDialog.cpp:385
@ ExistingPhysical
Definition TextureImportDialog.hpp:55
static bool texture_entry_is_physical(TextureFilamentKind kind)
Definition TextureImportDialog.cpp:402
static std::array< float, 4 > parse_color_string(const std::string &hex)
Definition TextureImportDialog.cpp:359
@ Preset
Definition calib.hpp:39

References add_virtual_filament(), add_virtual_mixed_filament(), Slic3r::GUI::DecomposeComponent::colour, Slic3r::GUI::ColorDecomposeResult::components, Slic3r::GUI::ExistingPhysical, Slic3r::GUI::DecomposeComponent::filament_index, Slic3r::GUI::filament_type_for_color_decompose(), Slic3r::GUI::ColorDecomposeDialog::get_result(), m_current_matches, m_filament_entries, m_mapping_rows, Slic3r::GUI::ColorDecomposeResult::matched_color, max_filament_count(), Slic3r::GUI::parse_color_string(), Slic3r::GUI::DecomposeComponent::ratio, rebuild_mapping_rows(), Slic3r::GUI::ColorDecomposeDialog::set_missing_physical_calculator(), Slic3r::GUI::DPIAware< P >::ShowModal(), Slic3r::GUI::texture_entry_is_physical(), Slic3r::GUI::texture_entry_official_basic(), Slic3r::GUI::texture_normalize_color_hex(), and update_filament_color_map().

Referenced by show_filament_popup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_virtual_filament()

int Slic3r::GUI::TextureImportDialog::add_virtual_filament ( const std::array< float, 4 > & rgba,
const std::string & hex,
const std::string & preset_name = std::string() )
private
2719{
2720 if (m_filament_color_strs.size() != m_filament_colors_rgba.size() ||
2721 m_filament_names.size() != m_filament_colors_rgba.size() ||
2722 m_filament_entries.size() != m_filament_colors_rgba.size()) {
2723 return -1;
2724 }
2725 if (!can_add_virtual_filament()) {
2726 // Mark that this do_auto_match() run hit the filament cap and had to
2727 // drop at least one cluster. The mapping itself still falls back via
2728 // find_closest_filament_index() below; this flag only drives the
2729 // inline orange warning above the bottom buttons.
2730 // Note: only the false -> true transition happens here; the flag is
2731 // cleared exclusively at the entry of do_auto_match() so it always
2732 // reflects the most recent match, never an accumulated history.
2733 m_filaments_dropped = true;
2734 return -1;
2735 }
2736
2737 const int new_idx = (int)m_filament_colors_rgba.size();
2738 m_filament_colors_rgba.push_back(rgba);
2739 m_filament_color_strs.push_back(hex);
2741 TextureFilamentEntry entry;
2743 entry.dialog_index = new_idx;
2744 entry.project_config_index = size_t(-1);
2745 entry.color_hex = texture_normalize_color_hex(hex);
2746 entry.name = DEFAULT_VIRTUAL_FILAMENT_NAME;
2747 entry.preset_name = preset_name.empty() ? m_default_virtual_filament_preset_name : preset_name;
2748 m_filament_entries.push_back(entry);
2749 m_new_filament_colors.push_back(rgba);
2750 m_new_filament_preset_names.push_back(preset_name.empty() ? m_default_virtual_filament_preset_name : preset_name);
2751 return new_idx;
2752}
static constexpr const char * DEFAULT_VIRTUAL_FILAMENT_NAME
Definition TextureImportDialog.cpp:83
bool m_filaments_dropped
Definition TextureImportDialog.hpp:335
std::vector< std::string > m_filament_names
Definition TextureImportDialog.hpp:317
std::string m_default_virtual_filament_preset_name
Definition TextureImportDialog.hpp:324
std::vector< std::string > m_filament_color_strs
Definition TextureImportDialog.hpp:316
std::vector< std::array< float, 4 > > m_new_filament_colors
Definition TextureImportDialog.hpp:321
std::vector< std::string > m_new_filament_preset_names
Definition TextureImportDialog.hpp:322
std::vector< std::array< float, 4 > > m_filament_colors_rgba
Definition TextureImportDialog.hpp:318
bool can_add_virtual_filament() const
Definition TextureImportDialog.cpp:2697
@ NewPhysical
Definition TextureImportDialog.hpp:57

References can_add_virtual_filament(), Slic3r::GUI::TextureFilamentEntry::color_hex, DEFAULT_VIRTUAL_FILAMENT_NAME, Slic3r::GUI::TextureFilamentEntry::dialog_index, Slic3r::GUI::TextureFilamentEntry::kind, m_default_virtual_filament_preset_name, m_filament_color_strs, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_filaments_dropped, m_new_filament_colors, m_new_filament_preset_names, Slic3r::GUI::TextureFilamentEntry::name, Slic3r::GUI::NewPhysical, Slic3r::GUI::TextureFilamentEntry::preset_name, Slic3r::GUI::TextureFilamentEntry::project_config_index, and Slic3r::GUI::texture_normalize_color_hex().

Referenced by add_decomposed_mixed_filament(), apply_auto_standard_mix(), do_auto_match(), and show_filament_popup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_virtual_mixed_filament()

int Slic3r::GUI::TextureImportDialog::add_virtual_mixed_filament ( const std::string & color_hex,
const std::vector< int > & component_dialog_indices,
const std::vector< int > & ratios )
private
2757{
2758 if (m_filament_color_strs.size() != m_filament_colors_rgba.size() ||
2759 m_filament_names.size() != m_filament_colors_rgba.size() ||
2760 m_filament_entries.size() != m_filament_colors_rgba.size()) {
2761 return -1;
2762 }
2763 if (component_dialog_indices.size() < 2 || component_dialog_indices.size() != ratios.size())
2764 return -1;
2765 for (int idx : component_dialog_indices) {
2766 if (idx < 0 || idx >= (int)m_filament_entries.size() ||
2768 return -1;
2769 }
2770 }
2771 if (!can_add_virtual_filament()) {
2772 m_filaments_dropped = true;
2773 return -1;
2774 }
2775
2776 const int new_idx = (int)m_filament_colors_rgba.size();
2777 TextureFilamentEntry entry;
2778 entry.kind = TextureFilamentKind::NewMixed;
2779 entry.dialog_index = new_idx;
2780 entry.project_config_index = size_t(-1);
2781 entry.color_hex = texture_normalize_color_hex(color_hex);
2782 entry.name = DEFAULT_VIRTUAL_FILAMENT_NAME;
2783 entry.mixed_ratios = ratios;
2784 for (int idx : component_dialog_indices)
2785 entry.mixed_components.push_back((unsigned int)(idx + 1));
2786
2787 TextureNewMixedFilament mixed;
2788 mixed.dialog_index = entry.dialog_index;
2789 mixed.color_hex = entry.color_hex;
2790 mixed.component_dialog_indices = component_dialog_indices;
2791 mixed.ratios = ratios;
2792
2793 m_filament_entries.push_back(entry);
2794 m_filament_color_strs.push_back(entry.color_hex);
2795 m_filament_names.push_back(entry.name);
2796 m_filament_colors_rgba.push_back(parse_color_string(entry.color_hex));
2797 m_new_mixed_filaments.push_back(mixed);
2798 return entry.dialog_index;
2799}
std::vector< TextureNewMixedFilament > m_new_mixed_filaments
Definition TextureImportDialog.hpp:323
@ NewMixed
Definition TextureImportDialog.hpp:58

References can_add_virtual_filament(), Slic3r::GUI::TextureFilamentEntry::color_hex, Slic3r::GUI::TextureNewMixedFilament::color_hex, Slic3r::GUI::TextureNewMixedFilament::component_dialog_indices, DEFAULT_VIRTUAL_FILAMENT_NAME, Slic3r::GUI::TextureFilamentEntry::dialog_index, Slic3r::GUI::TextureNewMixedFilament::dialog_index, Slic3r::GUI::TextureFilamentEntry::kind, m_filament_color_strs, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_filaments_dropped, m_new_mixed_filaments, Slic3r::GUI::TextureFilamentEntry::mixed_components, Slic3r::GUI::TextureFilamentEntry::mixed_ratios, Slic3r::GUI::TextureFilamentEntry::name, Slic3r::GUI::NewMixed, Slic3r::GUI::parse_color_string(), Slic3r::GUI::TextureFilamentEntry::project_config_index, Slic3r::GUI::TextureNewMixedFilament::ratios, Slic3r::GUI::texture_entry_is_physical(), and Slic3r::GUI::texture_normalize_color_hex().

Referenced by add_decomposed_mixed_filament(), and apply_auto_standard_mix().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_auto_standard_mix()

void Slic3r::GUI::TextureImportDialog::apply_auto_standard_mix ( TextureAutoMixMode mode)
private
3106{
3107 if (m_mapping_rows.empty())
3108 return;
3109 m_filaments_dropped = false;
3110
3111 auto find_or_add_base_physical = [this](const std::string& color_hex) -> int {
3112 const std::string normalized = texture_normalize_color_hex(color_hex);
3113 for (const auto& entry : m_filament_entries) {
3114 if (!texture_entry_is_physical(entry.kind))
3115 continue;
3116 if (texture_normalize_color_hex(entry.color_hex) != normalized)
3117 continue;
3118 if (texture_entry_is_pla_basic(entry))
3119 return entry.dialog_index;
3120 }
3121
3122 std::array<float, 4> rgba = parse_color_string(normalized);
3124 if (idx >= 0 && idx < (int)m_filament_entries.size()) {
3127 }
3128 return idx;
3129 };
3130
3131 auto find_existing_mixed = [this](const std::vector<int>& component_indices, const std::vector<int>& ratios) -> int {
3132 for (const auto& entry : m_filament_entries) {
3133 if (!texture_entry_is_mixed(entry.kind) || entry.mixed_components.size() != component_indices.size() ||
3134 entry.mixed_ratios.size() != ratios.size())
3135 continue;
3136 bool same = true;
3137 for (size_t i = 0; i < component_indices.size(); ++i) {
3138 if (entry.mixed_components[i] != (unsigned int)(component_indices[i] + 1) ||
3139 entry.mixed_ratios[i] != ratios[i]) {
3140 same = false;
3141 break;
3142 }
3143 }
3144 if (same)
3145 return entry.dialog_index;
3146 }
3147 return -1;
3148 };
3149
3150 bool changed = false;
3151 const auto recipe_mode = texture_recipe_mode(mode);
3152 for (size_t row_index = 0; row_index < m_mapping_rows.size(); ++row_index) {
3153 Slic3r::ColorDecomposeRgb target_rgb;
3154 if (!Slic3r::color_decompose_hex_to_rgb(m_mapping_rows[row_index].source_hex, target_rgb))
3155 continue;
3156
3157 auto recipe = Slic3r::lookup_standard_recipe(target_rgb, recipe_mode, DEFAULT_VIRTUAL_FILAMENT_BASIC_TYPE);
3158 if (!recipe.valid || recipe.components.size() < 2)
3159 continue;
3160
3161 std::vector<int> component_dialog_indices;
3162 std::vector<int> ratios;
3163 for (const auto& comp : recipe.components) {
3164 int component_idx = find_or_add_base_physical(comp.color_hex);
3165 if (component_idx < 0) {
3166 component_dialog_indices.clear();
3167 break;
3168 }
3169 component_dialog_indices.push_back(component_idx);
3170 ratios.push_back(comp.ratio);
3171 }
3172 if (component_dialog_indices.size() < 2 || component_dialog_indices.size() != ratios.size())
3173 continue;
3174
3175 int mixed_idx = find_existing_mixed(component_dialog_indices, ratios);
3176 if (mixed_idx < 0)
3177 mixed_idx = add_virtual_mixed_filament(recipe.matched_color_hex, component_dialog_indices, ratios);
3178 if (mixed_idx < 0)
3179 continue;
3180
3181 m_mapping_rows[row_index].target_filament_idx = mixed_idx;
3182 if (row_index < m_current_matches.size()) {
3183 m_current_matches[row_index].filament_index = mixed_idx;
3184 m_current_matches[row_index].filament_color = m_filament_colors_rgba[mixed_idx];
3185 m_current_matches[row_index].delta_e = Slic3r::compute_delta_e(
3186 m_current_matches[row_index].cluster_color, m_current_matches[row_index].filament_color);
3187 if (mixed_idx >= (int)m_existing_filament_count)
3188 m_current_matches[row_index].delta_e = 0.0;
3189 }
3190 changed = true;
3191 }
3192
3193 if (!changed)
3194 return;
3195
3196 m_auto_mix_applied = true;
3202}
static constexpr const char * DEFAULT_VIRTUAL_FILAMENT_BASIC_TYPE
Definition TextureImportDialog.cpp:81
bool m_auto_mix_applied
Definition TextureImportDialog.hpp:371
void update_drop_warning_visibility()
Definition TextureImportDialog.cpp:4114
size_t m_existing_filament_count
Definition TextureImportDialog.hpp:320
void update_auto_mix_reset_visibility()
Definition TextureImportDialog.cpp:3234
void compact_used_virtual_filaments()
Definition TextureImportDialog.cpp:2801
static bool texture_entry_is_mixed(TextureFilamentKind kind)
Definition TextureImportDialog.cpp:407
static bool texture_entry_is_pla_basic(const TextureFilamentEntry &entry)
Definition TextureImportDialog.cpp:412
static Slic3r::ColorDecomposeRecipeMode texture_recipe_mode(TextureAutoMixMode mode)
Definition TextureImportDialog.cpp:434
ColorDecomposeRecipeResult lookup_standard_recipe(const ColorDecomposeRgb &target, ColorDecomposeRecipeMode mode, const std::string &preferred_material_type)
Definition ColorDecomposeRecipe.cpp:333
double compute_delta_e(const std::array< std::size_t, 3 > &rgb1, const std::array< float, 4 > &rgba2)
Definition TexturePainting.cpp:431
bool color_decompose_hex_to_rgb(const std::string &hex, ColorDecomposeRgb &out)
Definition ColorDecomposeRecipe.cpp:239

References add_virtual_filament(), add_virtual_mixed_filament(), Slic3r::color_decompose_hex_to_rgb(), compact_used_virtual_filaments(), Slic3r::compute_delta_e(), DEFAULT_VIRTUAL_FILAMENT_BASIC_TYPE, DEFAULT_VIRTUAL_FILAMENT_NAME, Slic3r::lookup_standard_recipe(), m_auto_mix_applied, m_current_matches, m_default_virtual_filament_preset_name, m_existing_filament_count, m_filament_colors_rgba, m_filament_entries, m_filaments_dropped, m_mapping_rows, Slic3r::GUI::parse_color_string(), rebuild_mapping_rows(), Slic3r::GUI::texture_entry_is_mixed(), Slic3r::GUI::texture_entry_is_physical(), Slic3r::GUI::texture_entry_is_pla_basic(), Slic3r::GUI::texture_normalize_color_hex(), Slic3r::GUI::texture_recipe_mode(), update_auto_mix_reset_visibility(), update_drop_warning_visibility(), and update_filament_color_map().

Referenced by set_auto_mix_mode().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_bottom_buttons()

void Slic3r::GUI::TextureImportDialog::build_bottom_buttons ( wxSizer * sizer)
private
2221{
2222 m_drop_warning_label = new wxStaticText(this, wxID_ANY,
2223 wxString::Format(
2224 _L_PLURAL("The project supports up to %d filament. Extra filaments will be discarded.",
2225 "The project supports up to %d filaments. Extra filaments will be discarded.",
2226 (int)max_filament_count()),
2227 (int)max_filament_count()));
2228 m_drop_warning_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#FF6F00")));
2230 m_drop_warning_label->Hide();
2231 sizer->Add(m_drop_warning_label, 0, wxALIGN_LEFT | wxBOTTOM, FromDIP(4));
2232
2233 wxBoxSizer* btn_sizer = new wxBoxSizer(wxHORIZONTAL);
2234 m_btn_skip = new Button(this, _L("Skip Matching"));
2235 m_btn_skip->SetId(ID_BTN_SKIP);
2236 m_btn_skip->SetToolTip(_L("Skip filament mapping and import as a single-color model"));
2238
2239 m_btn_ok = new Button(this, _L("Confirm"));
2240 m_btn_ok->SetId(wxID_OK);
2242 m_btn_ok->EnableTooltipEvenDisabled();
2243
2244 btn_sizer->AddStretchSpacer();
2245 btn_sizer->Add(m_btn_ok, 0, wxRIGHT, FromDIP(16)); // Match ordering of choice buttons on whole UI
2246 btn_sizer->Add(m_btn_skip, 0);
2247
2248 sizer->Add(btn_sizer, 0, wxEXPAND | wxTOP, FromDIP(8));
2249}
@ Confirm
Definition Button.hpp:25
@ Regular
Definition Button.hpp:24
@ Choice
Definition Button.hpp:33
#define _L(s)
Definition OBJ.cpp:34
class WXDLLIMPEXP_FWD_CORE wxStaticText
Definition ProgressDialog.hpp:30
static wxFont texture_import_section_title_font(wxWindow *win)
Definition TextureImportDialog.cpp:106
Button * m_btn_ok
Definition TextureImportDialog.hpp:388
static const int ID_BTN_SKIP
Definition TextureImportDialog.hpp:403
Button * m_btn_skip
Definition TextureImportDialog.hpp:387
wxStaticText * m_drop_warning_label
Definition TextureImportDialog.hpp:389
static wxColour darkModeColorFor(wxColour const &color)
Definition StateColor.cpp:219
#define _L_PLURAL(s, plural, n)
Definition I18N.hpp:96

References _L, _L_PLURAL, Choice, Confirm, StateColor::darkModeColorFor(), ID_BTN_SKIP, m_btn_ok, m_btn_skip, m_drop_warning_label, max_filament_count(), Regular, texture_import_section_title_font(), and wxStaticText.

Referenced by build_ui().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_mapping_panel()

void Slic3r::GUI::TextureImportDialog::build_mapping_panel ( wxWindow * parent,
wxSizer * sizer )
private
2162{
2163 wxColour secondary_fg = StateColor::darkModeColorFor(wxColour("#363636"));
2164
2165 wxBoxSizer* header_sizer = new wxBoxSizer(wxHORIZONTAL);
2166
2167 wxStaticText* lbl_mapping = new wxStaticText(parent, wxID_ANY, _L("Filament Mapping"));
2168 lbl_mapping->SetForegroundColour(secondary_fg);
2169 lbl_mapping->SetFont(Label::Head_14);
2170 m_auto_mix_font_point_size = lbl_mapping->GetFont().GetPointSize();
2171 header_sizer->Add(lbl_mapping, 0, wxALIGN_CENTER_VERTICAL);
2172
2173 m_btn_mix_reset = new Button(parent, "", "revert_btn", wxBORDER_NONE, 16);
2174 m_btn_mix_reset->SetCanFocus(false);
2176 m_btn_mix_reset->SetToolTip(_L("Reset filament mapping to the state before one-click mixing"));
2177 m_btn_mix_reset->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) {
2179 evt.Skip();
2180 });
2181 m_btn_mix_reset->Hide();
2182 header_sizer->Add(m_btn_mix_reset, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(6));
2183
2184 header_sizer->AddStretchSpacer();
2185
2186 m_btn_auto_mix = new Button(parent, auto_mix_mode_label(m_auto_mix_mode), "drop_down", 0, 16);
2188 m_btn_auto_mix->SetToolTip(_L("Choose the one-click auto-mix mode for texture color import"));
2189 m_btn_auto_mix->Bind(wxEVT_BUTTON, [this](wxCommandEvent& evt) { // ORCA show popup on click instead
2191 evt.Skip();
2192 });
2193 header_sizer->Add(m_btn_auto_mix, 0, wxALIGN_CENTER_VERTICAL);
2194
2195 sizer->Add(header_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(4));
2196
2197 wxBoxSizer* merge_sizer = new wxBoxSizer(wxHORIZONTAL);
2198 m_auto_merge_cb = new wxCheckBox(parent, wxID_ANY, _L("Auto-merge same filament"));
2200 m_auto_merge_cb->SetToolTip(_L("Automatically merge identical filaments into existing filaments in the project"));
2201 m_auto_merge_cb->SetForegroundColour(secondary_fg);
2202 m_auto_merge_cb->SetValue(true);
2203 m_auto_merge_cb->Bind(wxEVT_CHECKBOX, &TextureImportDialog::on_auto_merge_toggled, this);
2204 merge_sizer->Add(m_auto_merge_cb, 0, wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM, FromDIP(5));
2205
2206 sizer->Add(merge_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(8));
2207
2208 m_mapping_scroll = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition,
2209 wxSize(-1, FromDIP(300)));
2210 m_mapping_scroll->SetScrollRate(0, FromDIP(20));
2211 m_mapping_scroll->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
2213
2214 m_mapping_sizer = new wxBoxSizer(wxVERTICAL);
2216
2217 sizer->Add(m_mapping_scroll, 1, wxEXPAND | wxBOTTOM, FromDIP(8));
2218}
@ Icon
Definition Button.hpp:35
@ Parameter
Definition Button.hpp:34
static wxFont Head_14
Definition Label.hpp:45
static wxFont Body_14
Definition Label.hpp:53
wxBoxSizer * m_mapping_sizer
Definition TextureImportDialog.hpp:374
wxCheckBox * m_auto_merge_cb
Definition TextureImportDialog.hpp:368
wxScrolledWindow * m_mapping_scroll
Definition TextureImportDialog.hpp:373
void on_auto_merge_toggled(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4051
Button * m_btn_mix_reset
Definition TextureImportDialog.hpp:370
Button * m_btn_auto_mix
Definition TextureImportDialog.hpp:369
void show_auto_mix_popup()
Definition TextureImportDialog.cpp:3044
void dismiss_filament_popup_on_wheel(wxMouseEvent &evt)
Definition TextureImportDialog.cpp:3358
int m_auto_mix_font_point_size
Definition TextureImportDialog.hpp:338
void reset_auto_mix()
Definition TextureImportDialog.cpp:3204
TextureAutoMixMode m_auto_mix_mode
Definition TextureImportDialog.hpp:337
static wxString auto_mix_mode_label(TextureAutoMixMode mode)
Definition TextureImportDialog.cpp:483

References _L, Slic3r::GUI::auto_mix_mode_label(), Label::Body_14, StateColor::darkModeColorFor(), dismiss_filament_popup_on_wheel(), Label::Head_14, Icon, m_auto_merge_cb, m_auto_mix_font_point_size, m_auto_mix_mode, m_btn_auto_mix, m_btn_mix_reset, m_mapping_scroll, m_mapping_sizer, on_auto_merge_toggled(), Parameter, Regular, reset_auto_mix(), show_auto_mix_popup(), and wxStaticText.

Referenced by build_ui().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_matches_from_rows()

std::vector< Slic3r::FilamentMatch > Slic3r::GUI::TextureImportDialog::build_matches_from_rows ( ) const
private
3917{
3918 std::vector<Slic3r::FilamentMatch> matches(m_mapping_rows.size());
3919 for (size_t i = 0; i < m_mapping_rows.size(); ++i) {
3920 auto& m = matches[i];
3921 m.cluster_index = m_mapping_rows[i].cluster_id;
3922 m.cluster_color = m_mapping_rows[i].source_color;
3923
3924 int sel = m_mapping_rows[i].target_filament_idx;
3925 if (sel >= 0 && sel < (int)m_filament_colors_rgba.size()) {
3926 m.filament_index = sel;
3927 m.filament_color = m_filament_colors_rgba[sel];
3928 m.delta_e = Slic3r::compute_delta_e(m.cluster_color, m.filament_color);
3929 }
3930 }
3931 return matches;
3932}

References Slic3r::compute_delta_e(), m_filament_colors_rgba, and m_mapping_rows.

Referenced by get_matches(), and on_ok_clicked().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_params_panel()

void Slic3r::GUI::TextureImportDialog::build_params_panel ( wxWindow * parent,
wxSizer * sizer )
private
2059{
2060 wxColour label_fg = StateColor::darkModeColorFor(wxColour("#363636"));
2061
2062 wxBoxSizer* color_header_sizer = new wxBoxSizer(wxHORIZONTAL);
2063 wxStaticText* lbl_colors = new wxStaticText(parent, wxID_ANY, _L("Color Count"));
2064 lbl_colors->SetForegroundColour(label_fg);
2065 lbl_colors->SetFont(Label::Head_14);
2066 color_header_sizer->Add(lbl_colors, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(8));
2067
2068 m_btn_color_4 = new Button(parent, "4");
2069 m_btn_color_4->SetId(ID_COLOR_4);
2070 m_btn_color_8 = new Button(parent, "8");
2071 m_btn_color_8->SetId(ID_COLOR_8);
2072 m_btn_color_16 = new Button(parent, "16");
2074 m_btn_color_auto = new Button(parent, _L("Auto"));
2077
2079
2080 color_header_sizer->AddStretchSpacer();
2081 color_header_sizer->Add(m_btn_color_4, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(2));
2082 color_header_sizer->Add(m_btn_color_8, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(2));
2083 color_header_sizer->Add(m_btn_color_16, 0, wxALIGN_CENTER_VERTICAL);
2084 sizer->Add(color_header_sizer, 0, wxBOTTOM, FromDIP(4));
2085
2086 wxBoxSizer* color_slider_sizer = new wxBoxSizer(wxHORIZONTAL);
2087 m_color_slider = new AccentSlider(parent, m_param_color_count, 1, (int)max_filament_count());
2088 m_color_spin = new SpinInput(parent, wxString::Format("%d", m_param_color_count),
2089 wxEmptyString, wxDefaultPosition,
2090 wxSize(FromDIP(60), FromDIP(28)),
2091 wxTE_PROCESS_ENTER, 1, (int)max_filament_count(), m_param_color_count);
2092
2094 m_color_spin->Bind(wxEVT_SPINCTRL, &TextureImportDialog::on_color_spin_changed, this);
2095 m_color_spin->Bind(EVT_SPINCTRL_TEXT, &TextureImportDialog::on_color_spin_text_changed, this);
2096
2097 color_slider_sizer->Add(m_color_slider, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(4));
2098 color_slider_sizer->Add(m_color_spin, 0, wxALIGN_CENTER_VERTICAL);
2099 sizer->Add(color_slider_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(8));
2100
2101 wxStaticText* lbl_smooth = new wxStaticText(parent, wxID_ANY, _L("Smooth Level"));
2102 lbl_smooth->SetForegroundColour(label_fg);
2103 lbl_smooth->SetFont(Label::Head_14);
2104 sizer->Add(lbl_smooth, 0, wxBOTTOM, FromDIP(4));
2105
2106 wxBoxSizer* smooth_sizer = new wxBoxSizer(wxHORIZONTAL);
2107 m_smooth_slider = new AccentSlider(parent, m_param_smooth, 0, 10);
2108 m_smooth_spin = new SpinInput(parent, wxString::Format("%d", m_param_smooth),
2109 wxEmptyString, wxDefaultPosition,
2110 wxSize(FromDIP(60), FromDIP(28)),
2111 wxTE_PROCESS_ENTER, 0, 10, m_param_smooth);
2112
2114 m_smooth_spin->Bind(wxEVT_SPINCTRL, &TextureImportDialog::on_smooth_spin_changed, this);
2115 m_smooth_spin->Bind(EVT_SPINCTRL_TEXT, &TextureImportDialog::on_smooth_spin_text_changed, this);
2116
2117 smooth_sizer->Add(m_smooth_slider, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(4));
2118 smooth_sizer->Add(m_smooth_spin, 0, wxALIGN_CENTER_VERTICAL);
2119 sizer->Add(smooth_sizer, 0, wxEXPAND | wxBOTTOM, FromDIP(4));
2120
2121 m_btn_apply = new Button(parent, _L("Apply"));
2122 m_btn_apply->SetId(ID_BTN_APPLY);
2124
2125 // Defer attaching the Auto/Apply tooltips until the dialog has actually
2126 // been shown. On macOS, AppKit creates NSTrackingArea and dispatches a
2127 // synthetic mouseEntered: as soon as the window first becomes visible,
2128 // which would otherwise pop the native tooltip without the user actually
2129 // hovering when the cursor happens to land on these buttons as the dialog
2130 // appears.
2131 Bind(wxEVT_SHOW, [this](wxShowEvent& e) {
2132 e.Skip();
2133 if (!e.IsShown() || m_initial_tooltips_set)
2134 return;
2136 CallAfter([this]() {
2137 if (m_btn_color_auto)
2138 m_btn_color_auto->SetToolTip(_L("Automatically determine the optimal color count only and recompute filament mapping"));
2139 if (m_btn_apply)
2140 m_btn_apply->SetToolTip(_L("Convert texture to painting using the specified color count and smooth level"));
2141 });
2142 });
2143
2144 wxBoxSizer* apply_sizer = new wxBoxSizer(wxHORIZONTAL);
2145 apply_sizer->Add(m_btn_color_auto, 0, wxRIGHT, FromDIP(4));
2146 apply_sizer->Add(m_btn_apply, 0);
2147 sizer->Add(apply_sizer, 0, wxALIGN_RIGHT | wxBOTTOM | wxTOP, FromDIP(8));
2148
2149 m_hint_label = new wxStaticText(parent, wxID_ANY,
2150 _L("Reminder: parameters changed, click Apply to take effect"));
2151 m_hint_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#FF6F00")));
2153 m_hint_label->Hide();
2154 sizer->Add(m_hint_label, 0, wxBOTTOM, FromDIP(4));
2155
2156 auto* mapping_separator = new StaticLine(parent);
2157 mapping_separator->SetLineColour(wxColour(SEPARATOR_COLOUR_KEY));
2158 sizer->Add(mapping_separator, 0, wxEXPAND | wxBOTTOM, FromDIP(8));
2159}
@ Window
Definition Button.hpp:32
static constexpr const char * SEPARATOR_COLOUR_KEY
Definition TextureImportDialog.cpp:99
static const int ID_BTN_APPLY
Definition TextureImportDialog.hpp:402
Button * m_btn_color_8
Definition TextureImportDialog.hpp:359
static const int ID_COLOR_8
Definition TextureImportDialog.hpp:399
void on_color_spin_changed(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4018
void on_color_slider_changed(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4013
static const int ID_COLOR_4
Definition TextureImportDialog.hpp:398
Button * m_btn_color_auto
Definition TextureImportDialog.hpp:361
Button * m_btn_color_16
Definition TextureImportDialog.hpp:360
void update_color_count_preset_buttons()
Definition TextureImportDialog.cpp:3936
SpinInput * m_smooth_spin
Definition TextureImportDialog.hpp:365
AccentSlider * m_color_slider
Definition TextureImportDialog.hpp:362
void on_color_spin_text_changed(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4023
static const int ID_COLOR_16
Definition TextureImportDialog.hpp:400
int m_param_smooth
Definition TextureImportDialog.hpp:392
void on_smooth_slider_changed(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4030
SpinInput * m_color_spin
Definition TextureImportDialog.hpp:363
bool m_initial_tooltips_set
Definition TextureImportDialog.hpp:353
void on_smooth_spin_text_changed(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4040
int m_param_color_count
Definition TextureImportDialog.hpp:391
Button * m_btn_color_4
Definition TextureImportDialog.hpp:358
Button * m_btn_apply
Definition TextureImportDialog.hpp:366
wxStaticText * m_hint_label
Definition TextureImportDialog.hpp:396
static const int ID_COLOR_AUTO
Definition TextureImportDialog.hpp:401
AccentSlider * m_smooth_slider
Definition TextureImportDialog.hpp:364
void on_smooth_spin_changed(wxCommandEvent &evt)
Definition TextureImportDialog.cpp:4035

References _L, StateColor::darkModeColorFor(), Label::Head_14, ID_BTN_APPLY, ID_COLOR_16, ID_COLOR_4, ID_COLOR_8, ID_COLOR_AUTO, m_btn_apply, m_btn_color_16, m_btn_color_4, m_btn_color_8, m_btn_color_auto, m_color_slider, m_color_spin, m_hint_label, m_initial_tooltips_set, m_param_color_count, m_param_smooth, m_smooth_slider, m_smooth_spin, max_filament_count(), on_color_slider_changed(), on_color_spin_changed(), on_color_spin_text_changed(), on_smooth_slider_changed(), on_smooth_spin_changed(), on_smooth_spin_text_changed(), Regular, SEPARATOR_COLOUR_KEY, texture_import_section_title_font(), update_color_count_preset_buttons(), Window, and wxStaticText.

Referenced by build_ui().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_preview_panel()

void Slic3r::GUI::TextureImportDialog::build_preview_panel ( wxWindow * parent,
wxSizer * sizer )
private
1956{
1957 wxColour preview_bg = StateColor::darkModeColorFor(wxColour("#EEEEEE"));
1958 wxColour preview_bd = texture_import_separator_colour();
1959
1960 wxPanel* preview_container = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
1961 preview_container->SetBackgroundColour(preview_bg);
1962 preview_container->SetBackgroundStyle(wxBG_STYLE_PAINT);
1963 preview_container->Bind(wxEVT_PAINT, [preview_bg, preview_bd](wxPaintEvent& e) {
1964 auto* p = static_cast<wxPanel*>(e.GetEventObject());
1965 wxAutoBufferedPaintDC dc(p);
1966 wxSize sz = p->GetClientSize();
1967 dc.SetBrush(wxBrush(p->GetParent()->GetBackgroundColour()));
1968 dc.SetPen(*wxTRANSPARENT_PEN);
1969 dc.DrawRectangle(0, 0, sz.x, sz.y);
1970 dc.SetBrush(wxBrush(preview_bg));
1971 dc.SetPen(wxPen(preview_bd, 1));
1972 dc.DrawRoundedRectangle(0, 0, sz.x, sz.y, 4);
1973 });
1974
1975 wxBoxSizer* container_sizer = new wxBoxSizer(wxVERTICAL);
1976
1977 wxGLAttributes canvas_attrs;
1978 canvas_attrs.PlatformDefaults().RGBA().DoubleBuffer().Depth(24).EndList();
1979 m_preview_canvas = new TexturePreviewCanvas(preview_container, canvas_attrs);
1980 container_sizer->Add(m_preview_canvas, 1, wxEXPAND | wxALL, FromDIP(1));
1981
1982 preview_container->SetSizer(container_sizer);
1983 sizer->Add(preview_container, 1, wxEXPAND);
1984
1985 m_tab_panel = new wxPanel(preview_container, wxID_ANY);
1986 m_tab_panel->SetBackgroundColour(preview_bg);
1987
1988 m_btn_view_original = new Button(m_tab_panel, _L("Original"));
1991 m_btn_view_multicolor = new Button(m_tab_panel, _L("Multi-Color"));
1994
1995 const int view_button_height = FromDIP(27);
1996 m_btn_view_original->SetToolTip(_L("Your input texture model"));
1997 m_btn_view_multicolor->SetToolTip(_L("Processed multi-color model"));
1998
1999 wxBoxSizer* tab_sizer = new wxBoxSizer(wxHORIZONTAL);
2000 tab_sizer->Add(m_btn_view_original, 0, wxRIGHT, FromDIP(2));
2001 tab_sizer->Add(m_btn_view_multicolor, 0);
2002 m_tab_panel->SetSizer(tab_sizer);
2003 m_tab_panel->Fit();
2004
2005 m_btn_view_multicolor->Hide();
2006 auto preview_original = [this](wxMouseEvent& e) {
2007 if (m_preview_canvas) {
2010 }
2011 e.Skip();
2012 };
2013 auto preview_multicolor = [this](wxMouseEvent& e) {
2014 if (m_preview_canvas) {
2017 }
2018 e.Skip();
2019 };
2020 auto restore_filament_if_outside = [this](wxMouseEvent& e) {
2022 wxWindow* event_window = wxDynamicCast(e.GetEventObject(), wxWindow);
2023 wxPoint screen_pos = event_window ? event_window->ClientToScreen(e.GetPosition()) : wxGetMousePosition();
2024 wxPoint panel_pos = m_tab_panel->ScreenToClient(screen_pos);
2025 if (!m_tab_panel->GetClientRect().Contains(panel_pos)) {
2026 const bool mapping_ready = (m_state == TextureImportState::Ready);
2027 m_preview_canvas->set_render_mode(mapping_ready ? TexturePreviewCanvas::RenderMode::FilamentMap :
2030 }
2031 }
2032 e.Skip();
2033 };
2034
2035 m_btn_view_original->Bind(wxEVT_ENTER_WINDOW, preview_original);
2036 m_btn_view_multicolor->Bind(wxEVT_ENTER_WINDOW, preview_multicolor);
2037 m_btn_view_original->Bind(wxEVT_LEAVE_WINDOW, restore_filament_if_outside);
2038 m_btn_view_multicolor->Bind(wxEVT_LEAVE_WINDOW, restore_filament_if_outside);
2039 m_tab_panel->Bind(wxEVT_LEAVE_WINDOW, restore_filament_if_outside);
2040
2041 auto update_preview_overlay_buttons = [this]() {
2042 if (m_tab_panel) {
2043 m_tab_panel->Fit();
2044 m_tab_panel->SetPosition(wxPoint(FromDIP(8), FromDIP(8)));
2045 m_tab_panel->Raise();
2046 }
2047 };
2048
2049 preview_container->Bind(wxEVT_SIZE, [update_preview_overlay_buttons](wxSizeEvent& e) {
2050 e.Skip();
2051 update_preview_overlay_buttons();
2052 });
2053 update_preview_overlay_buttons();
2054
2056}
static wxColour texture_import_separator_colour()
Definition TextureImportDialog.cpp:101
Button * m_btn_view_original
Definition TextureImportDialog.hpp:382
static const int ID_VIEW_ORIGINAL
Definition TextureImportDialog.hpp:404
TexturePreviewCanvas * m_preview_canvas
Definition TextureImportDialog.hpp:380
Button * m_btn_view_multicolor
Definition TextureImportDialog.hpp:383
wxPanel * m_tab_panel
Definition TextureImportDialog.hpp:381
void highlight_view_button(int view_index)
Definition TextureImportDialog.cpp:4068
TextureImportState m_state
Definition TextureImportDialog.hpp:326
static const int ID_VIEW_MULTICOLOR
Definition TextureImportDialog.hpp:405
@ Original
Definition TextureImportDialog.hpp:96
@ FilamentMap
Definition TextureImportDialog.hpp:96
@ MultiColor
Definition TextureImportDialog.hpp:96
wxMouseEvent
Definition CameraPopup.cpp:47
@ Ready
Definition TextureImportDialog.hpp:45

References _L, StateColor::darkModeColorFor(), Slic3r::GUI::TexturePreviewCanvas::FilamentMap, highlight_view_button(), ID_VIEW_MULTICOLOR, ID_VIEW_ORIGINAL, m_btn_view_multicolor, m_btn_view_original, m_preview_canvas, m_state, m_tab_panel, Slic3r::GUI::TexturePreviewCanvas::MultiColor, Slic3r::GUI::TexturePreviewCanvas::Original, Parameter, Slic3r::GUI::Ready, Regular, texture_import_separator_colour(), and Slic3r::GUI::wxMouseEvent.

Referenced by build_ui().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_ui()

void Slic3r::GUI::TextureImportDialog::build_ui ( )
private
1906{
1907 const wxColour dialog_bg = StateColor::darkModeColorFor(*wxWHITE);
1908 SetBackgroundColour(dialog_bg);
1909 SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636")));
1910
1911 wxBoxSizer* root_sizer = new wxBoxSizer(wxVERTICAL);
1912
1913 auto line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
1914 line_top->SetBackgroundColour(texture_import_separator_colour());
1915 root_sizer->Add(line_top, 0, wxEXPAND);
1916
1917 wxBoxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL);
1918
1919 wxBoxSizer* left_sizer = new wxBoxSizer(wxVERTICAL);
1920 build_preview_panel(this, left_sizer);
1921 main_sizer->Add(left_sizer, 3, wxEXPAND | wxALL, FromDIP(8));
1922
1923 wxBoxSizer* right_sizer = new wxBoxSizer(wxVERTICAL);
1924 build_params_panel(this, right_sizer);
1925 build_mapping_panel(this, right_sizer);
1926 build_bottom_buttons(right_sizer);
1927 main_sizer->Add(right_sizer, 2, wxEXPAND | wxALL, FromDIP(8));
1928
1929 root_sizer->Add(main_sizer, 1, wxEXPAND);
1930
1931 SetSizer(root_sizer);
1932 Layout();
1933 Bind(wxEVT_MOUSEWHEEL, &TextureImportDialog::dismiss_filament_popup_on_wheel, this);
1934
1935#ifdef __WXMSW__
1936 wxPanel* size_grip_cover = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
1937 size_grip_cover->SetBackgroundColour(dialog_bg);
1938 size_grip_cover->SetBackgroundStyle(wxBG_STYLE_COLOUR);
1939
1940 auto update_size_grip_cover = [this, size_grip_cover]() {
1941 const int cover_size = FromDIP(20);
1942 wxSize client_size = GetClientSize();
1943 size_grip_cover->SetSize(client_size.x - cover_size, client_size.y - cover_size, cover_size, cover_size);
1944 size_grip_cover->Raise();
1945 };
1946 update_size_grip_cover();
1947
1948 Bind(wxEVT_SIZE, [update_size_grip_cover](wxSizeEvent& e) {
1949 e.Skip();
1950 update_size_grip_cover();
1951 });
1952#endif
1953}
void build_preview_panel(wxWindow *parent, wxSizer *sizer)
Definition TextureImportDialog.cpp:1955
void build_bottom_buttons(wxSizer *sizer)
Definition TextureImportDialog.cpp:2220
void build_params_panel(wxWindow *parent, wxSizer *sizer)
Definition TextureImportDialog.cpp:2058
void build_mapping_panel(wxWindow *parent, wxSizer *sizer)
Definition TextureImportDialog.cpp:2161

References build_bottom_buttons(), build_mapping_panel(), build_params_panel(), build_preview_panel(), StateColor::darkModeColorFor(), dismiss_filament_popup_on_wheel(), and texture_import_separator_colour().

Here is the call graph for this function:

◆ can_add_virtual_filament()

bool Slic3r::GUI::TextureImportDialog::can_add_virtual_filament ( ) const
private
2698{
2700}

References m_filament_colors_rgba, and max_filament_count().

Referenced by add_virtual_filament(), and add_virtual_mixed_filament().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cancel_computation()

void Slic3r::GUI::TextureImportDialog::cancel_computation ( )
private
2401{
2402 m_cancel_flag = true;
2403 if (m_worker && m_worker->joinable())
2404 m_worker->join();
2405 m_worker.reset();
2406
2407 if (m_progress_dlg) {
2408 m_progress_dlg->Destroy();
2409 m_progress_dlg = nullptr;
2410 }
2411
2416 }
2417}
bool m_initial_computation_pending
Definition TextureImportDialog.hpp:350
bool m_current_computation_initial
Definition TextureImportDialog.hpp:349
bool m_initial_computation_cancelled
Definition TextureImportDialog.hpp:351
ProgressDialog * m_progress_dlg
Definition TextureImportDialog.hpp:385

References m_cancel_flag, m_current_computation_initial, m_initial_computation_cancelled, m_initial_computation_pending, m_progress_dlg, and m_worker.

Referenced by on_skip_clicked(), and start_computation().

Here is the caller graph for this function:

◆ compact_used_virtual_filaments()

void Slic3r::GUI::TextureImportDialog::compact_used_virtual_filaments ( )
private
2802{
2803 if (m_current_matches.empty())
2804 return;
2805
2806 const std::vector<std::array<float, 4>> old_colors = m_filament_colors_rgba;
2807 const std::vector<std::string> old_color_strs = m_filament_color_strs;
2808 const std::vector<std::string> old_names = m_filament_names;
2809 const std::vector<TextureFilamentEntry> old_entries = m_filament_entries;
2810
2811 auto old_new_mixed_has_valid_components = [&old_entries, &old_colors](const TextureFilamentEntry& entry) {
2812 if (entry.kind != TextureFilamentKind::NewMixed)
2813 return true;
2814 if (entry.mixed_components.size() < 2 || entry.mixed_components.size() != entry.mixed_ratios.size())
2815 return false;
2816 for (unsigned int comp : entry.mixed_components) {
2817 int comp_idx = comp >= 1 ? (int)comp - 1 : -1;
2818 if (comp_idx < 0 || comp_idx >= (int)old_entries.size() || comp_idx >= (int)old_colors.size() ||
2819 !texture_entry_is_physical(old_entries[comp_idx].kind)) {
2820 return false;
2821 }
2822 }
2823 return true;
2824 };
2825
2826 std::set<int> used_virtual_indices;
2827 for (const auto& m : m_current_matches) {
2828 if (m.filament_index >= (int)m_existing_filament_count &&
2829 m.filament_index < (int)old_colors.size()) {
2830 if (m.filament_index < (int)old_entries.size() &&
2831 old_entries[m.filament_index].kind == TextureFilamentKind::NewMixed &&
2832 !old_new_mixed_has_valid_components(old_entries[m.filament_index])) {
2833 continue;
2834 }
2835 used_virtual_indices.insert(m.filament_index);
2836 }
2837 }
2838 bool added_dependency = true;
2839 while (added_dependency) {
2840 added_dependency = false;
2841 std::vector<int> current_used(used_virtual_indices.begin(), used_virtual_indices.end());
2842 for (int used_idx : current_used) {
2843 if (used_idx < 0 || used_idx >= (int)old_entries.size() ||
2844 old_entries[used_idx].kind != TextureFilamentKind::NewMixed ||
2845 !old_new_mixed_has_valid_components(old_entries[used_idx]))
2846 continue;
2847 for (unsigned int comp : old_entries[used_idx].mixed_components) {
2848 int comp_idx = comp >= 1 ? (int)comp - 1 : -1;
2849 if (comp_idx >= (int)m_existing_filament_count && comp_idx < (int)old_entries.size() &&
2850 used_virtual_indices.insert(comp_idx).second) {
2851 added_dependency = true;
2852 }
2853 }
2854 }
2855 }
2856
2857 std::vector<std::array<float, 4>> compact_colors;
2858 std::vector<std::string> compact_color_strs;
2859 std::vector<std::string> compact_names;
2860 std::vector<TextureFilamentEntry> compact_entries;
2861 compact_colors.reserve(m_existing_filament_count + used_virtual_indices.size());
2862 compact_color_strs.reserve(m_existing_filament_count + used_virtual_indices.size());
2863 compact_names.reserve(m_existing_filament_count + used_virtual_indices.size());
2864 compact_entries.reserve(m_existing_filament_count + used_virtual_indices.size());
2865
2866 const size_t existing_count = std::min(m_existing_filament_count, old_colors.size());
2867 for (size_t i = 0; i < existing_count; ++i) {
2868 compact_colors.push_back(old_colors[i]);
2869 compact_color_strs.push_back(i < old_color_strs.size() ? old_color_strs[i] : "");
2870 compact_names.push_back(i < old_names.size() ? old_names[i] : GUI::format(_u8L("Filament %d"), i + 1));
2871 TextureFilamentEntry entry = i < old_entries.size() ? old_entries[i] : TextureFilamentEntry{};
2872 entry.dialog_index = (int)i;
2873 entry.color_hex = texture_normalize_color_hex(compact_color_strs.back());
2874 entry.name = compact_names.back();
2875 compact_entries.push_back(entry);
2876 }
2877
2878 std::map<int, int> old_to_new;
2879 std::vector<std::array<float, 4>> compact_new_colors;
2880 std::vector<std::string> compact_new_preset_names;
2881 compact_new_colors.reserve(used_virtual_indices.size());
2882 compact_new_preset_names.reserve(used_virtual_indices.size());
2883
2884 for (int old_idx : used_virtual_indices) {
2885 old_to_new[old_idx] = (int)compact_colors.size();
2886 compact_colors.push_back(old_colors[old_idx]);
2887 compact_color_strs.push_back(old_idx < (int)old_color_strs.size() ? old_color_strs[old_idx] : "");
2888 compact_names.push_back(old_idx < (int)old_names.size() ? old_names[old_idx] : DEFAULT_VIRTUAL_FILAMENT_NAME);
2889 TextureFilamentEntry entry = old_idx < (int)old_entries.size() ? old_entries[old_idx] : TextureFilamentEntry{};
2890 entry.dialog_index = (int)compact_entries.size();
2891 entry.color_hex = texture_normalize_color_hex(compact_color_strs.back());
2892 entry.name = compact_names.back();
2893 if (entry.kind == TextureFilamentKind::NewPhysical) {
2894 compact_new_colors.push_back(old_colors[old_idx]);
2895 compact_new_preset_names.push_back(entry.preset_name.empty() ? m_default_virtual_filament_preset_name : entry.preset_name);
2896 }
2897 compact_entries.push_back(entry);
2898 }
2899
2900 m_filament_colors_rgba = std::move(compact_colors);
2901 m_filament_color_strs = std::move(compact_color_strs);
2902 m_filament_names = std::move(compact_names);
2903 m_filament_entries = std::move(compact_entries);
2904 m_new_filament_colors = std::move(compact_new_colors);
2905 m_new_filament_preset_names = std::move(compact_new_preset_names);
2906 m_new_mixed_filaments.clear();
2907 std::set<int> invalid_compacted_mixed_indices;
2908 for (auto& entry : m_filament_entries) {
2909 if (entry.kind != TextureFilamentKind::NewMixed)
2910 continue;
2911 TextureNewMixedFilament mixed;
2912 mixed.dialog_index = entry.dialog_index;
2913 mixed.color_hex = entry.color_hex;
2914 mixed.ratios = entry.mixed_ratios;
2915 mixed.component_dialog_indices.reserve(entry.mixed_components.size());
2916 bool valid_components = entry.mixed_components.size() >= 2 &&
2917 entry.mixed_components.size() == entry.mixed_ratios.size();
2918 for (unsigned int comp : entry.mixed_components) {
2919 int old_comp_idx = comp >= 1 ? (int)comp - 1 : -1;
2920 if (old_comp_idx < 0) {
2921 valid_components = false;
2922 break;
2923 }
2924 auto remap_it = old_to_new.find(old_comp_idx);
2925 int new_comp_idx = remap_it != old_to_new.end() ? remap_it->second : old_comp_idx;
2926 if (new_comp_idx < 0 || new_comp_idx >= (int)m_filament_entries.size() ||
2927 !texture_entry_is_physical(m_filament_entries[new_comp_idx].kind)) {
2928 valid_components = false;
2929 break;
2930 }
2931 mixed.component_dialog_indices.push_back(new_comp_idx);
2932 }
2933 if (!valid_components) {
2934 invalid_compacted_mixed_indices.insert(entry.dialog_index);
2935 continue;
2936 }
2937 entry.mixed_components.clear();
2938 for (int comp_idx : mixed.component_dialog_indices)
2939 entry.mixed_components.push_back((unsigned int)(comp_idx + 1));
2940 m_new_mixed_filaments.push_back(mixed);
2941 }
2942
2943 auto find_closest_physical_filament_index = [this](const std::array<std::size_t, 3>& color) {
2944 int best_idx = -1;
2945 double best_delta = std::numeric_limits<double>::max();
2946 const size_t filament_count = std::min(m_filament_colors_rgba.size(), max_filament_count());
2947 for (size_t i = 0; i < filament_count && i < m_filament_entries.size(); ++i) {
2949 continue;
2950 const double delta = Slic3r::compute_delta_e(color, m_filament_colors_rgba[i]);
2951 if (delta < best_delta) {
2952 best_delta = delta;
2953 best_idx = (int)i;
2954 }
2955 }
2956 return best_idx;
2957 };
2958
2959 for (auto& m : m_current_matches) {
2960 auto it = old_to_new.find(m.filament_index);
2961 if (it != old_to_new.end()) {
2962 m.filament_index = it->second;
2963 } else if (m.filament_index >= (int)m_existing_filament_count) {
2964 m.filament_index = find_closest_filament_index(m.cluster_color);
2965 }
2966 if (invalid_compacted_mixed_indices.count(m.filament_index) > 0) {
2967 int fallback_idx = find_closest_physical_filament_index(m.cluster_color);
2968 m.filament_index = fallback_idx >= 0 ? fallback_idx : find_closest_filament_index(m.cluster_color);
2969 }
2970
2971 if (m.filament_index >= 0 && m.filament_index < (int)m_filament_colors_rgba.size()) {
2972 m.filament_color = m_filament_colors_rgba[m.filament_index];
2973 m.delta_e = Slic3r::compute_delta_e(m.cluster_color, m.filament_color);
2974 if (m.filament_index >= (int)m_existing_filament_count)
2975 m.delta_e = 0.0;
2976 }
2977 }
2978}
int find_closest_filament_index(const std::array< std::size_t, 3 > &color) const
Definition TextureImportDialog.cpp:2702
std::string format(const char *fmt, TArgs &&... args)
Definition format.hpp:36
#define _u8L(s)
Definition I18N.hpp:11

References _u8L, Slic3r::GUI::TextureFilamentEntry::color_hex, Slic3r::GUI::TextureNewMixedFilament::color_hex, Slic3r::GUI::TextureNewMixedFilament::component_dialog_indices, Slic3r::compute_delta_e(), DEFAULT_VIRTUAL_FILAMENT_NAME, Slic3r::GUI::TextureFilamentEntry::dialog_index, Slic3r::GUI::TextureNewMixedFilament::dialog_index, find_closest_filament_index(), Slic3r::GUI::format(), Slic3r::GUI::TextureFilamentEntry::kind, m_current_matches, m_default_virtual_filament_preset_name, m_existing_filament_count, m_filament_color_strs, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_new_filament_colors, m_new_filament_preset_names, m_new_mixed_filaments, max_filament_count(), Slic3r::GUI::TextureFilamentEntry::name, Slic3r::GUI::NewMixed, Slic3r::GUI::NewPhysical, Slic3r::GUI::TextureFilamentEntry::preset_name, Slic3r::GUI::TextureNewMixedFilament::ratios, Slic3r::GUI::texture_entry_is_physical(), and Slic3r::GUI::texture_normalize_color_hex().

Referenced by apply_auto_standard_mix(), do_auto_match(), on_auto_merge_toggled(), on_computation_complete(), on_ok_clicked(), and reset_auto_mix().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ compute_display_numbers()

std::vector< int > Slic3r::GUI::TextureImportDialog::compute_display_numbers ( ) const
private
2981{
2982 // Assigns each entry a 1-based display number in the order the sidebar will
2983 // show after apply: ExistingPhysical, NewPhysical, ExistingMixed, NewMixed.
2984 // This keeps the dialog's visible IDs in sync with the post-apply sidebar,
2985 // instead of the raw dialog_index (which interleaves physicals and mixeds
2986 // by processing order and causes e.g. CMYW to show 4,5,6,8 instead of 3,4,5,6).
2987 // MUST mirror ordering in apply_textured_mesh_import_result (Plater.cpp:9896):
2988 // - ExistingPhysical keeps its project_config_index
2989 // - NewPhysical is inserted at existing_physical_count + new_order
2990 // - ExistingMixed shifts to project_config_index + new_physical_count
2991 // - NewMixed is appended after all existing mixeds
2992 std::vector<int> result(m_filament_entries.size(), 0);
2993 int next = 1;
2994
2995 auto assign_group = [&](TextureFilamentKind kind, bool by_project_config_index) {
2996 if (by_project_config_index) {
2997 std::vector<const TextureFilamentEntry*> group;
2998 for (const auto& e : m_filament_entries)
2999 if (e.kind == kind)
3000 group.push_back(&e);
3001 std::sort(group.begin(), group.end(),
3002 [](const TextureFilamentEntry* a, const TextureFilamentEntry* b) {
3003 return a->project_config_index < b->project_config_index;
3004 });
3005 for (const auto* e : group) {
3006 if (e->dialog_index >= 0 && e->dialog_index < (int)result.size())
3007 result[e->dialog_index] = next;
3008 ++next;
3009 }
3010 } else {
3011 for (const auto& e : m_filament_entries) {
3012 if (e.kind != kind)
3013 continue;
3014 if (e.dialog_index >= 0 && e.dialog_index < (int)result.size())
3015 result[e.dialog_index] = next;
3016 ++next;
3017 }
3018 }
3019 };
3020
3021 assign_group(TextureFilamentKind::ExistingPhysical, true);
3022 assign_group(TextureFilamentKind::NewPhysical, false);
3023 assign_group(TextureFilamentKind::ExistingMixed, true);
3024 assign_group(TextureFilamentKind::NewMixed, false);
3025 return result;
3026}
TextureFilamentKind
Definition TextureImportDialog.hpp:54
@ ExistingMixed
Definition TextureImportDialog.hpp:56

References Slic3r::GUI::ExistingMixed, Slic3r::GUI::ExistingPhysical, m_filament_entries, Slic3r::GUI::NewMixed, and Slic3r::GUI::NewPhysical.

Referenced by rebuild_mapping_rows(), and show_filament_popup().

Here is the caller graph for this function:

◆ dismiss_auto_mix_popup()

void Slic3r::GUI::TextureImportDialog::dismiss_auto_mix_popup ( )
private
3083{
3084 if (!m_auto_mix_popup)
3085 return;
3086
3087 AutoMixSelectPopup* popup = m_auto_mix_popup;
3088 m_auto_mix_popup = nullptr;
3089 if (popup->IsShown())
3090 popup->Dismiss();
3091 else
3092 popup->Destroy();
3093}
AutoMixSelectPopup * m_auto_mix_popup
Definition TextureImportDialog.hpp:372

References m_auto_mix_popup.

Referenced by ~TextureImportDialog(), dismiss_filament_popup_on_wheel(), reset_auto_mix(), show_auto_mix_popup(), and update_ui_for_state().

Here is the caller graph for this function:

◆ dismiss_filament_popup()

void Slic3r::GUI::TextureImportDialog::dismiss_filament_popup ( )
private
3029{
3030 if (!m_filament_popup) {
3032 return;
3033 }
3034
3035 FilamentSelectPopup* popup = m_filament_popup;
3036 m_filament_popup = nullptr;
3038 if (popup->IsShown())
3039 popup->Dismiss();
3040 else
3041 popup->Destroy();
3042}
int m_filament_popup_row
Definition TextureImportDialog.hpp:377
FilamentSelectPopup * m_filament_popup
Definition TextureImportDialog.hpp:376

References m_filament_popup, and m_filament_popup_row.

Referenced by ~TextureImportDialog(), dismiss_filament_popup_on_wheel(), and show_filament_popup().

Here is the caller graph for this function:

◆ dismiss_filament_popup_on_wheel()

void Slic3r::GUI::TextureImportDialog::dismiss_filament_popup_on_wheel ( wxMouseEvent & evt)
private
3359{
3362 evt.Skip();
3363}

References dismiss_auto_mix_popup(), dismiss_filament_popup(), and Slic3r::GUI::wxMouseEvent.

Referenced by build_mapping_panel(), build_ui(), and rebuild_mapping_rows().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_auto_match()

void Slic3r::GUI::TextureImportDialog::do_auto_match ( )
private
3475{
3476 if (m_painted.cluster_colors.empty()) return;
3477
3478 // do_auto_match() always rebuilds the baseline mapping without any mixed
3479 // filaments, so it is the common entry for every "revert one-click mix"
3480 // path. Clear the applied flag here; callers refresh the reset button.
3481 m_auto_mix_applied = false;
3482
3483 // Reset the "filaments were dropped" flag at the start of every run, so it
3484 // strictly reflects what happens during *this* match (no historical
3485 // accumulation). add_virtual_filament() will flip it back to true if and
3486 // only if it hits the global filament cap below.
3487 m_filaments_dropped = false;
3488
3489 // Drop any virtual filaments left over from previous match runs that the
3490 // current m_current_matches no longer references. Without this, the
3491 // residual virtual filaments inflate m_filament_colors_rgba.size() at the
3492 // entry of this match, which can make add_virtual_filament() fail (and
3493 // wrongly flip m_filaments_dropped to true) even when the *real* count
3494 // of needed virtual filaments for this run is well below the global cap.
3495 // This is purely a state cleanup; it does not change any mapping rule.
3497
3498 const auto previous_matches = m_current_matches;
3499
3500 std::map<std::array<std::size_t, 3>, int> previous_virtual_by_cluster;
3501 for (const auto& match : previous_matches) {
3502 if (match.filament_index >= (int)m_existing_filament_count &&
3503 match.filament_index < (int)m_filament_entries.size() &&
3504 texture_entry_is_physical(m_filament_entries[match.filament_index].kind)) {
3505 previous_virtual_by_cluster[match.cluster_color] = match.filament_index;
3506 }
3507 }
3508
3509 auto find_virtual_filament_by_color = [this](const std::array<std::size_t, 3>& color) -> int {
3510 std::string hex = rgb_to_hex(color).ToStdString();
3511 for (size_t i = m_existing_filament_count; i < m_filament_color_strs.size(); ++i) {
3512 if (m_filament_color_strs[i] == hex &&
3514 return (int)i;
3515 }
3516 return -1;
3517 };
3518
3519 auto get_or_add_virtual_filament = [this, &previous_virtual_by_cluster, &find_virtual_filament_by_color](
3520 const std::array<std::size_t, 3>& color) -> int {
3521 auto previous_it = previous_virtual_by_cluster.find(color);
3522 if (previous_it != previous_virtual_by_cluster.end() &&
3523 previous_it->second >= (int)m_existing_filament_count &&
3524 previous_it->second < (int)m_filament_colors_rgba.size()) {
3525 return previous_it->second;
3526 }
3527
3528 int existing_idx = find_virtual_filament_by_color(color);
3529 if (existing_idx >= 0)
3530 return existing_idx;
3531
3532 std::array<float, 4> rgba = {
3533 color[0] / 255.f,
3534 color[1] / 255.f,
3535 color[2] / 255.f,
3536 1.f
3537 };
3538 return add_virtual_filament(rgba, rgb_to_hex(color).ToStdString());
3539 };
3540
3541 if (m_auto_merge_cb && m_auto_merge_cb->GetValue()) {
3542 // Match clusters to closest existing filaments
3543 std::vector<std::string> names;
3544 for (size_t i = 0; i < m_existing_filament_count; ++i)
3545 names.push_back(m_filament_names.size() > i ? m_filament_names[i] : GUI::format(_u8L("Filament %d"), i + 1));
3546
3547 std::vector<std::array<float, 4>> existing_filament_colors(
3548 m_filament_colors_rgba.begin(),
3550
3552 m_painted.cluster_colors, existing_filament_colors, names);
3553
3554 // For clusters with poor match (CIEDE2000 ΔE > 5), create virtual filaments.
3555 constexpr double NEW_FILAMENT_THRESHOLD = 5.0;
3556 std::map<std::array<std::size_t, 3>, int> virtual_color_index;
3557
3558 for (auto& m : m_current_matches) {
3559 if (m.delta_e <= NEW_FILAMENT_THRESHOLD)
3560 continue;
3561
3562 auto it = virtual_color_index.find(m.cluster_color);
3563 if (it != virtual_color_index.end()) {
3564 m.filament_index = it->second;
3565 } else {
3566 int new_idx = get_or_add_virtual_filament(m.cluster_color);
3567 if (new_idx >= 0)
3568 virtual_color_index[m.cluster_color] = new_idx;
3569 m.filament_index = new_idx >= 0 ? new_idx : find_closest_filament_index(m.cluster_color);
3570 }
3571 if (m.filament_index >= 0 && m.filament_index < (int)m_filament_colors_rgba.size()) {
3572 m.filament_color = m_filament_colors_rgba[m.filament_index];
3573 m.delta_e = Slic3r::compute_delta_e(m.cluster_color, m.filament_color);
3574 if (m.filament_index >= (int)m_existing_filament_count)
3575 m.delta_e = 0.0;
3576 }
3577 }
3578 } else {
3579 // Keep all virtual filaments in this dialog; unused ones are pruned only on OK.
3580 m_current_matches.clear();
3581 std::map<std::array<std::size_t, 3>, int> virtual_map;
3582
3583 for (size_t i = 0; i < m_painted.cluster_colors.size(); ++i) {
3584 const auto& cc = m_painted.cluster_colors[i];
3585 Slic3r::FilamentMatch fm;
3586 fm.cluster_index = (int)i;
3587 fm.cluster_color = cc;
3588
3589 auto it = virtual_map.find(cc);
3590 if (it != virtual_map.end()) {
3591 fm.filament_index = it->second;
3592 } else {
3593 int idx = get_or_add_virtual_filament(cc);
3594 if (idx >= 0)
3595 virtual_map[cc] = idx;
3596 fm.filament_index = idx >= 0 ? idx : find_closest_filament_index(cc);
3597 }
3598 if (fm.filament_index >= 0 && fm.filament_index < (int)m_filament_colors_rgba.size()) {
3602 fm.delta_e = 0.0;
3603 }
3604 m_current_matches.push_back(fm);
3605 }
3606 }
3607
3609}
Slic3r::PaintedMesh m_painted
Definition TextureImportDialog.hpp:340
static wxString rgb_to_hex(const std::array< std::size_t, 3 > &c)
Definition TextureImportDialog.cpp:371
int filament_index
Definition TexturePainting.hpp:86
std::array< std::size_t, 3 > cluster_color
Definition TexturePainting.hpp:88
std::array< float, 4 > filament_color
Definition TexturePainting.hpp:89
double delta_e
Definition TexturePainting.hpp:87
int cluster_index
Definition TexturePainting.hpp:85
std::vector< FilamentMatch > match_clusters_to_filaments(const std::vector< std::array< std::size_t, 3 > > &cluster_colors, const std::vector< std::array< float, 4 > > &filament_colors, const std::vector< std::string > &)
Definition TexturePainting.cpp:444

References _u8L, add_virtual_filament(), Slic3r::FilamentMatch::cluster_color, Slic3r::FilamentMatch::cluster_index, compact_used_virtual_filaments(), Slic3r::compute_delta_e(), Slic3r::FilamentMatch::delta_e, Slic3r::FilamentMatch::filament_color, Slic3r::FilamentMatch::filament_index, find_closest_filament_index(), Slic3r::GUI::format(), m_auto_merge_cb, m_auto_mix_applied, m_current_matches, m_existing_filament_count, m_filament_color_strs, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_filaments_dropped, m_painted, Slic3r::match_clusters_to_filaments(), Slic3r::GUI::rgb_to_hex(), Slic3r::GUI::texture_entry_is_physical(), and update_filament_color_map().

Referenced by on_auto_merge_toggled(), on_computation_complete(), and reset_auto_mix().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ em_unit()

int Slic3r::GUI::DPIAware< wxDialog >::em_unit ( ) const
inlineinherited
203{ return m_em_unit; }
Definition GUI_Utils.hpp:107

Referenced by Slic3r::GUI::AuxiliaryDialog::AuxiliaryDialog(), Slic3r::GUI::CopyrightsDialog::CopyrightsDialog(), Slic3r::GUI::DesignTextDialog::DesignTextDialog(), Slic3r::GUI::EditGCodeDialog::EditGCodeDialog(), Slic3r::GUI::FileArchiveDialog::FileArchiveDialog(), Slic3r::GUI::MsgNoUpdates::MsgNoUpdates(), Slic3r::GUI::MsgUpdateForced::MsgUpdateForced(), Slic3r::GUI::OAuthDialog::OAuthDialog(), Slic3r::GUI::ParamsDialog::ParamsDialog(), Slic3r::GUI::PhysicalPrinterDialog::PhysicalPrinterDialog(), Slic3r::GUI::SettingsDialog::SettingsDialog(), anonymous_namespace{3DPrinterOS.cpp}::TokenAuthDialog::TokenAuthDialog(), anonymous_namespace{3DPrinterOS.cpp}::UploadOptionsDialog::UploadOptionsDialog(), Slic3r::GUI::PublishSettingsDialog::add_row_ui(), Slic3r::GUI::DiffPresetDialog::complete_dialog_creation(), Slic3r::GUI::DiffPresetDialog::create_edit_sizer(), Slic3r::GUI::DiffPresetDialog::create_presets_sizer(), Slic3r::GUI::DiffPresetDialog::create_tree(), Slic3r::GUI::ElegooPrintHostSendDialog::init(), Slic3r::GUI::FlashforgePrintHostSendDialog::init(), Slic3r::GUI::PrintHostSendDialog::init(), Slic3r::GUI::AboutDialog::on_dpi_changed(), Slic3r::GUI::AuxiliaryDialog::on_dpi_changed(), Slic3r::GUI::BedShapeDialog::on_dpi_changed(), Slic3r::GUI::ConfigWizard::on_dpi_changed(), Slic3r::GUI::CopyrightsDialog::on_dpi_changed(), Slic3r::GUI::DiffPresetDialog::on_dpi_changed(), Slic3r::GUI::EditGCodeDialog::on_dpi_changed(), Slic3r::GUI::FileArchiveDialog::on_dpi_changed(), Slic3r::GUI::OAuthDialog::on_dpi_changed(), Slic3r::GUI::ObjectTableDialog::on_dpi_changed(), Slic3r::GUI::ParamsDialog::on_dpi_changed(), Slic3r::GUI::PhysicalPrinterDialog::on_dpi_changed(), Slic3r::GUI::PrintHostQueueDialog::on_dpi_changed(), Slic3r::GUI::PurgeModeDialog::on_dpi_changed(), Slic3r::GUI::SavePresetDialog::on_dpi_changed(), Slic3r::GUI::SendSystemInfoDialog::on_dpi_changed(), Slic3r::GUI::SettingsDialog::on_dpi_changed(), and Slic3r::GUI::UnsavedChangesDialog::on_dpi_changed().

Here is the caller graph for this function:

◆ enable_force_rescale()

void Slic3r::GUI::DPIAware< wxDialog >::enable_force_rescale ( )
inlineinherited
206{ m_force_rescale = true; }

◆ EndModal()

void Slic3r::GUI::DPIDialog::EndModal ( int retCode)
inlineoverrideinherited
306 {
307 if (!dialogStack.empty() && dialogStack.front() != this) {
308 // This is a bug in wxWidgets
309 // when the dialog is not top modal dialog, EndModal() just hide dialog without quit
310 // the modal event loop. And the modal event loop blocks us from bottom widgets.
311 // Solution: let user click it manually or close outside. FIXME
312 BOOST_LOG_TRIVIAL(warning) << "DPIAware::EndModal Error: dialogStack is not empty, but top dialog is not this one. retCode=" << retCode;
313 return;
314 }
315
316 return wxDialog::EndModal(retCode);
317 }
std::deque< wxDialog * > dialogStack
Definition GUI_Utils.cpp:549

References Slic3r::GUI::dialogStack.

Referenced by Slic3r::GUI::CloneDialog::CloneDialog(), Slic3r::GUI::ConfigWizard::ConfigWizard(), Slic3r::GUI::CreatePresetSuccessfulDialog::CreatePresetSuccessfulDialog(), Slic3r::GUI::DeleteConfirmDialog::DeleteConfirmDialog(), Slic3r::GUI::DesignVariableDialog::DesignVariableDialog(), Slic3r::GUI::anonymous_namespace{PrintHostDialogs.cpp}::FlashforgeSlotDialog::FlashforgeSlotDialog(), Slic3r::GUI::GuideFrame::GuideFrame(), Slic3r::GUI::InputIpAddressDialog::InputIpAddressDialog(), Slic3r::GUI::ManualNozzleCountDialog::ManualNozzleCountDialog(), Slic3r::GUI::MsgUpdateConfig::MsgUpdateConfig(), Slic3r::GUI::MsgUpdateForced::MsgUpdateForced(), Slic3r::GUI::MultiChoiceDialog::MultiChoiceDialog(), Slic3r::GUI::NetworkErrorDialog::NetworkErrorDialog(), Slic3r::GUI::NetworkPluginRestartDialog::NetworkPluginRestartDialog(), Slic3r::GUI::PartSkipConfirmDialog::PartSkipConfirmDialog(), Slic3r::GUI::PhysicalPrinterDialog::PhysicalPrinterDialog(), Slic3r::GUI::PlateNameEditDialog::PlateNameEditDialog(), Slic3r::GUI::PlateSettingsDialog::PlateSettingsDialog(), Slic3r::GUI::PublishSettingsDialog::PublishSettingsDialog(), Slic3r::GUI::SelectMachineDialog::SelectMachineDialog(), Slic3r::GUI::SendFailedConfirm::SendFailedConfirm(), Slic3r::GUI::SendSystemInfoDialog::SendSystemInfoDialog(), Slic3r::GUI::ShortcutCaptureDialog::ShortcutCaptureDialog(), Slic3r::GUI::SingleChoiceDialog::SingleChoiceDialog(), StepMeshDialog::StepMeshDialog(), Slic3r::GUI::SyncAmsInfoDialog::SyncAmsInfoDialog(), anonymous_namespace{3DPrinterOS.cpp}::TokenAuthDialog::TokenAuthDialog(), Slic3r::GUI::UpdatePluginDialog::UpdatePluginDialog(), Slic3r::GUI::UpdateVersionDialog::UpdateVersionDialog(), Slic3r::GUI::wgtDeviceNozzleRackUpgradeDlg::wgtDeviceNozzleRackUpgradeDlg(), Slic3r::GUI::SavePresetDialog::accept(), Slic3r::GUI::MsgDialog::add_button(), Slic3r::GUI::TipsDialog::add_button(), Slic3r::GUI::FilamentPickerDialog::BindEvents(), Slic3r::GUI::PluginPickerDialog::build_capability_ui(), Slic3r::GUI::BedShapeDialog::build_dialog(), Slic3r::GUI::PluginPickerDialog::build_ui(), Slic3r::GUI::UnsavedChangesDialog::close(), Slic3r::GUI::FileArchiveDialog::create_btn_sizer(), Slic3r::GUI::ColorDecomposeDialog::create_button_panel(), Slic3r::GUI::MixedFilamentDialog::create_button_panel(), Slic3r::GUI::CreateFilamentPresetDialog::create_dialog_buttons(), Slic3r::GUI::CreatePresetForPrinterDialog::create_dialog_buttons(), Slic3r::GUI::EditFilamentPresetDialog::create_dialog_buttons(), Slic3r::GUI::ExportConfigsDialog::create_dialog_buttons(), Slic3r::GUI::PreferencesDialog::create_item_language_combobox(), Slic3r::GUI::PreferencesDialog::create_item_region_combobox(), Slic3r::GUI::PreferencesDialog::create_items(), Slic3r::GUI::CreatePrinterPresetDialog::create_page1_dialog_buttons(), Slic3r::GUI::CreatePrinterPresetDialog::create_page2_dialog_buttons(), Slic3r::GUI::ExportConfigsDialog::data_init(), Slic3r::GUI::WebDialog::destroy_silently(), Slic3r::GUI::EditFilamentPresetDialog::edit_preset(), Slic3r::GUI::ConnectPrinterDialog::end_modal(), Slic3r::GUI::PrintHostSendDialog::EndModal(), Slic3r::GUI::ColorPickerDialog::finish(), Slic3r::GUI::WebDialog::finish(), Slic3r::GUI::Newer3mfVersionDialog::get_btn_sizer(), Slic3r::GUI::ScoreDialog::get_button_sizer(), Slic3r::GUI::WebViewHostDialog::handle_common_script_command(), Slic3r::GUI::ExportPresetBundleDialog::InitExportData(), Slic3r::GUI::SelectMachineDialog::navigate_to_timelapse_page(), Slic3r::GUI::BindMachineDialog::on_bind_success(), Slic3r::GUI::ConnectPrinterDialog::on_button_confirm(), Slic3r::GUI::RecenterDialog::on_button_confirm(), Slic3r::GUI::BindMachineDialog::on_cancel(), Slic3r::GUI::EditCalibrationHistoryDialog::on_cancel(), Slic3r::GUI::InputIpAddressDialog::on_cancel(), Slic3r::GUI::NewCalibrationHistoryDialog::on_cancel(), Slic3r::GUI::OAuthDialog::on_cancel(), Slic3r::GUI::PingCodeBindDialog::on_cancel(), Slic3r::GUI::SelectMachineDialog::on_cancel(), Slic3r::GUI::SendToPrinterDialog::on_cancel(), Slic3r::GUI::SyncAmsInfoDialog::on_cancel(), Slic3r::GUI::UnBindMachineDialog::on_cancel(), Slic3r::GUI::WebDialog::on_close_window(), Slic3r::GUI::NetworkPluginDownloadDialog::on_dont_ask(), Slic3r::GUI::NetworkPluginDownloadDialog::on_download(), Slic3r::GUI::EditDevNameDialog::on_edit_name(), Slic3r::GUI::ConfirmBeforeSendDialog::on_hide(), Slic3r::GUI::PrivacyUpdateDialog::on_hide(), Slic3r::GUI::ShortcutCaptureDialog::on_key(), Slic3r::GUI::TextureImportDialog::on_ok_clicked(), Slic3r::GUI::FileArchiveDialog::on_open_button(), Slic3r::GUI::NetworkPluginDownloadDialog::on_remind_later(), Slic3r::GUI::ProjectDropDialog::on_select_cancel(), Slic3r::GUI::SavePresetDialog::on_select_cancel(), Slic3r::GUI::ProjectDropDialog::on_select_ok(), Slic3r::GUI::SendMultiMachinePage::on_send(), Slic3r::GUI::NetworkPluginDownloadDialog::on_skip(), Slic3r::GUI::TextureImportDialog::on_skip_clicked(), Slic3r::GUI::NetworkPluginDownloadDialog::on_skip_version(), Slic3r::GUI::Cornering_Test_Dlg::on_start(), Slic3r::GUI::FlowRateCalibrationDialog::on_start(), Slic3r::GUI::Input_Shaping_Damp_Test_Dlg::on_start(), Slic3r::GUI::Input_Shaping_Freq_Test_Dlg::on_start(), Slic3r::GUI::MaxVolumetricSpeed_Test_Dlg::on_start(), Slic3r::GUI::PA_Calibration_Dlg::on_start(), Slic3r::GUI::Retraction_Test_Dlg::on_start(), Slic3r::GUI::Temp_Calibration_Dlg::on_start(), Slic3r::GUI::VFA_Test_Dlg::on_start(), Slic3r::GUI::CalibrationDialog::on_start_calibration(), Slic3r::GUI::UnBindMachineDialog::on_unbind_printer(), Slic3r::GUI::PartSkipDialog::OnApplyDialog(), anonymous_namespace{3DPrinterOS.cpp}::TokenAuthDialog::OnCancel(), Slic3r::GUI::AboutDialog::onCloseDialog(), Slic3r::GUI::CopyrightsDialog::onCloseDialog(), Slic3r::GUI::MultiNozzleSyncDialog::OnRackStatusReadingFinished(), Slic3r::GUI::GuideFrame::OnScriptMessage(), Slic3r::GUI::InputIpAddressDialog::OnTimer(), Slic3r::GUI::KBShortcutsDialog::open_mouse_preferences(), Slic3r::GUI::TroubleshootDialog::PackAll(), Slic3r::GUI::TroubleshootDialog::RebuildSystemProfiles(), Slic3r::GUI::SpeedDialWebDialog::run_action(), Slic3r::GUI::OAuthDialog::Show(), Slic3r::GUI::MultiNozzleSyncDialog::UpdateButton(), and Slic3r::GUI::CreatePrinterPresetDialog::validate_input_valid().

◆ fallback_to_geometry_only()

bool Slic3r::GUI::TextureImportDialog::fallback_to_geometry_only ( ) const
inline
bool m_fallback_to_geometry_only
Definition TextureImportDialog.hpp:328

References m_fallback_to_geometry_only.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ find_closest_filament_index()

int Slic3r::GUI::TextureImportDialog::find_closest_filament_index ( const std::array< std::size_t, 3 > & color) const
private
2703{
2704 int best_idx = -1;
2705 double best_delta = std::numeric_limits<double>::max();
2706 const size_t filament_count = std::min(m_filament_colors_rgba.size(), max_filament_count());
2707 for (size_t i = 0; i < filament_count; ++i) {
2708 const double delta = Slic3r::compute_delta_e(color, m_filament_colors_rgba[i]);
2709 if (delta < best_delta) {
2710 best_delta = delta;
2711 best_idx = (int)i;
2712 }
2713 }
2714 return best_idx;
2715}

References Slic3r::compute_delta_e(), m_filament_colors_rgba, and max_filament_count().

Referenced by compact_used_virtual_filaments(), and do_auto_match().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ force_rescale()

bool Slic3r::GUI::DPIAware< wxDialog >::force_rescale ( ) const
inlineinherited
201{ return m_force_rescale; }

◆ get_existing_filament_count()

size_t Slic3r::GUI::TextureImportDialog::get_existing_filament_count ( ) const
inline

References m_existing_filament_count.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ get_filament_entries()

const std::vector< TextureFilamentEntry > & Slic3r::GUI::TextureImportDialog::get_filament_entries ( ) const
inline
219{ return m_filament_entries; }

References m_filament_entries.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ get_matches()

std::vector< Slic3r::FilamentMatch > Slic3r::GUI::TextureImportDialog::get_matches ( ) const
4182{
4183 if (!m_current_matches.empty())
4184 return m_current_matches;
4185 return build_matches_from_rows();
4186}
std::vector< Slic3r::FilamentMatch > build_matches_from_rows() const
Definition TextureImportDialog.cpp:3916

References build_matches_from_rows(), and m_current_matches.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_new_filament_colors()

const std::vector< std::array< float, 4 > > & Slic3r::GUI::TextureImportDialog::get_new_filament_colors ( ) const
inline
216{ return m_new_filament_colors; }

References m_new_filament_colors.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ get_new_filament_preset_names()

const std::vector< std::string > & Slic3r::GUI::TextureImportDialog::get_new_filament_preset_names ( ) const
inline

References m_new_filament_preset_names.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ get_new_mixed_filaments()

const std::vector< TextureNewMixedFilament > & Slic3r::GUI::TextureImportDialog::get_new_mixed_filaments ( ) const
inline
218{ return m_new_mixed_filaments; }

References m_new_mixed_filaments.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ get_painted_mesh()

Slic3r::PaintedMesh Slic3r::GUI::TextureImportDialog::get_painted_mesh ( ) const
4177{
4178 return m_painted;
4179}

References m_painted.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ has_valid_result()

bool Slic3r::GUI::TextureImportDialog::has_valid_result ( ) const
private
4091{
4092 if (m_painted.face_colors.empty() || m_current_matches.empty() || m_mapping_rows.empty())
4093 return false;
4094
4095 if (m_mapping_rows.size() != m_current_matches.size())
4096 return false;
4097
4098 const int filament_count = (int)std::min(m_filament_colors_rgba.size(), max_filament_count());
4099 for (const auto& row : m_mapping_rows) {
4100 if (row.target_filament_idx < 0 || row.target_filament_idx >= filament_count)
4101 return false;
4102 }
4103 return true;
4104}

References m_current_matches, m_filament_colors_rgba, m_mapping_rows, m_painted, and max_filament_count().

Referenced by on_computation_error(), on_mesh_repair_decision_required(), on_ok_clicked(), update_confirm_button_state(), and update_ui_for_state().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ highlight_view_button()

void Slic3r::GUI::TextureImportDialog::highlight_view_button ( int view_index)
private
4069{
4070 Button* btns[] = { m_btn_view_original, m_btn_view_multicolor };
4071
4072 for (int i = 0; i < 2; ++i) {
4073 if (!btns[i]) continue;
4075 btns[i]->Refresh();
4076 }
4077}
void SetStyle(const ButtonStyle style, const ButtonType type)
Definition Button.cpp:200

References Confirm, m_btn_view_multicolor, m_btn_view_original, Parameter, Regular, and Button::SetStyle().

Referenced by build_preview_panel(), and on_computation_complete().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_new_scale_factor()

bool Slic3r::GUI::DPIAware< wxDialog >::is_new_scale_factor ( ) const
inlineprivateinherited
262{ return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }

◆ is_params_dirty()

bool Slic3r::GUI::TextureImportDialog::is_params_dirty ( ) const
private
4107{
4108 if (m_applied_color_count < 0)
4109 return false;
4112}
int m_applied_color_count
Definition TextureImportDialog.hpp:394
int m_applied_smooth
Definition TextureImportDialog.hpp:395

References m_applied_color_count, m_applied_smooth, m_param_color_count, and m_param_smooth.

Referenced by on_ok_clicked(), update_confirm_button_state(), and update_ui_for_state().

Here is the caller graph for this function:

◆ max_filament_count()

size_t Slic3r::GUI::TextureImportDialog::max_filament_count ( ) const
private
2693{
2694 return static_cast<size_t>(EnforcerBlockerType::ExtruderMax);
2695}
@ ExtruderMax
Definition TriangleSelector.hpp:66

References Slic3r::ExtruderMax.

Referenced by add_decomposed_mixed_filament(), build_bottom_buttons(), build_params_panel(), can_add_virtual_filament(), compact_used_virtual_filaments(), find_closest_filament_index(), has_valid_result(), on_color_spin_text_changed(), on_computation_complete(), and set_color_count_value().

Here is the caller graph for this function:

◆ normal_font()

◆ on_apply_clicked()

void Slic3r::GUI::TextureImportDialog::on_apply_clicked ( wxCommandEvent & evt)
private
4047{
4049}
void start_computation(bool auto_color=false, bool initial=false)
Definition TextureImportDialog.cpp:2300

References start_computation().

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_auto_merge_toggled()

void Slic3r::GUI::TextureImportDialog::on_auto_merge_toggled ( wxCommandEvent & evt)
private
4052{
4053 bool auto_merge_enabled = !m_auto_merge_cb || m_auto_merge_cb->GetValue();
4054 m_auto_merge_enabled = auto_merge_enabled;
4055
4057 const auto previous_matches = m_current_matches;
4058 do_auto_match();
4059 restore_current_match_order(previous_matches);
4065 }
4066}
bool m_auto_merge_enabled
Definition TextureImportDialog.hpp:336
void do_auto_match()
Definition TextureImportDialog.cpp:3474
void restore_current_match_order(const std::vector< Slic3r::FilamentMatch > &previous_matches)
Definition TextureImportDialog.cpp:2665

References compact_used_virtual_filaments(), do_auto_match(), m_auto_merge_cb, m_auto_merge_enabled, m_current_matches, m_state, Slic3r::GUI::Ready, rebuild_mapping_rows(), restore_current_match_order(), update_auto_mix_reset_visibility(), update_drop_warning_visibility(), and update_filament_color_map().

Referenced by build_mapping_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_color_preset_clicked()

void Slic3r::GUI::TextureImportDialog::on_color_preset_clicked ( wxCommandEvent & evt)
private
3998{
3999 int id = evt.GetId();
4000 int color_count = m_param_color_count;
4001 if (id == ID_COLOR_4) { color_count = 4; }
4002 if (id == ID_COLOR_8) { color_count = 8; }
4003 if (id == ID_COLOR_16) { color_count = 16; }
4004
4005 if (id == ID_COLOR_AUTO) {
4006 start_computation(true);
4007 return;
4008 }
4009
4010 set_color_count_value(color_count, true);
4011}
void set_color_count_value(int value, bool update_spin)
Definition TextureImportDialog.cpp:3946

References ID_COLOR_16, ID_COLOR_4, ID_COLOR_8, ID_COLOR_AUTO, m_param_color_count, set_color_count_value(), and start_computation().

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_color_slider_changed()

void Slic3r::GUI::TextureImportDialog::on_color_slider_changed ( wxCommandEvent & evt)
private
4014{
4015 set_color_count_value(m_color_slider->GetValue(), true);
4016}

References m_color_slider, and set_color_count_value().

Referenced by build_params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_color_spin_changed()

void Slic3r::GUI::TextureImportDialog::on_color_spin_changed ( wxCommandEvent & evt)
private
4019{
4020 set_color_count_value(m_color_spin->GetValue(), true);
4021}

References m_color_spin, and set_color_count_value().

Referenced by build_params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_color_spin_text_changed()

void Slic3r::GUI::TextureImportDialog::on_color_spin_text_changed ( wxCommandEvent & evt)
private
4024{
4026 1, (int)max_filament_count(), evt.GetString(),
4027 [this]() { update_color_count_preset_buttons(); });
4028}
void preview_spin_text_value(SpinInput *spin, AccentSlider *slider, int &param, int min_value, int max_value, const wxString &text, std::function< void()> on_value_changed={})
Definition TextureImportDialog.cpp:3965

References m_color_slider, m_color_spin, m_param_color_count, max_filament_count(), and preview_spin_text_value().

Referenced by build_params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_computation_complete()

void Slic3r::GUI::TextureImportDialog::on_computation_complete ( wxCommandEvent & evt)
private
2431{
2432 bool initial = m_current_computation_initial;
2433
2434 if (m_progress_dlg) {
2435 m_progress_dlg->Destroy();
2436 m_progress_dlg = nullptr;
2437 }
2438
2439 {
2440 std::lock_guard<std::mutex> lock(m_result_mutex);
2441 m_painted = std::move(m_pending_result);
2442 }
2443
2444 int actual_colors = (int)m_painted.cluster_colors.size();
2445 if (actual_colors >= 2 && actual_colors <= (int)max_filament_count()) {
2446 set_color_count_value(actual_colors, true);
2447 }
2448
2449 m_preview_canvas->set_painted_mesh_data(m_painted.vertices, m_painted.indices);
2450 m_preview_canvas->set_face_colors(m_painted.face_colors);
2451
2452 // A fresh texture computation replaces m_painted, so virtual filaments from
2453 // the previous computation must not consume capacity when deciding whether
2454 // this run drops extra colors. Rebuild virtual filaments from this result.
2455 m_current_matches.clear();
2465 TextureFilamentEntry entry;
2467 entry.dialog_index = (int)m_filament_entries.size();
2468 entry.project_config_index = m_filament_entries.size();
2469 m_filament_entries.push_back(entry);
2470 }
2471 for (size_t i = 0; i < m_filament_entries.size(); ++i) {
2472 m_filament_entries[i].dialog_index = (int)i;
2473 m_filament_entries[i].color_hex = i < m_filament_color_strs.size() ?
2475 m_filament_entries[i].name = i < m_filament_names.size() ?
2476 m_filament_names[i] : GUI::format(_u8L("Filament %d"), i + 1);
2477 }
2478 m_new_filament_colors.clear();
2480 m_new_mixed_filaments.clear();
2481
2482 do_auto_match();
2487
2490
2494
2495 m_btn_view_multicolor->Show();
2496 if (m_tab_panel) {
2497 m_tab_panel->GetSizer()->Layout();
2498 m_tab_panel->Fit();
2499 m_tab_panel->SetPosition(wxPoint(FromDIP(8), FromDIP(8)));
2500 }
2501 GetSizer()->Layout();
2502
2505
2506 if (initial) {
2509 }
2510}
Slic3r::PaintedMesh m_pending_result
Definition TextureImportDialog.hpp:346
std::mutex m_result_mutex
Definition TextureImportDialog.hpp:345
void set_state(TextureImportState new_state)
Definition TextureImportDialog.cpp:2253
void sort_current_matches_by_filament_index()
Definition TextureImportDialog.cpp:2634
@ lock
Definition GLGizmoEmboss.cpp:209

References _u8L, compact_used_virtual_filaments(), Slic3r::GUI::TextureFilamentEntry::dialog_index, do_auto_match(), Slic3r::GUI::ExistingPhysical, Slic3r::GUI::TexturePreviewCanvas::FilamentMap, Slic3r::GUI::format(), highlight_view_button(), Slic3r::GUI::TextureFilamentEntry::kind, m_applied_color_count, m_applied_smooth, m_btn_view_multicolor, m_current_computation_initial, m_current_matches, m_existing_filament_count, m_filament_color_strs, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_initial_computation_pending, m_new_filament_colors, m_new_filament_preset_names, m_new_mixed_filaments, m_painted, m_param_color_count, m_param_smooth, m_pending_result, m_preview_canvas, m_progress_dlg, m_result_mutex, m_tab_panel, max_filament_count(), Slic3r::GUI::TextureFilamentEntry::project_config_index, Slic3r::GUI::Ready, rebuild_mapping_rows(), set_color_count_value(), set_state(), sort_current_matches_by_filament_index(), Slic3r::GUI::texture_normalize_color_hex(), update_auto_mix_reset_visibility(), update_drop_warning_visibility(), and update_filament_color_map().

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_computation_error()

void Slic3r::GUI::TextureImportDialog::on_computation_error ( wxCommandEvent & evt)
private
2513{
2514 bool initial = m_current_computation_initial;
2515
2516 if (m_progress_dlg) {
2517 m_progress_dlg->Destroy();
2518 m_progress_dlg = nullptr;
2519 }
2520
2521 if (m_cancel_flag.load()) {
2522 if (initial) {
2526 return;
2527 }
2528 if (has_valid_result()) {
2529 if (m_applied_color_count >= 0) {
2534 }
2535 if (m_applied_smooth >= 0) {
2538 m_smooth_spin->SetValue(m_param_smooth);
2539 }
2541 return;
2542 }
2544 return;
2545 }
2546
2547 if (initial) {
2552 return;
2553 }
2554
2556 Slic3r::GUI::MessageDialog dlg(initial ? GetParent() : this,
2557 _L("Computation failed. Please adjust parameters and retry."),
2558 _L("Error"), wxOK | wxICON_ERROR);
2559 dlg.ShowModal();
2560}
bool m_initial_computation_failed
Definition TextureImportDialog.hpp:352
bool has_valid_result() const
Definition TextureImportDialog.cpp:4090
@ Error
Definition TextureImportDialog.hpp:46
@ Idle
Definition TextureImportDialog.hpp:43

References _L, Slic3r::GUI::Error, has_valid_result(), Slic3r::GUI::Idle, m_applied_color_count, m_applied_smooth, m_cancel_flag, m_color_slider, m_color_spin, m_current_computation_initial, m_fallback_to_geometry_only, m_initial_computation_cancelled, m_initial_computation_failed, m_initial_computation_pending, m_param_color_count, m_param_smooth, m_progress_dlg, m_smooth_slider, m_smooth_spin, Slic3r::GUI::Ready, set_state(), Slic3r::GUI::DPIAware< P >::ShowModal(), and update_color_count_preset_buttons().

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_computation_progress()

void Slic3r::GUI::TextureImportDialog::on_computation_progress ( wxCommandEvent & evt)
private
2420{
2421 if (m_progress_dlg) {
2422 if (!m_progress_dlg->Update(evt.GetInt()))
2423 m_cancel_flag = true;
2425 if (!m_initial_progress_callback(evt.GetInt()))
2426 m_cancel_flag = true;
2427 }
2428}
std::function< bool(int)> m_initial_progress_callback
Definition TextureImportDialog.hpp:348

References m_cancel_flag, m_current_computation_initial, m_initial_progress_callback, and m_progress_dlg.

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the caller graph for this function:

◆ on_dpi_changed()

void Slic3r::GUI::TextureImportDialog::on_dpi_changed ( const wxRect & suggested_rect)
overridevirtual

Implements Slic3r::GUI::DPIAware< wxDialog >.

4189{
4190 // All control sizes below are baked into persistent properties (min size,
4191 // corner radius, fixed wxSize) using FromDIP() at build time. The base
4192 // DPIAware::rescale() only rescales fonts; it does not recompute these
4193 // stored pixel values. Re-apply them here so the layout stays consistent
4194 // when the dialog is dragged to a screen with a different DPI.
4195 SetMinSize(wxSize(FromDIP(800), FromDIP(500)));
4196
4197 const int view_button_height = FromDIP(27);
4198 for (Button* btn : {m_btn_view_original, m_btn_view_multicolor}) {
4199 if (btn) btn->Rescale(); // ORCA Rescale applies all style automatically when combined with SetStyle
4200 }
4201
4202 update_color_count_preset_buttons(); // ORCA Rescale applies all style automatically when combined with SetStyle
4203
4204 if (m_color_spin)
4205 m_color_spin->SetMinSize(wxSize(FromDIP(60), FromDIP(28)));
4206 if (m_smooth_spin)
4207 m_smooth_spin->SetMinSize(wxSize(FromDIP(60), FromDIP(28)));
4208
4209 if (m_mapping_scroll) {
4210 m_mapping_scroll->SetMinSize(wxSize(-1, FromDIP(300)));
4211 m_mapping_scroll->SetScrollRate(0, FromDIP(20));
4212 }
4213
4214 // ORCA Rescale applies all style automatically when combined with SetStyle
4215 if (m_btn_skip) m_btn_skip->Rescale();
4216 if (m_btn_ok) m_btn_ok->Rescale();
4217 if (m_btn_color_auto) m_btn_color_auto->Rescale();
4218 if (m_btn_apply) m_btn_apply->Rescale();
4219 if (m_btn_auto_mix) m_btn_auto_mix->Rescale();
4220 if (m_btn_mix_reset) m_btn_mix_reset->Rescale();
4221
4222 // Mapping rows store their panel sizes (source/target/arrow/row height)
4223 // as fixed FromDIP min/max sizes, so rebuild them to pick up the new DPI.
4225
4226 if (wxSizer* sizer = GetSizer())
4227 sizer->Layout();
4228 Layout();
4229 Refresh();
4230 wxGetApp().UpdateDlgDarkUI(this);
4231}

References m_btn_apply, m_btn_auto_mix, m_btn_color_auto, m_btn_mix_reset, m_btn_ok, m_btn_skip, m_btn_view_multicolor, m_btn_view_original, m_color_spin, m_mapping_scroll, m_smooth_spin, rebuild_mapping_rows(), and update_color_count_preset_buttons().

Here is the call graph for this function:

◆ on_mesh_repair_decision_required()

void Slic3r::GUI::TextureImportDialog::on_mesh_repair_decision_required ( wxCommandEvent & evt)
private
2563{
2564 bool initial = m_current_computation_initial;
2565 bool auto_color = m_current_computation_auto_color;
2566
2567 if (m_progress_dlg) {
2568 m_progress_dlg->Destroy();
2569 m_progress_dlg = nullptr;
2570 }
2571
2572 Slic3r::GUI::MessageDialog dlg(initial ? GetParent() : this,
2573 _L("The mesh has non-manifold geometry or open boundaries. You can import it as-is or repair it before importing."),
2574 _L("Mesh repair"), wxYES_NO | wxCANCEL | wxICON_WARNING | wxYES_DEFAULT);
2575 dlg.SetButtonLabel(wxID_YES, _L("Import without repair"));
2576 dlg.SetButtonLabel(wxID_NO, _L("Repair and import"), true);
2577 dlg.SetButtonLabel(wxID_CANCEL, _L("Cancel"));
2578 // "Repair and import" is the recommended action here, so the accent moves off the default YES
2579 // button onto NO. MsgDialog::add_button already styled both as ButtonType::Choice, so restyling
2580 // with the same type swaps only the palette and leaves the geometry alone.
2581 if (auto* yes_btn = dynamic_cast<Button*>(dlg.FindWindow(wxID_YES))) {
2582 yes_btn->SetStyle(ButtonStyle::Regular, ButtonType::Choice);
2583 //yes_btn->SetMinSize(wxSize(FromDIP(180), FromDIP(32))); // Height not matches and will cause issues on longer translations. let dialog manages it
2584 }
2585 if (auto* no_btn = dynamic_cast<Button*>(dlg.FindWindow(wxID_NO))) {
2586 no_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Choice);
2587 //no_btn->SetMinSize(wxSize(FromDIP(160), FromDIP(32))); // Height not matches and will cause issues on longer translations. let dialog manages it
2588 }
2589 dlg.Layout();
2590 dlg.Fit();
2591 dlg.CenterOnParent();
2592 int ret = dlg.ShowModal();
2593 if (ret == wxID_CANCEL) {
2594 m_cancel_flag = true;
2595 if (initial) {
2599 } else if (has_valid_result()) {
2601 } else {
2603 }
2604 return;
2605 }
2606 m_mesh_repair_decision = (ret == wxID_NO)
2608 : Slic3r::TexturePaintingSettings::MeshRepairDecision::ImportWithoutRepair;
2609
2610 start_computation(auto_color, initial);
2611}
bool m_current_computation_auto_color
Definition TextureImportDialog.hpp:354
Slic3r::TexturePaintingSettings::MeshRepairDecision m_mesh_repair_decision
Definition TextureImportDialog.hpp:355
MeshRepairDecision
Definition TextureToColor.hpp:18
@ ImportWithoutRepair
Definition TextureToColor.hpp:20
@ RepairAndImport
Definition TexturePainting.hpp:77

References _L, Choice, Confirm, has_valid_result(), Slic3r::GUI::Idle, Slic3r::TexturePaintingSettings::ImportWithoutRepair, m_cancel_flag, m_current_computation_auto_color, m_current_computation_initial, m_initial_computation_cancelled, m_initial_computation_pending, m_mesh_repair_decision, m_progress_dlg, Slic3r::GUI::Ready, Regular, Slic3r::TexturePaintingSettings::RepairAndImport, set_state(), Slic3r::GUI::MsgDialog::SetButtonLabel(), Slic3r::GUI::DPIAware< P >::ShowModal(), and start_computation().

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_ok_clicked()

void Slic3r::GUI::TextureImportDialog::on_ok_clicked ( wxCommandEvent & evt)
private
4161{
4163 return;
4164
4166 if (m_current_matches.empty())
4167 return;
4168
4170
4171 EndModal(wxID_OK);
4172}
void EndModal(int retCode) override
Definition GUI_Utils.hpp:305
bool is_params_dirty() const
Definition TextureImportDialog.cpp:4106

References build_matches_from_rows(), compact_used_virtual_filaments(), Slic3r::GUI::DPIDialog::EndModal(), has_valid_result(), is_params_dirty(), m_current_matches, m_state, and Slic3r::GUI::Ready.

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_skip_clicked()

void Slic3r::GUI::TextureImportDialog::on_skip_clicked ( wxCommandEvent & evt)
private
4080{
4081 m_skipped = true;
4082 m_new_filament_colors.clear();
4084 m_new_mixed_filaments.clear();
4085 m_current_matches.clear();
4087 EndModal(wxID_CANCEL);
4088}
void cancel_computation()
Definition TextureImportDialog.cpp:2400
bool m_skipped
Definition TextureImportDialog.hpp:327

References cancel_computation(), Slic3r::GUI::DPIDialog::EndModal(), m_current_matches, m_new_filament_colors, m_new_filament_preset_names, m_new_mixed_filaments, and m_skipped.

Referenced by Slic3r::GUI::wxBEGIN_EVENT_TABLE().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_smooth_slider_changed()

void Slic3r::GUI::TextureImportDialog::on_smooth_slider_changed ( wxCommandEvent & evt)
private
4031{
4032 set_smooth_value(m_smooth_slider->GetValue(), true);
4033}
void set_smooth_value(int value, bool update_spin)
Definition TextureImportDialog.cpp:3956

References m_smooth_slider, and set_smooth_value().

Referenced by build_params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_smooth_spin_changed()

void Slic3r::GUI::TextureImportDialog::on_smooth_spin_changed ( wxCommandEvent & evt)
private
4036{
4037 set_smooth_value(m_smooth_spin->GetValue(), true);
4038}

References m_smooth_spin, and set_smooth_value().

Referenced by build_params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_smooth_spin_text_changed()

void Slic3r::GUI::TextureImportDialog::on_smooth_spin_text_changed ( wxCommandEvent & evt)
private
4041{
4043 0, 10, evt.GetString());
4044}

References m_param_smooth, m_smooth_slider, m_smooth_spin, and preview_spin_text_value().

Referenced by build_params_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_sys_color_changed()

◆ prev_scale_factor()

float Slic3r::GUI::DPIAware< wxDialog >::prev_scale_factor ( ) const
inlineinherited
196{ return m_prev_scale_factor; }

◆ preview_spin_text_value()

void Slic3r::GUI::TextureImportDialog::preview_spin_text_value ( SpinInput * spin,
AccentSlider * slider,
int & param,
int min_value,
int max_value,
const wxString & text,
std::function< void()> on_value_changed = {} )
private
3968{
3969 long value;
3970 if (!text.ToLong(&value))
3971 return;
3972
3973 wxTextCtrl* tc = spin->GetTextCtrl();
3974 long parsed = value;
3975 value = std::clamp((int)parsed, min_value, max_value);
3976
3977 wxString normalized = text;
3978 if (parsed > max_value || (text.length() > 1 && text[0] == '0'))
3979 normalized = wxString::Format("%ld", value);
3980
3981 if (normalized != text) {
3982 long pos = tc->GetInsertionPoint();
3983 tc->ChangeValue(normalized);
3984 if (parsed > max_value)
3985 tc->SetInsertionPointEnd();
3986 else
3987 tc->SetInsertionPoint(std::min<long>(normalized.length(), std::max(0L, pos - 1)));
3988 }
3989
3990 param = (int)value;
3991 slider->SetValue(param);
3992 if (on_value_changed)
3993 on_value_changed();
3995}
#define L(s)
Definition ExtrusionEntity.cpp:25
void SetValue(int val)
Definition TextureImportDialog.cpp:259
void update_confirm_button_state()
Definition TextureImportDialog.cpp:4127
wxTextCtrl * GetTextCtrl()
Definition SpinInput.hpp:81
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16

References SpinInput::GetTextCtrl(), L, AccentSlider::SetValue(), and update_confirm_button_state().

Referenced by on_color_spin_text_changed(), and on_smooth_spin_text_changed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rebuild_mapping_rows()

void Slic3r::GUI::TextureImportDialog::rebuild_mapping_rows ( )
private
3612{
3613 m_mapping_scroll->Freeze();
3614 m_mapping_sizer->Clear(true);
3615 m_mapping_rows.clear();
3616
3617 if (m_current_matches.empty()) {
3618 m_mapping_scroll->FitInside();
3619 m_mapping_scroll->Thaw();
3620 return;
3621 }
3622
3623 auto get_target_wxcolor = [this](int idx) -> wxColour {
3624 if (idx >= 0 && idx < (int)m_filament_colors_rgba.size()) {
3625 const auto& c = m_filament_colors_rgba[idx];
3626 return wxColour((unsigned char)(c[0] * 255.f),
3627 (unsigned char)(c[1] * 255.f),
3628 (unsigned char)(c[2] * 255.f));
3629 }
3630 return wxColour(128, 128, 128);
3631 };
3632
3633 const auto display_numbers = compute_display_numbers();
3634 auto display_number = [display_numbers](int idx) -> int {
3635 return (idx >= 0 && idx < (int)display_numbers.size() && display_numbers[idx] > 0)
3636 ? display_numbers[idx] : idx + 1;
3637 };
3638
3639 auto get_filament_label = [this, display_number](int idx) -> wxString {
3640 if (idx >= 0 && idx < (int)m_filament_names.size())
3642 return wxString::Format(_L("Filament %d"), display_number(idx));
3643 };
3644
3645 const wxColour dash_clr = StateColor::darkModeColorFor(wxColour("#ACACAC"));
3646 const wxColour hex_fg = texture_import_text_colour();
3647 const wxColour card_bg = StateColor::darkModeColorFor(wxColour("#FFFFFF"));
3648 const wxColour card_bd = StateColor::darkModeColorFor(wxColour("#DBDBDB"));
3649 const wxColour name_fg = texture_import_text_colour();
3650 const wxColour chev_clr = StateColor::darkModeColorFor(wxColour("#6B6B6A"));
3651
3652 m_mapping_rows.resize(m_current_matches.size());
3653 for (size_t ci = 0; ci < m_current_matches.size(); ++ci) {
3654 auto& row = m_mapping_rows[ci];
3655 row.cluster_id = m_current_matches[ci].cluster_index;
3656 row.source_color = m_current_matches[ci].cluster_color;
3657 row.source_hex = rgb_to_hex(row.source_color).ToStdString();
3658 row.target_filament_idx = m_current_matches[ci].filament_index;
3659
3660 wxColour src_wx_color(
3661 (unsigned char)row.source_color[0],
3662 (unsigned char)row.source_color[1],
3663 (unsigned char)row.source_color[2]);
3664
3665 // --- Row container ---
3666 wxPanel* row_panel = new wxPanel(m_mapping_scroll, wxID_ANY);
3667 row_panel->SetBackgroundColour(m_mapping_scroll->GetBackgroundColour());
3668 row_panel->Bind(wxEVT_MOUSEWHEEL, &TextureImportDialog::dismiss_filament_popup_on_wheel, this);
3669 wxBoxSizer* row_sizer = new wxBoxSizer(wxHORIZONTAL);
3670
3671 // --- Source card (dashed border, circle + hex) ---
3672 const int src_w = FromDIP(138);
3673 const int target_min_w = FromDIP(239);
3674 const int row_h = FromDIP(32); // ORCA compact row height
3675 row.source_panel = new wxPanel(row_panel, wxID_ANY, wxDefaultPosition, wxSize(src_w, row_h),
3676 wxTAB_TRAVERSAL | wxFULL_REPAINT_ON_RESIZE);
3677 row.source_panel->SetMinSize(wxSize(src_w, row_h));
3678 row.source_panel->SetMaxSize(wxSize(src_w, row_h));
3679 row.source_panel->SetBackgroundStyle(wxBG_STYLE_PAINT);
3680
3681 row.source_panel->Bind(wxEVT_PAINT, [this, ci, src_wx_color, dash_clr, hex_fg](wxPaintEvent& e) {
3682 auto* p = static_cast<wxPanel*>(e.GetEventObject());
3683 wxAutoBufferedPaintDC dc(p);
3684 wxSize sz = p->GetClientSize();
3685
3686 dc.SetBrush(wxBrush(p->GetParent()->GetBackgroundColour()));
3687 dc.SetPen(*wxTRANSPARENT_PEN);
3688 dc.DrawRectangle(0, 0, sz.x, sz.y);
3689
3690 wxPen dash_pen(dash_clr, 1, wxPENSTYLE_SHORT_DASH);
3691 dc.SetPen(dash_pen);
3692 dc.SetBrush(wxBrush(p->GetParent()->GetBackgroundColour()));
3693 int r = 0; //p->FromDIP(8);
3694 dc.DrawRoundedRectangle(0, 0, sz.x, sz.y, r);
3695
3696 // Color circle 20px
3697 int cd = p->FromDIP(20); // ORCA match size of swatches
3698 int cx = p->FromDIP(6); // ORCA match margins
3699 int cy = (sz.y - cd) / 2;
3700 dc.SetPen(*wxTRANSPARENT_PEN);
3701 dc.SetBrush(wxBrush(src_wx_color));
3702 dc.DrawEllipse(cx, cy, cd, cd);
3703 draw_filament_swatch_ellipse_border(dc, src_wx_color, cx, cy, cd, cd);
3704
3705 if (ci < m_mapping_rows.size()) {
3706 wxFont hex_font = p->GetFont();
3707 hex_font.SetPointSize(9);
3708 dc.SetFont(hex_font);
3709 dc.SetTextForeground(hex_fg);
3710 wxString hex_str = wxString::Format("# %s", m_mapping_rows[ci].source_hex.substr(1));
3711 wxSize tsz = dc.GetTextExtent(hex_str);
3712 dc.DrawText(hex_str, cx + cd + p->FromDIP(6), (sz.y - tsz.y) / 2);
3713 }
3714 });
3715 row.source_panel->Bind(wxEVT_SIZE, [](wxSizeEvent& e) {
3716 e.Skip();
3717 static_cast<wxWindow*>(e.GetEventObject())->Refresh();
3718 });
3719 row.source_panel->Bind(wxEVT_MOUSEWHEEL, &TextureImportDialog::dismiss_filament_popup_on_wheel, this);
3720
3721 row_sizer->Add(row.source_panel, 0, wxEXPAND);
3722
3723 // --- Arrow panel (dashed arrow) ---
3724 const int arrow_w = FromDIP(24);
3725 wxPanel* arrow_panel = new wxPanel(row_panel, wxID_ANY, wxDefaultPosition, wxSize(arrow_w, row_h));
3726 arrow_panel->SetMinSize(wxSize(arrow_w, row_h));
3727 arrow_panel->SetMaxSize(wxSize(arrow_w, row_h));
3728 arrow_panel->SetBackgroundStyle(wxBG_STYLE_PAINT);
3729 arrow_panel->Bind(wxEVT_MOUSEWHEEL, &TextureImportDialog::dismiss_filament_popup_on_wheel, this);
3730 arrow_panel->Bind(wxEVT_PAINT, [dash_clr](wxPaintEvent& e) {
3731 auto* p = static_cast<wxPanel*>(e.GetEventObject());
3732 wxAutoBufferedPaintDC dc(p);
3733 wxSize sz = p->GetClientSize();
3734
3735 dc.SetBrush(wxBrush(p->GetParent()->GetBackgroundColour()));
3736 dc.SetPen(*wxTRANSPARENT_PEN);
3737 dc.DrawRectangle(0, 0, sz.x, sz.y);
3738
3739 int mid_y = sz.y / 2;
3740 int margin = p->FromDIP(2);
3741 int arrow_tip = sz.x - margin;
3742 int arrow_start = margin;
3743
3744 wxPen dash_pen(dash_clr, p->FromDIP(1), wxPENSTYLE_SHORT_DASH);
3745 dc.SetPen(dash_pen);
3746 dc.DrawLine(arrow_start, mid_y, arrow_tip - p->FromDIP(4), mid_y);
3747
3748 int ah = p->FromDIP(4);
3749 wxPoint tri[3] = {
3750 {arrow_tip, mid_y},
3751 {arrow_tip - ah, mid_y - ah / 2},
3752 {arrow_tip - ah, mid_y + ah / 2}
3753 };
3754 dc.SetPen(*wxTRANSPARENT_PEN);
3755 dc.SetBrush(wxBrush(dash_clr));
3756 dc.DrawPolygon(3, tri);
3757 });
3758
3759 row_sizer->Add(arrow_panel, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, FromDIP(4));
3760
3761 // --- Target card (numbered square + material name + chevron) ---
3762 row.target_panel = new wxPanel(row_panel, wxID_ANY, wxDefaultPosition, wxSize(-1, row_h),
3763 wxTAB_TRAVERSAL | wxFULL_REPAINT_ON_RESIZE);
3764 row.target_panel->SetMinSize(wxSize(target_min_w, row_h));
3765 row.target_panel->SetToolTip(get_filament_label(row.target_filament_idx));
3766 row.target_panel->SetBackgroundStyle(wxBG_STYLE_PAINT);
3767 row.target_panel->SetCursor(wxCursor(wxCURSOR_HAND));
3768
3769 row.target_panel->Bind(wxEVT_PAINT, [this, ci, get_target_wxcolor, get_filament_label,
3770 display_number, card_bg, card_bd, name_fg, chev_clr](wxPaintEvent& e) {
3771 auto* p = static_cast<wxPanel*>(e.GetEventObject());
3772 wxAutoBufferedPaintDC dc(p);
3773 wxSize sz = p->GetClientSize();
3774
3775 dc.SetBrush(wxBrush(p->GetParent()->GetBackgroundColour()));
3776 dc.SetPen(*wxTRANSPARENT_PEN);
3777 dc.DrawRectangle(0, 0, sz.x, sz.y);
3778
3779 if (ci >= m_mapping_rows.size()) return;
3780 int fil_idx = m_mapping_rows[ci].target_filament_idx;
3781
3782 int r = 0; //p->FromDIP(8);
3783 dc.SetBrush(wxBrush(card_bg));
3784 dc.SetPen(wxPen(card_bd, 1));
3785 dc.DrawRoundedRectangle(0, 0, sz.x, sz.y, r);
3786
3787 if (fil_idx >= 0 && fil_idx < (int)m_filament_entries.size() &&
3789 const TextureFilamentEntry& entry = m_filament_entries[fil_idx];
3790 wxFont mixed_font = p->GetFont();
3791 mixed_font.SetPointSize(10);
3792 dc.SetFont(mixed_font);
3793
3794 int x = p->FromDIP(6);// ORCA Match left margins
3795 const int sw = p->FromDIP(20); // ORCA match size of swatches
3796 const int sw_r = 0; //p->FromDIP(6);
3797 const int sw_y = (sz.y - sw) / 2;
3798 for (size_t mi = 0; mi < entry.mixed_components.size() && mi < entry.mixed_ratios.size(); ++mi) {
3799 if (mi > 0) {
3800 dc.SetTextForeground(name_fg);
3801 wxString plus = "+";
3802 wxSize psz = dc.GetTextExtent(plus);
3803 dc.DrawText(plus, x, (sz.y - psz.y) / 2);
3804 x += psz.x + p->FromDIP(4);
3805 }
3806
3807 const unsigned int comp_id = entry.mixed_components[mi];
3808 const int comp_idx = comp_id >= 1 ? (int)comp_id - 1 : -1;
3809 wxColour comp_clr("#D9D9D9");
3810 if (comp_idx >= 0 && comp_idx < (int)m_filament_colors_rgba.size()) {
3811 const auto& c = m_filament_colors_rgba[comp_idx];
3812 comp_clr = wxColour((unsigned char)(c[0] * 255.f),
3813 (unsigned char)(c[1] * 255.f),
3814 (unsigned char)(c[2] * 255.f));
3815 }
3816
3817 dc.SetPen(*wxTRANSPARENT_PEN);
3818 dc.SetBrush(wxBrush(comp_clr));
3819 dc.DrawRoundedRectangle(x, sw_y, sw, sw, sw_r);
3820 draw_filament_swatch_border(dc, comp_clr, x, sw_y, sw, sw, sw_r);
3821
3822 wxString num_str = wxString::Format("%d", display_number(comp_idx));
3823 wxSize nsz = dc.GetTextExtent(num_str);
3824 dc.SetTextForeground(comp_clr.GetLuminance() < 0.51 ? *wxWHITE : *wxBLACK); // ORCA match used foreground color with other swatches
3825 dc.DrawText(num_str, x + (sw - nsz.x) / 2, sw_y + (sw - nsz.y) / 2);
3826 x += sw + p->FromDIP(5);
3827
3828 dc.SetTextForeground(name_fg);
3829 wxString pct = wxString::Format("%d%%", entry.mixed_ratios[mi]);
3830 wxSize pct_sz = dc.GetTextExtent(pct);
3831 dc.DrawText(pct, x, (sz.y - pct_sz.y) / 2);
3832 x += pct_sz.x + p->FromDIP(5);
3833 if (x > sz.x - p->FromDIP(34))
3834 break;
3835 }
3836
3837 int chev_cx = sz.x - p->FromDIP(14);
3838 int chev_cy = sz.y / 2;
3839 int hw = p->FromDIP(3);
3840 int hh = p->FromDIP(2);
3841 dc.SetPen(wxPen(chev_clr, p->FromDIP(1) > 0 ? p->FromDIP(1) : 1));
3842 dc.DrawLine(chev_cx - hw, chev_cy - hh, chev_cx, chev_cy + hh);
3843 dc.DrawLine(chev_cx, chev_cy + hh, chev_cx + hw, chev_cy - hh);
3844 return;
3845 }
3846
3847 // Numbered color square 32x32, rounded 6px
3848 int sq = p->FromDIP(20); // ORCA match size of swatches
3849 int sq_x = p->FromDIP(6);// ORCA Match left margins
3850 int sq_y = (sz.y - sq) / 2;
3851 int sq_r = 0; //p->FromDIP(6);
3852 wxColour fil_clr = get_target_wxcolor(fil_idx);
3853 dc.SetPen(*wxTRANSPARENT_PEN);
3854 dc.SetBrush(wxBrush(fil_clr));
3855 dc.DrawRoundedRectangle(sq_x, sq_y, sq, sq, sq_r);
3856 draw_filament_swatch_border(dc, fil_clr, sq_x, sq_y, sq, sq, sq_r);
3857
3858 {
3859 wxFont num_font = p->GetFont();
3860 num_font.SetPointSize(10);
3861 dc.SetFont(num_font);
3862 dc.SetTextForeground(fil_clr.GetLuminance() < 0.51 ? *wxWHITE : *wxBLACK); // ORCA match used foreground color with other swatches
3863 wxString num_str = wxString::Format("%d", display_number(fil_idx));
3864 wxSize nsz = dc.GetTextExtent(num_str);
3865 dc.DrawText(num_str, sq_x + (sq - nsz.x) / 2, sq_y + (sq - nsz.y) / 2);
3866 }
3867
3868 // Material name
3869 {
3870 wxFont name_font = p->GetFont();
3871 name_font.SetPointSize(9);
3872 dc.SetFont(name_font);
3873 dc.SetTextForeground(name_fg);
3874 wxString name_str = get_filament_label(fil_idx);
3875 int text_x = sq_x + sq + p->FromDIP(8);
3876 int max_text_w = sz.x - text_x - p->FromDIP(24);
3877 if (max_text_w > 0) {
3878 name_str = ellipsize_text(dc, name_str, max_text_w);
3879 wxSize tsz = dc.GetTextExtent(name_str);
3880 dc.DrawText(name_str, text_x, (sz.y - tsz.y) / 2);
3881 }
3882 }
3883
3884 // Dropdown chevron at right edge
3885 {
3886 int chev_cx = sz.x - p->FromDIP(14);
3887 int chev_cy = sz.y / 2;
3888 int hw = p->FromDIP(3);
3889 int hh = p->FromDIP(2);
3890 dc.SetPen(wxPen(chev_clr, p->FromDIP(1) > 0 ? p->FromDIP(1) : 1));
3891 dc.DrawLine(chev_cx - hw, chev_cy - hh, chev_cx, chev_cy + hh);
3892 dc.DrawLine(chev_cx, chev_cy + hh, chev_cx + hw, chev_cy - hh);
3893 }
3894 });
3895
3896 row.target_panel->Bind(wxEVT_LEFT_DOWN, [this, ci](wxMouseEvent&) {
3898 });
3899 row.target_panel->Bind(wxEVT_SIZE, [](wxSizeEvent& e) {
3900 e.Skip();
3901 static_cast<wxWindow*>(e.GetEventObject())->Refresh();
3902 });
3903 row.target_panel->Bind(wxEVT_MOUSEWHEEL, &TextureImportDialog::dismiss_filament_popup_on_wheel, this);
3904
3905 row_sizer->Add(row.target_panel, 1, wxEXPAND);
3906
3907 row_panel->SetSizer(row_sizer);
3908 m_mapping_sizer->Add(row_panel, 0, wxEXPAND | wxBOTTOM, FromDIP(12));
3909 }
3910
3911 m_mapping_scroll->FitInside();
3912 m_mapping_scroll->Layout();
3913 m_mapping_scroll->Thaw();
3914}
static void draw_filament_swatch_border(wxDC &dc, const wxColour &colour, int x, int y, int w, int h, int radius=0)
Definition TextureImportDialog.cpp:167
static wxString ellipsize_text(wxDC &dc, wxString text, int max_width)
Definition TextureImportDialog.cpp:192
static wxColour texture_import_text_colour()
Definition TextureImportDialog.cpp:92
static void draw_filament_swatch_ellipse_border(wxDC &dc, const wxColour &colour, int x, int y, int w, int h)
Definition TextureImportDialog.cpp:181
void show_filament_popup(size_t row_index)
Definition TextureImportDialog.cpp:3365
std::vector< int > compute_display_numbers() const
Definition TextureImportDialog.cpp:2980
static wxString filament_name_to_wx_string(const std::string &name)
Definition TextureImportDialog.cpp:377
void plus(CGALMesh &A, CGALMesh &B)
Definition MeshBoolean.cpp:476

References _L, compute_display_numbers(), StateColor::darkModeColorFor(), dismiss_filament_popup_on_wheel(), draw_filament_swatch_border(), draw_filament_swatch_ellipse_border(), ellipsize_text(), Slic3r::GUI::filament_name_to_wx_string(), m_current_matches, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_mapping_rows, m_mapping_scroll, m_mapping_sizer, Slic3r::GUI::TextureFilamentEntry::mixed_components, Slic3r::GUI::TextureFilamentEntry::mixed_ratios, Slic3r::GUI::rgb_to_hex(), show_filament_popup(), Slic3r::GUI::texture_entry_is_mixed(), texture_import_text_colour(), and Slic3r::GUI::wxMouseEvent.

Referenced by add_decomposed_mixed_filament(), apply_auto_standard_mix(), on_auto_merge_toggled(), on_computation_complete(), on_dpi_changed(), reset_auto_mix(), and show_filament_popup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rescale()

void Slic3r::GUI::DPIAware< wxDialog >::rescale ( const wxRect & suggested_rect)
inlineprivateinherited
265 {
266 this->Freeze();
267
268 m_force_rescale = false;
269
270 // set normal application font as a current window font
271 m_normal_font = this->GetFont();
272
274
275 // rescale missed controls sizes and images
277
278 this->Layout();
279 this->Thaw();
280
281 // reset previous scale factor from current scale factor value
283 }
virtual void on_dpi_changed(const wxRect &suggested_rect)=0
void update_em_unit()
Definition GUI_Utils.hpp:249

◆ reset_auto_mix()

void Slic3r::GUI::TextureImportDialog::reset_auto_mix ( )
private
3205{
3207 return;
3208
3210
3211 // Clear mixed filament references so the compact inside do_auto_match()
3212 // removes them (and their exclusively-owned base physicals) from the
3213 // filament arrays, giving the baseline matching a clean starting state.
3214 for (auto& m : m_current_matches) {
3215 if (m.filament_index >= 0 && m.filament_index < (int)m_filament_entries.size() &&
3216 texture_entry_is_mixed(m_filament_entries[m.filament_index].kind)) {
3217 m.filament_index = -1;
3218 }
3219 }
3220
3221 // Re-run the baseline auto-match (same flow as the auto-merge toggle) so the
3222 // mapping reverts to the pre-mix state: every colour matches an existing
3223 // physical filament or a virtual physical filament, with no mixed filaments.
3224 const auto previous_matches = m_current_matches;
3225 do_auto_match();
3226 restore_current_match_order(previous_matches);
3232}

References compact_used_virtual_filaments(), dismiss_auto_mix_popup(), do_auto_match(), m_auto_mix_applied, m_current_matches, m_filament_entries, m_state, Slic3r::GUI::Ready, rebuild_mapping_rows(), restore_current_match_order(), Slic3r::GUI::texture_entry_is_mixed(), update_auto_mix_reset_visibility(), update_drop_warning_visibility(), and update_filament_color_map().

Referenced by build_mapping_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ restore_current_match_order()

void Slic3r::GUI::TextureImportDialog::restore_current_match_order ( const std::vector< Slic3r::FilamentMatch > & previous_matches)
private
2666{
2667 if (previous_matches.empty() || m_current_matches.size() < 2)
2668 return;
2669
2670 std::map<int, size_t> previous_order_by_cluster;
2671 for (size_t i = 0; i < previous_matches.size(); ++i) {
2672 if (previous_matches[i].cluster_index >= 0)
2673 previous_order_by_cluster.emplace(previous_matches[i].cluster_index, i);
2674 }
2675
2676 std::stable_sort(m_current_matches.begin(), m_current_matches.end(),
2677 [&previous_order_by_cluster](const auto& lhs, const auto& rhs) {
2678 const auto lhs_it = previous_order_by_cluster.find(lhs.cluster_index);
2679 const auto rhs_it = previous_order_by_cluster.find(rhs.cluster_index);
2680 const bool lhs_known = lhs_it != previous_order_by_cluster.end();
2681 const bool rhs_known = rhs_it != previous_order_by_cluster.end();
2682
2683 if (lhs_known != rhs_known)
2684 return lhs_known;
2685 if (!lhs_known)
2686 return false;
2687
2688 return lhs_it->second < rhs_it->second;
2689 });
2690}

References m_current_matches.

Referenced by on_auto_merge_toggled(), and reset_auto_mix().

Here is the caller graph for this function:

◆ scale_factor()

float Slic3r::GUI::DPIAware< wxDialog >::scale_factor ( ) const
inlineinherited
195{ return m_scale_factor; }

◆ set_auto_mix_mode()

void Slic3r::GUI::TextureImportDialog::set_auto_mix_mode ( TextureAutoMixMode mode)
private
3096{
3097 m_auto_mix_mode = mode;
3098 if (m_btn_auto_mix) {
3099 m_btn_auto_mix->SetLabel(auto_mix_mode_label(mode));
3100 m_btn_auto_mix->Refresh();
3101 }
3103}
void apply_auto_standard_mix(TextureAutoMixMode mode)
Definition TextureImportDialog.cpp:3105

References apply_auto_standard_mix(), Slic3r::GUI::auto_mix_mode_label(), m_auto_mix_mode, and m_btn_auto_mix.

Referenced by show_auto_mix_popup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_color_count_value()

void Slic3r::GUI::TextureImportDialog::set_color_count_value ( int value,
bool update_spin )
private
3947{
3948 m_param_color_count = std::clamp(value, 1, (int)max_filament_count());
3950 if (update_spin)
3954}

References m_color_slider, m_color_spin, m_param_color_count, max_filament_count(), update_color_count_preset_buttons(), and update_confirm_button_state().

Referenced by on_color_preset_clicked(), on_color_slider_changed(), on_color_spin_changed(), and on_computation_complete().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_em_unit()

void Slic3r::GUI::DPIAware< wxDialog >::set_em_unit ( int v)
inlineinherited
200{ m_em_unit = v; }

◆ set_prev_scale_factor()

void Slic3r::GUI::DPIAware< wxDialog >::set_prev_scale_factor ( float v)
inlineinherited

◆ set_scale_factor()

void Slic3r::GUI::DPIAware< wxDialog >::set_scale_factor ( float v)
inlineinherited
198{ m_scale_factor = v; }

◆ set_smooth_value()

void Slic3r::GUI::TextureImportDialog::set_smooth_value ( int value,
bool update_spin )
private
3957{
3958 m_param_smooth = std::clamp(value, 0, 10);
3960 if (update_spin)
3961 m_smooth_spin->SetValue(m_param_smooth);
3963}

References m_param_smooth, m_smooth_slider, m_smooth_spin, and update_confirm_button_state().

Referenced by on_smooth_slider_changed(), and on_smooth_spin_changed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_state()

void Slic3r::GUI::TextureImportDialog::set_state ( TextureImportState new_state)
private
2254{
2255 m_state = new_state;
2257}
void update_ui_for_state()
Definition TextureImportDialog.cpp:2259

References m_state, and update_ui_for_state().

Referenced by on_computation_complete(), on_computation_error(), on_mesh_repair_decision_required(), and start_computation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_auto_mix_popup()

void Slic3r::GUI::TextureImportDialog::show_auto_mix_popup ( )
private
3045{
3046 if (!m_btn_auto_mix || !m_btn_auto_mix->IsEnabled())
3047 return;
3048
3049 if (m_auto_mix_popup && m_auto_mix_popup->IsShown())
3050 return;
3052
3053 auto on_select = [this](TextureAutoMixMode mode) {
3054 set_auto_mix_mode(mode);
3055 };
3056 auto on_close = [this]() {
3057 m_auto_mix_popup = nullptr;
3058 };
3059
3060 auto* popup = new AutoMixSelectPopup(this, m_auto_mix_mode, m_btn_auto_mix->GetSize().x,
3062 on_select, on_close);
3063 wxPoint pos = m_btn_auto_mix->ClientToScreen(wxPoint(0, m_btn_auto_mix->GetSize().y));
3064 wxRect display_rect;
3065 int display_idx = wxDisplay::GetFromPoint(pos);
3066 if (display_idx != wxNOT_FOUND)
3067 display_rect = wxDisplay(display_idx).GetClientArea();
3068 else
3069 display_rect = wxDisplay().GetClientArea();
3070 pos.x = std::clamp(pos.x, display_rect.GetLeft(),
3071 std::max(display_rect.GetLeft(), display_rect.GetRight() - popup->GetSize().x));
3072 popup->Position(pos, wxSize(0, 0));
3073 popup->Bind(wxEVT_DESTROY, [this, popup](wxWindowDestroyEvent& e) {
3074 e.Skip();
3075 if (m_auto_mix_popup == popup)
3076 m_auto_mix_popup = nullptr;
3077 });
3078 m_auto_mix_popup = popup;
3079 popup->Popup();
3080}
void set_auto_mix_mode(TextureAutoMixMode mode)
Definition TextureImportDialog.cpp:3095
TextureAutoMixMode
Definition TextureImportDialog.hpp:49

References dismiss_auto_mix_popup(), m_auto_mix_font_point_size, m_auto_mix_mode, m_auto_mix_popup, m_btn_auto_mix, and set_auto_mix_mode().

Referenced by build_mapping_panel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_filament_popup()

void Slic3r::GUI::TextureImportDialog::show_filament_popup ( size_t row_index)
private
3366{
3367 if (row_index >= m_mapping_rows.size()) return;
3368
3369 if (m_skip_next_filament_popup_row == (int)row_index) {
3371 return;
3372 }
3373
3374 if (m_filament_popup && m_filament_popup->IsShown()) {
3375 if (m_filament_popup_row == (int)row_index) {
3377 return;
3378 }
3380 }
3381
3382 const auto display_numbers = compute_display_numbers();
3383 auto display_number = [display_numbers](int idx) -> int {
3384 return (idx >= 0 && idx < (int)display_numbers.size() && display_numbers[idx] > 0)
3385 ? display_numbers[idx] : idx + 1;
3386 };
3387
3388 auto on_select = [this, row_index, display_number](int idx) {
3389 if (row_index >= m_mapping_rows.size()) return;
3390 m_mapping_rows[row_index].target_filament_idx = idx;
3391 if (row_index < m_current_matches.size())
3392 m_current_matches[row_index].filament_index = idx;
3393 if (m_mapping_rows[row_index].target_panel) {
3394 wxString label = (idx >= 0 && idx < (int)m_filament_names.size())
3396 : wxString::Format(_L("Filament %d"), display_number(idx));
3397 m_mapping_rows[row_index].target_panel->SetToolTip(label);
3398 m_mapping_rows[row_index].target_panel->Refresh();
3399 }
3401 };
3402
3403 auto on_add_filament = [this, row_index](wxColour clr) {
3404 std::array<float, 4> rgba = {clr.Red() / 255.f, clr.Green() / 255.f,
3405 clr.Blue() / 255.f, 1.0f};
3406 std::string hex = wxString::Format("#%02X%02X%02X",
3407 clr.Red(), clr.Green(), clr.Blue()).ToStdString();
3408 int new_idx = add_virtual_filament(rgba, hex);
3409 if (new_idx < 0)
3410 return;
3411
3412 if (row_index < m_mapping_rows.size()) {
3413 m_mapping_rows[row_index].target_filament_idx = new_idx;
3414 if (row_index < m_current_matches.size())
3415 m_current_matches[row_index].filament_index = new_idx;
3416 }
3419 };
3420
3421 auto on_decompose_color = [this, row_index]() {
3422 CallAfter([this, row_index]() {
3424 });
3425 };
3426
3427 wxPanel* tp = m_mapping_rows[row_index].target_panel;
3428 if (!tp) return;
3429
3430 auto on_close = [this, row_index](bool closed_by_action) {
3431 if (m_filament_popup_row == (int)row_index) {
3432 m_filament_popup = nullptr;
3434 }
3435 if (!closed_by_action) {
3436 m_skip_next_filament_popup_row = (int)row_index;
3437 CallAfter([this, row_index]() {
3438 if (m_skip_next_filament_popup_row == (int)row_index)
3440 });
3441 }
3442 };
3443
3444 auto* popup = new FilamentSelectPopup(
3446 m_existing_filament_count, tp->GetSize().x, tp, on_select, on_add_filament,
3447 on_decompose_color,
3448 [this]() { return can_add_virtual_filament(); },
3449 on_close,
3450 display_numbers);
3451
3452 wxPoint pos = tp->ClientToScreen(wxPoint(0, tp->GetSize().y));
3453 wxRect display_rect;
3454 int display_idx = wxDisplay::GetFromPoint(pos);
3455 if (display_idx != wxNOT_FOUND)
3456 display_rect = wxDisplay(display_idx).GetClientArea();
3457 else
3458 display_rect = wxDisplay().GetClientArea();
3459 pos.x = std::clamp(pos.x, display_rect.GetLeft(),
3460 std::max(display_rect.GetLeft(), display_rect.GetRight() - popup->GetSize().x));
3461 popup->Position(pos, wxSize(0, 0));
3462 popup->Bind(wxEVT_DESTROY, [this, popup](wxWindowDestroyEvent& e) {
3463 e.Skip();
3464 if (m_filament_popup == popup) {
3465 m_filament_popup = nullptr;
3467 }
3468 });
3469 m_filament_popup = popup;
3470 m_filament_popup_row = (int)row_index;
3471 popup->Popup();
3472}
int m_skip_next_filament_popup_row
Definition TextureImportDialog.hpp:378
bool add_decomposed_mixed_filament(size_t row_index)
Definition TextureImportDialog.cpp:3244

References _L, add_decomposed_mixed_filament(), add_virtual_filament(), compute_display_numbers(), dismiss_filament_popup(), Slic3r::GUI::filament_name_to_wx_string(), m_current_matches, m_existing_filament_count, m_filament_colors_rgba, m_filament_entries, m_filament_names, m_filament_popup, m_filament_popup_row, m_mapping_rows, m_skip_next_filament_popup_row, rebuild_mapping_rows(), and update_filament_color_map().

Referenced by rebuild_mapping_rows().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowModal()

int Slic3r::GUI::TextureImportDialog::ShowModal ( )
override
1877{
1878 if (m_state == TextureImportState::Idle && m_painted.face_colors.empty()) {
1879 start_computation(true, true);
1880
1882 if (auto* event_loop = wxEventLoopBase::GetActive())
1883 event_loop->Yield();
1884 else
1885 wxYield();
1886 if (m_progress_dlg && m_progress_dlg->WasCancelled())
1887 m_cancel_flag = true;
1889 m_cancel_flag = true;
1890 wxMilliSleep(10);
1891 }
1892
1893 if (m_worker && m_worker->joinable())
1894 m_worker->join();
1895 m_worker.reset();
1896
1898 return wxID_CANCEL;
1899 }
1900
1901 ScopedInteractiveBusyCursorSuspender busy_cursor_suspender;
1902 return DPIDialog::ShowModal();
1903}
int ShowModal()
Definition GUI_Utils.hpp:216
std::function< bool()> m_initial_cancel_callback
Definition TextureImportDialog.hpp:347

References Slic3r::GUI::Idle, m_cancel_flag, m_initial_cancel_callback, m_initial_computation_cancelled, m_initial_computation_failed, m_initial_computation_pending, m_painted, m_progress_dlg, m_state, m_worker, Slic3r::GUI::DPIAware< wxDialog >::ShowModal(), and start_computation().

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sort_current_matches_by_filament_index()

void Slic3r::GUI::TextureImportDialog::sort_current_matches_by_filament_index ( )
private
2635{
2636 std::stable_sort(m_current_matches.begin(), m_current_matches.end(),
2637 [](const auto& lhs, const auto& rhs) {
2638 const bool lhs_valid = lhs.filament_index >= 0;
2639 const bool rhs_valid = rhs.filament_index >= 0;
2640
2641 if (lhs_valid != rhs_valid)
2642 return lhs_valid;
2643 if (!lhs_valid)
2644 return false;
2645
2646 return lhs.filament_index < rhs.filament_index;
2647 });
2648}

References m_current_matches.

Referenced by on_computation_complete().

Here is the caller graph for this function:

◆ start_computation()

void Slic3r::GUI::TextureImportDialog::start_computation ( bool auto_color = false,
bool initial = false )
private
2301{
2303
2304 m_cancel_flag = false;
2307 if (initial) {
2311 }
2313
2314 bool silent_initial = initial && static_cast<bool>(m_initial_cancel_callback);
2315 if (!silent_initial) {
2316 m_progress_dlg = new ProgressDialog(
2317 _L("Processing"), _L("Computing texture colors..."),
2318 100, initial ? GetParent() : this, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
2319 }
2320
2321 Slic3r::TexturePaintingSettings settings;
2322 settings.target_colors_num = auto_color ? 0 : (size_t)m_param_color_count;
2323 settings.smooth_weight = m_param_smooth / 10.0;
2325 settings.mesh_repair_callback = [](const indexed_triangle_set& mesh,
2326 indexed_triangle_set& repaired_mesh,
2327 std::function<void(const char*, unsigned)> progress_callback,
2328 std::function<bool()> cancel_callback,
2329 std::string* error_message) -> bool {
2330 if (progress_callback)
2331 progress_callback(_u8L("Repairing mesh").c_str(), 0);
2332
2333 struct Canceled {};
2334 TriangleMesh tm(mesh);
2335 try {
2336 if (!repair_mesh(tm, nullptr, error_message, [&cancel_callback](int) {
2337 if (cancel_callback && cancel_callback())
2338 throw Canceled();
2339 }))
2340 return false;
2341 } catch (const Canceled &) {
2342 return false;
2343 }
2344 repaired_mesh = tm.its;
2345 if (progress_callback)
2346 progress_callback(_u8L("Repairing mesh").c_str(), 100);
2347 return true;
2348 };
2349
2350 Slic3r::TexturedMesh mesh_copy = m_textured_mesh;
2351 wxEvtHandler* handler = this;
2352
2353 m_worker = std::make_unique<std::thread>([this, settings, mesh_copy, handler]() {
2354 Slic3r::PaintedMesh result;
2355
2356 auto progress_cb = [handler](int percent, const char*) {
2357 auto* evt = new wxCommandEvent(EVT_TEXTURE_COMPUTE_PROGRESS);
2358 evt->SetInt(percent);
2359 wxQueueEvent(handler, evt);
2360 };
2361
2362 auto cancel_cb = [this]() -> bool {
2363 return m_cancel_flag.load();
2364 };
2365
2366 auto worker_settings = settings;
2367 bool mesh_repair_decision_required = false;
2368 worker_settings.mesh_repair_decision_required = &mesh_repair_decision_required;
2369 bool ok;
2370 if (!mesh_copy.precomputed_face_colors.empty()) {
2372 mesh_copy, result, worker_settings, progress_cb, cancel_cb);
2373 } else {
2374 ok = Slic3r::texture_to_painting(mesh_copy, result, worker_settings, progress_cb, cancel_cb);
2375 }
2376
2377 if (m_cancel_flag.load()) {
2378 wxQueueEvent(handler, new wxCommandEvent(EVT_TEXTURE_COMPUTE_ERROR));
2379 return;
2380 }
2381
2382 if (!ok && mesh_repair_decision_required) {
2383 wxQueueEvent(handler, new wxCommandEvent(EVT_TEXTURE_MESH_REPAIR_DECISION));
2384 return;
2385 }
2386
2387 {
2388 std::lock_guard<std::mutex> lock(m_result_mutex);
2389 m_pending_result = std::move(result);
2390 }
2391
2392 if (ok) {
2393 wxQueueEvent(handler, new wxCommandEvent(EVT_TEXTURE_COMPUTE_DONE));
2394 } else {
2395 wxQueueEvent(handler, new wxCommandEvent(EVT_TEXTURE_COMPUTE_ERROR));
2396 }
2397 });
2398}
Slic3r::TexturedMesh m_textured_mesh
Definition TextureImportDialog.hpp:315
@ Computing
Definition TextureImportDialog.hpp:44
bool face_colors_to_painting(const TexturedMesh &mesh, PaintedMesh &painted, const TexturePaintingSettings &settings, PaintProgressCallback progress, PaintCancelCallback cancel)
Definition TexturePainting.cpp:368
bool repair_mesh(TriangleMesh &mesh, MeshRepairStats *stats_out, std::string *error, const std::function< void(int)> &progress)
Definition MeshRepair.cpp:1185
bool texture_to_painting(const TexturedMesh &textured, PaintedMesh &painted, const TexturePaintingSettings &settings, PaintProgressCallback progress, PaintCancelCallback cancel)
Definition TexturePainting.cpp:285
double smooth_weight
Definition TexturePainting.hpp:72
std::size_t target_colors_num
Definition TexturePainting.hpp:71
MeshRepairDecision mesh_repair_decision
Definition TexturePainting.hpp:79
PaintMeshRepairCallback mesh_repair_callback
Definition TexturePainting.hpp:81
bool * mesh_repair_decision_required
Definition TexturePainting.hpp:80
std::vector< std::array< std::size_t, 3 > > precomputed_face_colors
Definition TexturePainting.hpp:46

References _L, _u8L, cancel_computation(), Slic3r::GUI::Computing, Slic3r::face_colors_to_painting(), Slic3r::TriangleMesh::its, m_cancel_flag, m_current_computation_auto_color, m_current_computation_initial, m_initial_cancel_callback, m_initial_computation_cancelled, m_initial_computation_failed, m_initial_computation_pending, m_mesh_repair_decision, m_param_color_count, m_param_smooth, m_pending_result, m_progress_dlg, m_result_mutex, m_textured_mesh, m_worker, Slic3r::TexturePaintingSettings::mesh_repair_callback, Slic3r::TexturePaintingSettings::mesh_repair_decision, Slic3r::TexturePaintingSettings::mesh_repair_decision_required, Slic3r::TexturedMesh::precomputed_face_colors, Slic3r::repair_mesh(), set_state(), Slic3r::TexturePaintingSettings::smooth_weight, Slic3r::TexturePaintingSettings::target_colors_num, and Slic3r::texture_to_painting().

Referenced by on_apply_clicked(), on_color_preset_clicked(), on_mesh_repair_decision_required(), and ShowModal().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ style_confirm_button()

void Slic3r::GUI::TextureImportDialog::style_confirm_button ( bool dirty)
private
4150{
4151 if (dirty) {
4152 m_btn_ok->SetToolTip(_L("Reminder: parameters changed, click Apply to take effect"));
4153 } else {
4154 m_btn_ok->UnsetToolTip();
4155 }
4156 if (m_hint_label)
4157 m_hint_label->Show(dirty);
4158}

References _L, m_btn_ok, and m_hint_label.

Referenced by update_confirm_button_state(), and update_ui_for_state().

Here is the caller graph for this function:

◆ update_auto_mix_reset_visibility()

void Slic3r::GUI::TextureImportDialog::update_auto_mix_reset_visibility ( )
private
3235{
3236 if (!m_btn_mix_reset)
3237 return;
3239 if (wxWindow* parent = m_btn_mix_reset->GetParent())
3240 parent->Layout();
3241 }
3242}

References m_auto_mix_applied, and m_btn_mix_reset.

Referenced by apply_auto_standard_mix(), on_auto_merge_toggled(), on_computation_complete(), and reset_auto_mix().

Here is the caller graph for this function:

◆ update_color_count_preset_buttons()

void Slic3r::GUI::TextureImportDialog::update_color_count_preset_buttons ( )
private
3937{
3938 auto update = [this](auto* btn, int count) {
3940 };
3941 update(m_btn_color_4 , 4);
3942 update(m_btn_color_8 , 8);
3943 update(m_btn_color_16, 16);
3944}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246

References Confirm, count, m_btn_color_16, m_btn_color_4, m_btn_color_8, m_param_color_count, Regular, and Window.

Referenced by build_params_panel(), on_computation_error(), on_dpi_changed(), and set_color_count_value().

Here is the caller graph for this function:

◆ update_confirm_button_state()

void Slic3r::GUI::TextureImportDialog::update_confirm_button_state ( )
private
4128{
4130 return;
4131
4132 if (!has_valid_result()) {
4133 m_btn_ok->Enable(false);
4134 if (m_hint_label) m_hint_label->Hide();
4135 m_btn_ok->Refresh();
4136 Layout();
4137 return;
4138 }
4139
4140 m_btn_ok->Enable(true);
4142
4143 m_btn_ok->Refresh();
4144 Layout();
4145}
void style_confirm_button(bool dirty)
Definition TextureImportDialog.cpp:4149

References has_valid_result(), is_params_dirty(), m_btn_ok, m_hint_label, m_state, Slic3r::GUI::Ready, and style_confirm_button().

Referenced by preview_spin_text_value(), set_color_count_value(), and set_smooth_value().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_drop_warning_visibility()

void Slic3r::GUI::TextureImportDialog::update_drop_warning_visibility ( )
private
4115{
4116 if (!m_drop_warning_label) return;
4117 // Show only when the most recent do_auto_match() ran into the filament
4118 // cap AND we are in the Ready state. The flag is reset at every
4119 // do_auto_match() entry, so any "clean" re-run automatically hides the
4120 // warning even if a previous run had dropped clusters.
4121 const bool show = (m_state == TextureImportState::Ready) && m_filaments_dropped;
4122 if (m_drop_warning_label->IsShown() == show) return;
4123 m_drop_warning_label->Show(show);
4124 Layout();
4125}

References m_drop_warning_label, m_filaments_dropped, m_state, and Slic3r::GUI::Ready.

Referenced by apply_auto_standard_mix(), on_auto_merge_toggled(), on_computation_complete(), and reset_auto_mix().

Here is the caller graph for this function:

◆ update_em_unit()

void Slic3r::GUI::DPIAware< wxDialog >::update_em_unit ( )
inlineprivateinherited
250 {
251 // Linux specific issue : get_dpi_for_window(this) still doesn't responce to the Display's scale in new wxWidgets(3.1.3).
252 // So, calculate the m_em_unit value from the font size, as before
253#if !defined(__WXGTK__)
255#else
256 // initialize default width_unit according to the width of the one symbol ("m") of the currently active font of this window.
257 m_em_unit = std::max<size_t>(10, this->GetTextExtent("m").x - 1);
258#endif // __WXGTK__
259 }

◆ update_filament_color_map()

void Slic3r::GUI::TextureImportDialog::update_filament_color_map ( )
private
2616{
2617 std::map<std::array<std::size_t, 3>, std::array<float, 3>> color_map;
2618 for (const auto& m : m_current_matches) {
2619 if (m.filament_index >= 0 && m.filament_index < (int)m_filament_colors_rgba.size()) {
2620 color_map[m.cluster_color] = {
2621 m_filament_colors_rgba[m.filament_index][0],
2622 m_filament_colors_rgba[m.filament_index][1],
2623 m_filament_colors_rgba[m.filament_index][2]
2624 };
2625 }
2626 }
2627 m_preview_canvas->set_filament_color_map(color_map);
2628}

References m_current_matches, m_filament_colors_rgba, and m_preview_canvas.

Referenced by add_decomposed_mixed_filament(), apply_auto_standard_mix(), do_auto_match(), on_auto_merge_toggled(), on_computation_complete(), reset_auto_mix(), and show_filament_popup().

Here is the caller graph for this function:

◆ update_ui_for_state()

void Slic3r::GUI::TextureImportDialog::update_ui_for_state ( )
private
2260{
2261 bool computing = (m_state == TextureImportState::Computing);
2262 bool ready = (m_state == TextureImportState::Ready);
2263 bool idle = (m_state == TextureImportState::Idle);
2264 bool valid = has_valid_result();
2265
2266 m_color_slider->Enable(!computing);
2267 m_color_spin->Enable(!computing);
2268 m_smooth_slider->Enable(!computing);
2269 m_smooth_spin->Enable(!computing);
2270 m_btn_apply->Enable(!computing);
2271 m_btn_color_4->Enable(!computing);
2272 m_btn_color_8->Enable(!computing);
2273 m_btn_color_16->Enable(!computing);
2274 m_btn_color_auto->Enable(!computing);
2275 if (m_btn_auto_mix)
2276 m_btn_auto_mix->Enable(!computing);
2277 if (m_btn_mix_reset)
2278 m_btn_mix_reset->Enable(!computing);
2279 if (computing)
2281
2282 m_btn_ok->Enable(ready && valid);
2283 m_btn_skip->Enable(ready || idle);
2284
2285 m_auto_merge_cb->Enable(!computing);
2286
2287 m_preview_canvas->set_computing_overlay(computing);
2288
2289 if (ready && valid)
2291 else if (m_hint_label)
2292 m_hint_label->Hide();
2293
2294 m_btn_ok->Refresh();
2295 Layout();
2296}

References Slic3r::GUI::Computing, dismiss_auto_mix_popup(), has_valid_result(), Slic3r::GUI::Idle, is_params_dirty(), m_auto_merge_cb, m_btn_apply, m_btn_auto_mix, m_btn_color_16, m_btn_color_4, m_btn_color_8, m_btn_color_auto, m_btn_mix_reset, m_btn_ok, m_btn_skip, m_color_slider, m_color_spin, m_hint_label, m_preview_canvas, m_smooth_slider, m_smooth_spin, m_state, Slic3r::GUI::Ready, and style_confirm_button().

Referenced by set_state().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ was_skipped()

bool Slic3r::GUI::TextureImportDialog::was_skipped ( ) const
inline
212{ return m_skipped; }

References m_skipped.

Referenced by Slic3r::GUI::Plater::priv::run_textured_mesh_import_dialog().

Here is the caller graph for this function:

◆ wxDECLARE_EVENT_TABLE()

Slic3r::GUI::TextureImportDialog::wxDECLARE_EVENT_TABLE ( )
private

Member Data Documentation

◆ ID_BTN_APPLY

const int Slic3r::GUI::TextureImportDialog::ID_BTN_APPLY = wxID_HIGHEST + 204
staticprivate

◆ ID_BTN_SKIP

const int Slic3r::GUI::TextureImportDialog::ID_BTN_SKIP = wxID_HIGHEST + 205
staticprivate

◆ ID_COLOR_16

const int Slic3r::GUI::TextureImportDialog::ID_COLOR_16 = wxID_HIGHEST + 202
staticprivate

◆ ID_COLOR_4

const int Slic3r::GUI::TextureImportDialog::ID_COLOR_4 = wxID_HIGHEST + 200
staticprivate

◆ ID_COLOR_8

const int Slic3r::GUI::TextureImportDialog::ID_COLOR_8 = wxID_HIGHEST + 201
staticprivate

◆ ID_COLOR_AUTO

const int Slic3r::GUI::TextureImportDialog::ID_COLOR_AUTO = wxID_HIGHEST + 203
staticprivate

◆ ID_VIEW_MULTICOLOR

const int Slic3r::GUI::TextureImportDialog::ID_VIEW_MULTICOLOR = wxID_HIGHEST + 207
staticprivate

Referenced by build_preview_panel().

◆ ID_VIEW_ORIGINAL

const int Slic3r::GUI::TextureImportDialog::ID_VIEW_ORIGINAL = wxID_HIGHEST + 206
staticprivate

Referenced by build_preview_panel().

◆ m_applied_color_count

int Slic3r::GUI::TextureImportDialog::m_applied_color_count = -1
private

◆ m_applied_smooth

int Slic3r::GUI::TextureImportDialog::m_applied_smooth = -1
private

◆ m_auto_merge_cb

wxCheckBox* Slic3r::GUI::TextureImportDialog::m_auto_merge_cb = nullptr
private

◆ m_auto_merge_enabled

bool Slic3r::GUI::TextureImportDialog::m_auto_merge_enabled = true
private

Referenced by on_auto_merge_toggled().

◆ m_auto_mix_applied

bool Slic3r::GUI::TextureImportDialog::m_auto_mix_applied = false
private

◆ m_auto_mix_font_point_size

int Slic3r::GUI::TextureImportDialog::m_auto_mix_font_point_size = 10
private

◆ m_auto_mix_mode

TextureAutoMixMode Slic3r::GUI::TextureImportDialog::m_auto_mix_mode = TextureAutoMixMode::CMYW
private

◆ m_auto_mix_popup

AutoMixSelectPopup* Slic3r::GUI::TextureImportDialog::m_auto_mix_popup = nullptr
private

◆ m_btn_apply

Button* Slic3r::GUI::TextureImportDialog::m_btn_apply = nullptr
private

◆ m_btn_auto_mix

Button* Slic3r::GUI::TextureImportDialog::m_btn_auto_mix = nullptr
private

◆ m_btn_color_16

Button* Slic3r::GUI::TextureImportDialog::m_btn_color_16 = nullptr
private

◆ m_btn_color_4

Button* Slic3r::GUI::TextureImportDialog::m_btn_color_4 = nullptr
private

◆ m_btn_color_8

Button* Slic3r::GUI::TextureImportDialog::m_btn_color_8 = nullptr
private

◆ m_btn_color_auto

Button* Slic3r::GUI::TextureImportDialog::m_btn_color_auto = nullptr
private

◆ m_btn_mix_reset

Button* Slic3r::GUI::TextureImportDialog::m_btn_mix_reset = nullptr
private

◆ m_btn_ok

Button* Slic3r::GUI::TextureImportDialog::m_btn_ok = nullptr
private

◆ m_btn_skip

Button* Slic3r::GUI::TextureImportDialog::m_btn_skip = nullptr
private

◆ m_btn_view_multicolor

Button* Slic3r::GUI::TextureImportDialog::m_btn_view_multicolor = nullptr
private

◆ m_btn_view_original

Button* Slic3r::GUI::TextureImportDialog::m_btn_view_original = nullptr
private

◆ m_can_rescale

bool Slic3r::GUI::DPIAware< wxDialog >::m_can_rescale
privateinherited
235{ true };

◆ m_cancel_flag

std::atomic<bool> Slic3r::GUI::TextureImportDialog::m_cancel_flag {false}
private

◆ m_color_slider

◆ m_color_spin

◆ m_current_computation_auto_color

bool Slic3r::GUI::TextureImportDialog::m_current_computation_auto_color = false
private

◆ m_current_computation_initial

bool Slic3r::GUI::TextureImportDialog::m_current_computation_initial = false
private

◆ m_current_matches

◆ m_default_virtual_filament_preset_name

std::string Slic3r::GUI::TextureImportDialog::m_default_virtual_filament_preset_name
private

◆ m_drop_warning_label

wxStaticText* Slic3r::GUI::TextureImportDialog::m_drop_warning_label = nullptr
private

◆ m_em_unit

int Slic3r::GUI::DPIAware< wxDialog >::m_em_unit
privateinherited

◆ m_existing_filament_count

size_t Slic3r::GUI::TextureImportDialog::m_existing_filament_count = 0
private

◆ m_fallback_to_geometry_only

bool Slic3r::GUI::TextureImportDialog::m_fallback_to_geometry_only = false
private

◆ m_filament_color_strs

std::vector<std::string> Slic3r::GUI::TextureImportDialog::m_filament_color_strs
private

◆ m_filament_colors_rgba

◆ m_filament_entries

◆ m_filament_names

std::vector<std::string> Slic3r::GUI::TextureImportDialog::m_filament_names
private

◆ m_filament_popup

FilamentSelectPopup* Slic3r::GUI::TextureImportDialog::m_filament_popup = nullptr
private

◆ m_filament_popup_row

int Slic3r::GUI::TextureImportDialog::m_filament_popup_row = -1
private

◆ m_filaments_dropped

bool Slic3r::GUI::TextureImportDialog::m_filaments_dropped = false
private

◆ m_force_rescale

bool Slic3r::GUI::DPIAware< wxDialog >::m_force_rescale
privateinherited
236{ false };

◆ m_hint_label

wxStaticText* Slic3r::GUI::TextureImportDialog::m_hint_label = nullptr
private

◆ m_initial_cancel_callback

std::function<bool()> Slic3r::GUI::TextureImportDialog::m_initial_cancel_callback
private

Referenced by ShowModal(), and start_computation().

◆ m_initial_computation_cancelled

bool Slic3r::GUI::TextureImportDialog::m_initial_computation_cancelled = false
private

◆ m_initial_computation_failed

bool Slic3r::GUI::TextureImportDialog::m_initial_computation_failed = false
private

◆ m_initial_computation_pending

bool Slic3r::GUI::TextureImportDialog::m_initial_computation_pending = false
private

◆ m_initial_progress_callback

std::function<bool(int)> Slic3r::GUI::TextureImportDialog::m_initial_progress_callback
private

Referenced by on_computation_progress().

◆ m_initial_tooltips_set

bool Slic3r::GUI::TextureImportDialog::m_initial_tooltips_set = false
private

Referenced by build_params_panel().

◆ m_mapping_rows

◆ m_mapping_scroll

wxScrolledWindow* Slic3r::GUI::TextureImportDialog::m_mapping_scroll = nullptr
private

◆ m_mapping_sizer

wxBoxSizer* Slic3r::GUI::TextureImportDialog::m_mapping_sizer = nullptr
private

◆ m_mesh_repair_decision

Slic3r::TexturePaintingSettings::MeshRepairDecision Slic3r::GUI::TextureImportDialog::m_mesh_repair_decision
private

◆ m_new_filament_colors

std::vector<std::array<float, 4> > Slic3r::GUI::TextureImportDialog::m_new_filament_colors
private

◆ m_new_filament_preset_names

std::vector<std::string> Slic3r::GUI::TextureImportDialog::m_new_filament_preset_names
private

◆ m_new_font_point_size

int Slic3r::GUI::DPIAware< wxDialog >::m_new_font_point_size
privateinherited

◆ m_new_mixed_filaments

std::vector<TextureNewMixedFilament> Slic3r::GUI::TextureImportDialog::m_new_mixed_filaments
private

◆ m_normal_font

wxFont Slic3r::GUI::DPIAware< wxDialog >::m_normal_font
privateinherited

◆ m_painted

Slic3r::PaintedMesh Slic3r::GUI::TextureImportDialog::m_painted
private

◆ m_param_color_count

◆ m_param_smooth

◆ m_pending_result

Slic3r::PaintedMesh Slic3r::GUI::TextureImportDialog::m_pending_result
private

◆ m_prev_scale_factor

float Slic3r::GUI::DPIAware< wxDialog >::m_prev_scale_factor
privateinherited

◆ m_preview_canvas

TexturePreviewCanvas* Slic3r::GUI::TextureImportDialog::m_preview_canvas = nullptr
private

◆ m_progress_dlg

◆ m_result_mutex

std::mutex Slic3r::GUI::TextureImportDialog::m_result_mutex
private

◆ m_scale_factor

float Slic3r::GUI::DPIAware< wxDialog >::m_scale_factor
privateinherited

◆ m_skip_next_filament_popup_row

int Slic3r::GUI::TextureImportDialog::m_skip_next_filament_popup_row = -1
private

Referenced by show_filament_popup().

◆ m_skipped

bool Slic3r::GUI::TextureImportDialog::m_skipped = false
private

Referenced by on_skip_clicked(), and was_skipped().

◆ m_smooth_slider

◆ m_smooth_spin

◆ m_state

◆ m_tab_panel

wxPanel* Slic3r::GUI::TextureImportDialog::m_tab_panel = nullptr
private

◆ m_textured_mesh

Slic3r::TexturedMesh Slic3r::GUI::TextureImportDialog::m_textured_mesh
private

Referenced by start_computation().

◆ m_worker

std::unique_ptr<std::thread> Slic3r::GUI::TextureImportDialog::m_worker
private

The documentation for this class was generated from the following files: