Remap paint after mesh boolean

This commit is contained in:
Noisyfox
2026-05-09 21:48:52 +08:00
parent e6b3f6ccef
commit 3aadd6e080
2 changed files with 31 additions and 5 deletions

View File

@@ -188,6 +188,19 @@ CommonGizmosDataID GLGizmoMeshBoolean::on_get_requirements() const
| int(CommonGizmosDataID::ObjectClipper));
}
std::optional<TriangleSelector::SavedPainting> VolumeInfo::save_painting() const
{
if (wxGetApp().app_config->get_bool("keep_painting")) {
std::optional<TriangleSelector::SavedPainting> saved_painting = mv->save_painting();
if (saved_painting) {
saved_painting->mesh.transform(trafo);
}
return saved_painting;
}
return {};
}
void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_limit)
{
y = std::min(y, bottom_limit - ImGui::GetWindowHeight());
@@ -346,7 +359,9 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
std::vector<TriangleMesh> temp_mesh_resuls;
Slic3r::MeshBoolean::mcut::make_boolean(temp_src_mesh, temp_tool_mesh, temp_mesh_resuls, "UNION");
if (temp_mesh_resuls.size() != 0) {
generate_new_volume(true, *temp_mesh_resuls.begin());
// For union, we want to keep paint from both meshes
std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings{m_src.save_painting(), m_tool.save_painting()};
generate_new_volume(true, *temp_mesh_resuls.begin(), saved_paintings);
wxGetApp().notification_manager()->close_plater_warning_notification(warning_text);
}
else {
@@ -364,7 +379,9 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
std::vector<TriangleMesh> temp_mesh_resuls;
Slic3r::MeshBoolean::mcut::make_boolean(temp_src_mesh, temp_tool_mesh, temp_mesh_resuls, "A_NOT_B");
if (temp_mesh_resuls.size() != 0) {
generate_new_volume(m_diff_delete_input, *temp_mesh_resuls.begin());
// For diff, we only need paint from src
std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings{m_src.save_painting()};
generate_new_volume(m_diff_delete_input, *temp_mesh_resuls.begin(), saved_paintings);
wxGetApp().notification_manager()->close_plater_warning_notification(warning_text);
}
else {
@@ -382,7 +399,9 @@ void GLGizmoMeshBoolean::on_render_input_window(float x, float y, float bottom_l
std::vector<TriangleMesh> temp_mesh_resuls;
Slic3r::MeshBoolean::mcut::make_boolean(temp_src_mesh, temp_tool_mesh, temp_mesh_resuls, "INTERSECTION");
if (temp_mesh_resuls.size() != 0) {
generate_new_volume(m_inter_delete_input, *temp_mesh_resuls.begin());
// For intersection, we want to keep paint from both meshes
std::vector<std::optional<TriangleSelector::SavedPainting>> saved_paintings{m_src.save_painting(), m_tool.save_painting()};
generate_new_volume(m_inter_delete_input, *temp_mesh_resuls.begin(), saved_paintings);
wxGetApp().notification_manager()->close_plater_warning_notification(warning_text);
}
else {
@@ -420,7 +439,7 @@ void GLGizmoMeshBoolean::on_save(cereal::BinaryOutputArchive &ar) const
ar(m_enable, m_operation_mode, m_selecting_state, m_diff_delete_input, m_inter_delete_input, m_src, m_tool);
}
void GLGizmoMeshBoolean::generate_new_volume(bool delete_input, const TriangleMesh& mesh_result) {
void GLGizmoMeshBoolean::generate_new_volume(const bool delete_input, TriangleMesh& mesh_result, const std::vector<std::optional<TriangleSelector::SavedPainting>>& saved_paintings) {
wxGetApp().plater()->take_snapshot("Mesh Boolean");
@@ -429,6 +448,11 @@ void GLGizmoMeshBoolean::generate_new_volume(bool delete_input, const TriangleMe
// generate new volume
ModelVolume* new_volume = curr_model_object->add_volume(std::move(mesh_result));
// Remap paintings
for (const auto& saved_painting : saved_paintings) {
new_volume->restore_painting(saved_painting, true);
}
// assign to new_volume from old_volume
ModelVolume* old_volume = m_src.mv;
std::string suffix;

View File

@@ -34,6 +34,8 @@ struct VolumeInfo {
void serialize(Archive& ar) {
ar(volume_idx, trafo);
}
std::optional<TriangleSelector::SavedPainting> save_painting() const;
};
class GLGizmoMeshBoolean : public GLGizmoBase
{
@@ -87,7 +89,7 @@ private:
VolumeInfo m_src;
VolumeInfo m_tool;
void generate_new_volume(bool delete_input, const TriangleMesh& mesh_result);
void generate_new_volume(bool delete_input, TriangleMesh& mesh_result, const std::vector<std::optional<TriangleSelector::SavedPainting>>& saved_paintings);
};
} // namespace GUI