Remap paint after repair model

This commit is contained in:
Noisyfox
2026-05-10 18:27:02 +08:00
parent d5f964ee4f
commit 1299fcef4a
4 changed files with 25 additions and 9 deletions

View File

@@ -13,6 +13,7 @@
#include "libslic3r/MeshBoolean.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/format.hpp"
#include "libslic3r/Thread.hpp"
#include "../GUI/I18N.hpp"
// Orca: This file provides utilities for repairing 3D model meshes using the CGAL library, handling mesh splitting, merging, and boolean operations.
@@ -66,7 +67,7 @@ public:
// Orca: Main function to repair model objects using CGAL, with progress dialog and cancellation support.
// Returns false if fixing was canceled. fix_result contains error message if failed.
bool fix_model_with_cgal_gui(ModelObject &model_object, int volume_idx, GUI::ProgressDialog &progress_dialog, const wxString &msg_header, std::string &fix_result)
bool fix_model_with_cgal_gui(ModelObject &model_object, int volume_idx, GUI::ProgressDialog &progress_dialog, const wxString &msg_header, std::string &fix_result, bool keep_painting)
{
// Orca: Synchronization primitives for progress updates between worker thread and GUI.
std::mutex mtx;
@@ -94,8 +95,10 @@ bool fix_model_with_cgal_gui(ModelObject &model_object, int volume_idx, GUI::Pro
};
// Orca: Worker thread that performs the actual model repair operations.
auto worker_thread = std::thread([&model_object, volume_idx, &ivolume, on_progress, &success, &canceled, &finished, &fix_result]() {
auto worker_thread = std::thread([&model_object, volume_idx, &ivolume, on_progress, &success, &canceled, &finished, &fix_result, keep_painting]() {
try {
set_current_thread_name("cgal_fix_model");
size_t start_volume = volume_idx == -1 ? 0 : size_t(volume_idx);
size_t end_volume = volume_idx == -1 ? std::numeric_limits<size_t>::max() : size_t(volume_idx);
@@ -112,7 +115,7 @@ bool fix_model_with_cgal_gui(ModelObject &model_object, int volume_idx, GUI::Pro
// Orca: Split splittable volumes into parts for individual processing.
size_t parts_count = 1;
if (volume->is_splittable()) {
parts_count = volume->split(1, false); // TODO: fix this
parts_count = volume->split(1, keep_painting);
if (parts_count > 1) {
const std::string msg = Slic3r::format(L("Split into %1% parts"), parts_count);
on_progress(msg.c_str(), 10);
@@ -150,6 +153,12 @@ bool fix_model_with_cgal_gui(ModelObject &model_object, int volume_idx, GUI::Pro
ModelVolume *part_volume = model_object.volumes[part_idx];
TriangleMesh mesh = part_volume->mesh();
if (its_num_open_edges(mesh.its) != 0) {
// Save painting for later remap
const std::optional<TriangleSelector::SavedPainting> saved_painting = keep_painting ?
part_volume->save_painting() :
std::optional<TriangleSelector::SavedPainting>{};
std::string error;
if (!MeshBoolean::cgal::repair(mesh, nullptr, &error))
throw Slic3r::RuntimeError(error.empty() ? L("Repair failed") : error.c_str());
@@ -158,6 +167,9 @@ bool fix_model_with_cgal_gui(ModelObject &model_object, int volume_idx, GUI::Pro
part_volume->calculate_convex_hull();
part_volume->invalidate_convex_hull_2d();
part_volume->set_new_unique_id();
// Remap paint back
part_volume->restore_painting(saved_painting);
}
}