Allow opening object 'Manage Color Data' dialog from right click menu

This commit is contained in:
sentientstardust
2026-05-08 04:28:25 +01:00
parent aee6db8e27
commit d115824d6a
5 changed files with 129 additions and 43 deletions

View File

@@ -18,6 +18,7 @@
//BBS: add partplate related logic
#include "PartPlate.hpp"
#include "Gizmos/GLGizmoEmboss.hpp"
#include "Gizmos/GLGizmoMmuSegmentation.hpp"
#include "Gizmos/GLGizmoSVG.hpp"
#include <boost/algorithm/string.hpp>
@@ -98,6 +99,31 @@ static std::vector<unsigned int> ui_ordered_filament_ids(int fallback_count)
return ids;
}
static int menu_item_position(wxMenu *menu, const wxString &name)
{
int position = 0;
for (auto node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext(), ++position) {
wxMenuItem *item = node->GetData();
if (item != nullptr && item->GetItemLabelText() == name)
return position;
}
return wxNOT_FOUND;
}
static ModelObject *selected_managed_color_data_object()
{
Plater *app_plater = wxGetApp().plater();
if (app_plater == nullptr)
return nullptr;
const int object_idx = app_plater->get_selection().get_object_idx();
ModelObjectPtrs &objects = wxGetApp().model().objects;
if (object_idx < 0 || size_t(object_idx) >= objects.size())
return nullptr;
return objects[size_t(object_idx)];
}
static bool is_improper_category(const std::string& category, const int filaments_cnt, const bool is_object_settings = true)
{
return category.empty() ||
@@ -1174,6 +1200,45 @@ void MenuFactory::append_menu_items_flush_options(wxMenu* menu)
menu->Insert(i, wxID_ANY, _L("Flush Options"), flush_options_menu);
}
void MenuFactory::append_menu_item_manage_color_data(wxMenu *menu)
{
const wxString name = _L("Manage Color Data");
const int item_id = menu->FindItem(name);
if (item_id != wxNOT_FOUND)
menu->Destroy(item_id);
if (selected_managed_color_data_object() == nullptr)
return;
int insert_pos = menu_item_position(menu, _L("Flush Options"));
if (insert_pos != wxNOT_FOUND)
++insert_pos;
else {
insert_pos = menu_item_position(menu, _L("Edit in Parameter Table"));
if (insert_pos != wxNOT_FOUND)
++insert_pos;
}
auto can_manage_color_data = []() {
Plater *app_plater = wxGetApp().plater();
return app_plater != nullptr && app_plater->get_view3D_canvas3D() != nullptr && selected_managed_color_data_object() != nullptr;
};
append_menu_item(menu, wxID_ANY, name, _L("Manage Color Data for this object"),
[this](wxCommandEvent &) {
Plater *app_plater = wxGetApp().plater();
if (app_plater == nullptr)
return;
GLCanvas3D *canvas = app_plater->get_view3D_canvas3D();
ModelObject *object = selected_managed_color_data_object();
if (canvas == nullptr || object == nullptr)
return;
Slic3r::GUI::open_color_data_management_dialog(m_parent, *canvas, object);
}, "", menu, can_manage_color_data, m_parent, insert_pos);
}
void MenuFactory::append_menu_items_convert_unit(wxMenu* menu)
{
std::vector<int> obj_idxs, vol_idxs;
@@ -1825,6 +1890,7 @@ wxMenu* MenuFactory::object_menu()
{
append_menu_items_convert_unit(&m_object_menu);
append_menu_items_flush_options(&m_object_menu);
append_menu_item_manage_color_data(&m_object_menu);
append_menu_item_invalidate_cut_info(&m_object_menu);
append_menu_item_edit_text(&m_object_menu);
append_menu_item_edit_svg(&m_object_menu);

View File

@@ -152,6 +152,7 @@ private:
void append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu);
void append_menu_items_convert_unit(wxMenu* menu); // Add "Conver/Revert..." menu items (from/to inches/meters) after "Reload From Disk"
void append_menu_items_flush_options(wxMenu* menu);
void append_menu_item_manage_color_data(wxMenu *menu);
void append_menu_item_merge_to_multipart_object(wxMenu *menu);
void append_menu_item_merge_to_single_object(wxMenu* menu);
void append_menu_item_merge_parts_to_single_part(wxMenu *menu);

View File

@@ -4319,6 +4319,30 @@ static bool assign_object_to_texture_mapping_zone(ModelObject &object)
return true;
}
static void assign_texture_mapping_zone_preserving_painted_regions(ModelObject &object, unsigned int texture_mapping_filament_id)
{
if (texture_mapping_filament_id == 0)
return;
bool has_painted_regions = false;
for (const ModelVolume *volume : object.volumes) {
if (volume != nullptr && volume->is_model_part() && !volume->mmu_segmentation_facets.empty()) {
has_painted_regions = true;
break;
}
}
if (!has_painted_regions)
object.config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object.volumes) {
if (volume == nullptr || !volume->is_model_part())
continue;
if (!has_painted_regions || volume->mmu_segmentation_facets.empty())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
}
struct ManagedRegionColorSource
{
std::vector<std::vector<TriangleSelector::FacetStateTriangle>> triangles_per_type;
@@ -5472,6 +5496,15 @@ private:
wxStaticText *m_raw_image_texture_mode = nullptr;
};
void open_color_data_management_dialog(wxWindow *parent, GLCanvas3D &canvas, ModelObject *object, std::function<void()> on_object_changed)
{
if (object == nullptr)
return;
ColorDataManagementDialog dialog(parent, canvas, object, std::move(on_object_changed));
dialog.ShowModal();
}
void GLGizmoMmuSegmentation::init_extruders_data(const std::vector<ColorRGBA> &extruder_colors)
{
const unsigned int old_selected_filament_id =
@@ -6674,12 +6707,7 @@ void GLGizmoMmuSegmentation::convert_selected_object_vertex_colors_to_texture_ma
return;
const unsigned int texture_mapping_filament_id = ensure_texture_mapping_zone();
if (texture_mapping_filament_id != 0) {
object->config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object->volumes)
if (volume != nullptr && volume->is_model_part())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
assign_texture_mapping_zone_preserving_painted_regions(*object, texture_mapping_filament_id);
for (auto &selector : m_triangle_selectors)
if (selector != nullptr)
@@ -6750,12 +6778,7 @@ void GLGizmoMmuSegmentation::convert_selected_object_image_texture_to_texture_ma
return;
const unsigned int texture_mapping_filament_id = ensure_texture_mapping_zone();
if (texture_mapping_filament_id != 0) {
object->config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object->volumes)
if (volume != nullptr && volume->is_model_part())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
assign_texture_mapping_zone_preserving_painted_regions(*object, texture_mapping_filament_id);
for (auto &selector : m_triangle_selectors)
if (selector != nullptr)
@@ -7239,13 +7262,15 @@ void GLGizmoTrueColorPainting::init_model_triangle_selectors()
preview_rgb_data = preview.get();
m_preview_rgb_data_by_volume.back() = std::move(preview);
}
} else {
preview_rgb_data = &volume->texture_mapping_color_facets;
}
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorPatch>(volume->mesh(), volume, colors, 0.2f));
if (TriangleSelectorPatch *patch = dynamic_cast<TriangleSelectorPatch *>(m_triangle_selectors.back().get())) {
patch->set_none_state_rendered(false);
patch->set_texture_mapping_color_preview(preview_rgb_data);
patch->set_texture_preview_needed(!volume->texture_mapping_color_facets.empty() || preview_rgb_data != nullptr);
patch->set_texture_preview_needed(preview_rgb_data != nullptr);
patch->set_texture_preview_opaque(true);
}
m_triangle_selectors.back()->set_wireframe_needed(true);
@@ -7385,12 +7410,7 @@ void GLGizmoTrueColorPainting::update_model_object()
return;
const unsigned int texture_mapping_filament_id = ensure_texture_mapping_zone();
if (texture_mapping_filament_id != 0) {
object->config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object->volumes)
if (volume != nullptr && volume->is_model_part())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
assign_texture_mapping_zone_preserving_painted_regions(*object, texture_mapping_filament_id);
refresh_selected_object_after_rgb_change(object);
}
@@ -7409,13 +7429,12 @@ void GLGizmoTrueColorPainting::open_color_data_management_dialog()
if (object == nullptr)
return;
ColorDataManagementDialog dialog(wxGetApp().mainframe, m_parent, object, [this]() {
Slic3r::GUI::open_color_data_management_dialog(wxGetApp().mainframe, m_parent, object, [this]() {
update_selected_object_color_state();
init_model_triangle_selectors();
m_parent.set_as_dirty();
m_parent.request_extra_frame();
});
dialog.ShowModal();
update_selected_object_color_state();
init_model_triangle_selectors();
m_parent.set_as_dirty();
@@ -7475,12 +7494,7 @@ void GLGizmoTrueColorPainting::initialize_selected_object_rgb_data()
return;
const unsigned int texture_mapping_filament_id = ensure_texture_mapping_zone();
if (texture_mapping_filament_id != 0) {
object->config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object->volumes)
if (volume != nullptr && volume->is_model_part())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
assign_texture_mapping_zone_preserving_painted_regions(*object, texture_mapping_filament_id);
refresh_selected_object_after_rgb_change(object);
}
@@ -7540,12 +7554,7 @@ void GLGizmoTrueColorPainting::convert_selected_object_vertex_colors_to_rgb_data
return;
const unsigned int texture_mapping_filament_id = ensure_texture_mapping_zone();
if (texture_mapping_filament_id != 0) {
object->config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object->volumes)
if (volume != nullptr && volume->is_model_part())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
assign_texture_mapping_zone_preserving_painted_regions(*object, texture_mapping_filament_id);
refresh_selected_object_after_rgb_change(object);
}
@@ -7601,12 +7610,7 @@ void GLGizmoTrueColorPainting::convert_selected_object_image_texture_to_rgb_data
return;
const unsigned int texture_mapping_filament_id = ensure_texture_mapping_zone();
if (texture_mapping_filament_id != 0) {
object->config.set("extruder", int(texture_mapping_filament_id));
for (ModelVolume *volume : object->volumes)
if (volume != nullptr && volume->is_model_part())
volume->config.set("extruder", int(texture_mapping_filament_id));
}
assign_texture_mapping_zone_preserving_painted_regions(*object, texture_mapping_filament_id);
refresh_selected_object_after_rgb_change(object);
}
@@ -8490,13 +8494,12 @@ void GLGizmoImageProjection::open_color_data_management_dialog()
if (object == nullptr)
return;
ColorDataManagementDialog dialog(wxGetApp().mainframe, m_parent, object, [this]() {
Slic3r::GUI::open_color_data_management_dialog(wxGetApp().mainframe, m_parent, object, [this]() {
m_projection_mode_initialized = false;
update_default_projection_mode();
m_parent.set_as_dirty();
m_parent.request_extra_frame();
});
dialog.ShowModal();
m_projection_mode_initialized = false;
update_default_projection_mode();
m_parent.set_as_dirty();

View File

@@ -7,13 +7,24 @@
#include <array>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
class wxWindow;
namespace Slic3r {
class ModelObject;
}
namespace Slic3r::GUI {
class GLCanvas3D;
void open_color_data_management_dialog(wxWindow *parent, GLCanvas3D &canvas, ModelObject *object, std::function<void()> on_object_changed = {});
class GLMmSegmentationGizmo3DScene
{
public:

View File

@@ -3663,8 +3663,13 @@ void render_model_vertex_color_preview_models(
print_volume_z);
for (size_t idx = 0; idx < models.size(); ++idx) {
const float mix = texture_preview_mix_for_filament(filament_ids[idx], num_physical, texture_mgr);
const bool invalid = texture_preview_settings_invalid_for_filament(filament_ids[idx], num_physical, texture_mgr);
const bool raw_vertex_color_preview = filament_ids[idx] == 0;
const float mix = raw_vertex_color_preview ?
1.f :
texture_preview_mix_for_filament(filament_ids[idx], num_physical, texture_mgr);
const bool invalid = raw_vertex_color_preview ?
false :
texture_preview_settings_invalid_for_filament(filament_ids[idx], num_physical, texture_mgr);
if (mix <= 0.f && !invalid)
continue;
shader->set_uniform("texture_preview_mix", mix);