mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-06 15:21:09 +00:00
114 lines
4.9 KiB
C++
114 lines
4.9 KiB
C++
#include "TextureDisplacementDebugJob.hpp"
|
|
|
|
#include "libslic3r/Model.hpp"
|
|
|
|
#include "slic3r/GUI/GUI_App.hpp"
|
|
#include "slic3r/GUI/Gizmos/GLGizmoTextureDisplacement.hpp"
|
|
#include "slic3r/GUI/I18N.hpp"
|
|
#include "slic3r/GUI/Plater.hpp"
|
|
|
|
namespace Slic3r::GUI {
|
|
|
|
TextureDisplacementDebugJob::TextureDisplacementDebugJob(
|
|
TextureDisplacementDebugInput &&input, std::function<void(std::vector<BakeStageSnapshot>)> on_finished)
|
|
: m_input(std::move(input)), m_on_finished(std::move(on_finished))
|
|
{
|
|
}
|
|
|
|
void TextureDisplacementDebugJob::process(Ctl &ctl)
|
|
{
|
|
const std::string status = _u8L("Capturing bake stages");
|
|
ctl.update_status(1, status);
|
|
|
|
// Only ever touches m_input (captured by value before this job was queued) and local state - and,
|
|
// unlike the bake job, never writes anything back either.
|
|
int last_reported = 1;
|
|
const auto report = [&ctl, &status, &last_reported](int percent) {
|
|
if (ctl.was_canceled())
|
|
return false;
|
|
if (percent > last_reported) {
|
|
last_reported = percent;
|
|
ctl.update_status(percent, status);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
BakeStageRecorder recorder;
|
|
recorder.enable(true);
|
|
recorder.set_check_topology(m_input.check_topology);
|
|
recorder.set_mesh_cap(m_input.mesh_cap);
|
|
|
|
indexed_triangle_set mesh = m_input.base_mesh;
|
|
TextureDisplacementFacetsData masks = m_input.facets_data;
|
|
|
|
// The default pipeline can only move vertices the mesh already has, so its recipe starts with the
|
|
// preparation - which is where "first it remeshes, then it refines" actually happens. The
|
|
// experimental pipeline refines as part of the bake and has nothing to prepare.
|
|
if (m_input.run_prepare && !m_input.options.pipeline_v2) {
|
|
const TextureDisplacementPrepareResult prepared =
|
|
GLGizmoTextureDisplacement::prepare_mesh(mesh, masks, m_input.layers, m_input.prepare_params,
|
|
m_input.color.palette,
|
|
// Preparation is roughly half the run; the bake
|
|
// takes the progress bar from there.
|
|
[&report](int pct) { return report(1 + pct / 2); },
|
|
&recorder);
|
|
if (ctl.was_canceled())
|
|
return;
|
|
// An empty result means nothing needed doing, which is not a failure - the bake below simply
|
|
// runs on the mesh as it stands. paint_lost means the remesh dropped every layer's paint, so
|
|
// there is nothing left to displace and the stages recorded so far are the whole story.
|
|
if (prepared.paint_lost) {
|
|
m_stages = recorder.take();
|
|
ctl.update_status(100, status);
|
|
return;
|
|
}
|
|
if (!prepared.mesh.indices.empty()) {
|
|
mesh = prepared.mesh;
|
|
masks = prepared.masks;
|
|
}
|
|
}
|
|
|
|
build_texture_displacement(mesh, m_input.layers, masks, m_input.options,
|
|
[&report](int pct) { return report(50 + pct / 2); },
|
|
/* color */ nullptr, m_input.volume_to_world, &recorder);
|
|
|
|
m_stages = recorder.take();
|
|
ctl.update_status(100, status); // always finish at 100: this is what closes the notification
|
|
}
|
|
|
|
void TextureDisplacementDebugJob::finalize(bool canceled, std::exception_ptr &eptr)
|
|
{
|
|
if (!m_on_finished)
|
|
return;
|
|
// The handler must run on every outcome - the caller uses it to clear its in-progress latch, and
|
|
// an empty vector is its signal that nothing usable came back.
|
|
if (canceled || eptr)
|
|
m_on_finished({});
|
|
else
|
|
m_on_finished(std::move(m_stages));
|
|
}
|
|
|
|
void queue_texture_displacement_debug(const ModelVolume &volume, const TextureColorSettings &color,
|
|
const TextureDisplacementPrepareParams &prepare_params,
|
|
bool run_prepare, bool check_topology,
|
|
std::function<void(std::vector<BakeStageSnapshot>)> on_finished)
|
|
{
|
|
TextureDisplacementDebugInput input;
|
|
input.volume_id = volume.id();
|
|
input.base_mesh = volume.mesh().its;
|
|
input.layers = volume.texture_displacement_layers;
|
|
input.options = volume.texture_displacement_options;
|
|
input.prepare_params = prepare_params;
|
|
input.run_prepare = run_prepare;
|
|
input.check_topology = check_topology;
|
|
input.color = color;
|
|
input.volume_to_world = texture_displacement_volume_to_world(volume);
|
|
for (int i = 0; i < int(TEXTURE_DISPLACEMENT_MAX_LAYERS); ++i)
|
|
input.facets_data[size_t(i)] = volume.texture_displacement_facet(i).get_data();
|
|
|
|
auto &worker = wxGetApp().plater()->get_ui_job_worker();
|
|
queue_job(worker, std::make_unique<TextureDisplacementDebugJob>(std::move(input), std::move(on_finished)));
|
|
}
|
|
|
|
} // namespace Slic3r::GUI
|