#ifndef slic3r_TextureDisplacementBakeJob_hpp_ #define slic3r_TextureDisplacementBakeJob_hpp_ #include #include #include #include "libslic3r/Point.hpp" #include #include "libslic3r/ObjectID.hpp" #include "libslic3r/TextureDisplacement.hpp" #include "libslic3r/TriangleMesh.hpp" #include "libslic3r/TriangleSelector.hpp" #include "Job.hpp" namespace Slic3r { class ModelVolume; } namespace Slic3r::GUI { // Everything process() needs, captured by value on the main thread when the job is queued so the // worker thread never touches the live Model concurrently with the UI (mirrors how EmbossJob's // DataBase is captured before process() runs). struct TextureDisplacementBakeInput { ObjectID volume_id; indexed_triangle_set base_mesh; std::vector layers; TextureDisplacementFacetsData facets_data; TextureDisplacementOptions options; // Mesh coordinates -> world millimetres. Captured here with everything else so the worker never // reaches back into the live Model for it. See build_texture_displacement(). Transform3d volume_to_world = Transform3d::Identity(); // Captured on the main thread. Empty unless some layer is colouring, in which case the bake also // writes the volume's mmu_segmentation_facets - the same per-triangle filament assignment the MMU // paint gizmo writes - alongside the displaced geometry. TextureColorSettings color; // The colour already painted on the volume, indexed against `base_mesh`. Carried here rather than // read at commit time because the one-run pipeline rebuilds the mesh, and bringing this across to // the new topology is spatial work (see process()) that has no business on the UI thread. TriangleSelector::TriangleSplittingData mmu_segmentation; // What `mmu_segmentation` was taken from, so the commit can tell whether the volume was painted // while the bake ran and fall back to the live data if it was. ObjectBase::Timestamp mmu_segmentation_timestamp = 0; // Whether this job pushes its own undo step when it commits. False when the caller has already // taken one that is meant to cover the displacement as well - Standard mode's Bake, which remeshes // and subdivides first and has to undo as a single action. bool take_snapshot = true; }; // Bakes a volume's painted texture-displacement layers into real mesh geometry in the background, // then commits the result on the main thread - mirrors EmbossJob's UpdateJob/update_volume() // bake-and-commit pattern (see EmbossJob.cpp). class TextureDisplacementBakeJob : public Job { public: TextureDisplacementBakeJob(TextureDisplacementBakeInput &&input, std::function on_finished); void process(Ctl &ctl) override; void finalize(bool canceled, std::exception_ptr &eptr) override; private: TextureDisplacementBakeInput m_input; TriangleMesh m_result; // What the bake spent, for the message it leaves behind when the budget capped the detail. TextureBakeStats m_stats; // Per triangle of m_result: the palette entry to print it in, as its index + 1 (0 = leave alone). // Empty unless a layer asked for colour. See TextureColorRequest; finalize() turns these into // filaments. std::vector m_triangle_color; // m_input.mmu_segmentation brought onto m_result's topology, so finalize() can lay this bake's // colour over the colour that was already there. Indexed against m_result, not base_mesh. TriangleSelector::TriangleSplittingData m_carried_mmu; std::function m_on_finished; }; // Captures `volume`'s current mesh/layers/paint data and queues a TextureDisplacementBakeJob on // the app's UI job worker. `on_finished` is always called once the job settles (success, failure, // or cancellation), so the caller can clear its own "bake in progress" UI state. Must be called // from the main thread. void queue_texture_displacement_bake(const ModelVolume &volume, const TextureColorSettings &color, std::function on_finished, bool take_snapshot = true); } // namespace Slic3r::GUI #endif // slic3r_TextureDisplacementBakeJob_hpp_