#ifndef slic3r_EmbossJob_hpp_ #define slic3r_EmbossJob_hpp_ #include #include #include #include #include #include // ExPolygonsWithIds #include "libslic3r/Point.hpp" // Transform3d #include "libslic3r/ObjectID.hpp" #include "slic3r/GUI/Camera.hpp" //#include "slic3r/GUI/TextLines.hpp" #include "slic3r/Utils/RaycastManager.hpp" #include "JobNew.hpp" namespace Slic3r { class TriangleMesh; class ModelVolume; class ModelObject; enum class ModelVolumeType : int; class BuildVolume; namespace GUI { //class Plater; class GLCanvas3D; class Worker; class Selection; namespace Emboss { class DataBase { public: DataBase(const std::string &volume_name, std::shared_ptr> cancel) : volume_name(volume_name), cancel(std::move(cancel)) {} DataBase(const std::string &volume_name, std::shared_ptr> cancel, EmbossShape &&shape) : volume_name(volume_name), cancel(std::move(cancel)), shape(std::move(shape)) {} DataBase(DataBase &&) = default; virtual ~DataBase() = default; /// /// Create shape /// e.g. Text extract glyphs from font /// Not 'const' function because it could modify shape /// virtual EmbossShape &create_shape() { return shape; }; /// /// Write data how to reconstruct shape to volume /// /// Data object for store emboss params virtual void write(ModelVolume &volume) const; // Define projection move // True (raised) .. move outside from surface (MODEL_PART) // False (engraved).. move into object (NEGATIVE_VOLUME) bool is_outside = true; // Define per letter projection on one text line // [optional] It is not used when empty Slic3r::Emboss::TextLines text_lines = {}; // [optional] Define distance for surface // It is used only for flat surface (not cutted) // Position of Zero(not set value) differ for MODEL_PART and NEGATIVE_VOLUME std::optional from_surface; // new volume name std::string volume_name; // flag that job is canceled // for time after process. std::shared_ptr> cancel; // shape to emboss EmbossShape shape; bool merge_shape{true}; }; struct DataCreateVolumeUtil : public DataBase // modfiy bu bbs //struct DataCreateVolume : public DataBase { // define embossed volume type ModelVolumeType volume_type; // parent ModelObject index where to create volume ObjectID object_id; // new created volume transformation Transform3d trmat; }; using DataBasePtr = std::unique_ptr; /// /// Hold neccessary data to update embossed text object in job /// struct DataUpdate { // Hold data about shape DataBasePtr base; // unique identifier of volume to change ObjectID volume_id; // Used for prevent flooding Undo/Redo stack on slider. bool make_snapshot; }; struct CreateVolumeParams { GLCanvas3D &canvas; // Direction of ray into scene const Camera &camera; // To put new object on the build volume const BuildVolume &build_volume; // used to emplace job for execution Worker &worker; // Contain AABB trees from scene typedef std::function register_mesh_pick; register_mesh_pick on_register_mesh_pick{nullptr}; RaycastManager &raycaster; RaycastManager::AllowVolumes& raycast_condition; // New created volume type ModelVolumeType volume_type; // Define which gizmo open on the success unsigned char gizmo_type; // GLGizmosManager::EType // Volume define object to add new volume const GLVolume *gl_volume; // Contain AABB trees from scene // RaycastManager &raycaster; // Wanted additionl move in Z(emboss) direction of new created volume std::optional distance = {}; // Wanted additionl rotation around Z of new created volume std::optional angle = {}; bool merge_shape{true}; }; struct DataCreateObject { // Hold data about shape DataBasePtr base; // define position on screen where to create object Vec2d screen_coor; // projection property const Camera &camera; // shape of bed in case of create volume on bed std::vector bed_shape; // Define which gizmo open on the success unsigned char gizmo_type; // additionl rotation around Z axe, given by style settings std::optional angle = {}; }; /// /// Hold neccessary data to create ModelVolume in job /// Volume is created on the surface of existing volume in object. /// NOTE: EmbossDataBase::font_file doesn't have to be valid !!! /// struct DataCreateVolume { // Hold data about shape DataBasePtr base; // define embossed volume type ModelVolumeType volume_type; // parent ModelObject index where to create volume ObjectID object_id; // new created volume transformation std::optional trmat; // Define which gizmo open on the success unsigned char gizmo_type; }; struct SurfaceVolumeData { // Transformation of volume inside of object Transform3d transform; struct ModelSource { // source volumes std::shared_ptr mesh; // Transformation of volume inside of object Transform3d tr; }; using ModelSources = std::vector; ModelSources sources; }; /// /// Hold neccessary data to update embossed text object in job /// struct UpdateSurfaceVolumeData : public DataUpdate, public SurfaceVolumeData {}; static bool was_canceled(const JobNew::Ctl &ctl, const DataBase &base); static bool exception_process(std::exception_ptr &eptr); static bool finalize(bool canceled, std::exception_ptr &eptr, const DataBase &input); /// /// Update text volume to use surface from object /// class UpdateSurfaceVolumeJob : public JobNew { UpdateSurfaceVolumeData m_input; TriangleMesh m_result; public: // move params to private variable explicit UpdateSurfaceVolumeJob(UpdateSurfaceVolumeData &&input); void process(Ctl &ctl) override; void finalize(bool canceled, std::exception_ptr &eptr) override; static bool is_use_surfae_error; }; /// /// Update text shape in existing text volume /// Predict that there is only one runnig(not canceled) instance of it /// class UpdateJob : public JobNew { DataUpdate m_input; TriangleMesh m_result; public: // move params to private variable explicit UpdateJob(DataUpdate &&input); /// /// Create new embossed volume by m_input data and store to m_result /// /// Control containing cancel flag void process(Ctl &ctl) override; /// /// Update volume - change object_id /// /// Was process canceled. /// NOTE: Be carefull it doesn't care about /// time between finished process and started finalize part. /// unused void finalize(bool canceled, std::exception_ptr &eptr) override; /// /// Update text volume /// /// Volume to be updated /// New Triangle mesh for volume /// Data to write into volume static void update_volume(ModelVolume *volume, TriangleMesh &&mesh, const DataBase &base); }; /// /// Create new TextObject on the platter /// Should not be stopped /// class CreateObjectJob : public JobNew { DataCreateObject m_input; TriangleMesh m_result; std::vector m_results; Transform3d m_transformation; public: explicit CreateObjectJob(DataCreateObject &&input); void process(Ctl &ctl) override; void finalize(bool canceled, std::exception_ptr &eptr) override; }; struct Texture { unsigned id{0}; unsigned width{0}; unsigned height{0}; }; /// /// Hold neccessary data to create(cut) volume from surface object in job /// struct CreateSurfaceVolumeData : public SurfaceVolumeData { // Hold data about shape DataBasePtr base; // define embossed volume type ModelVolumeType volume_type; // parent ModelObject index where to create volume ObjectID object_id; // Define which gizmo open on the success unsigned char gizmo_type; }; class CreateSurfaceVolumeJob : public JobNew { CreateSurfaceVolumeData m_input; TriangleMesh m_result; public: explicit CreateSurfaceVolumeJob(CreateSurfaceVolumeData &&input); void process(Ctl &ctl) override; void finalize(bool canceled, std::exception_ptr &eptr) override; }; class CreateVolumeJob : public JobNew { DataCreateVolume m_input; TriangleMesh m_result; public: explicit CreateVolumeJob(DataCreateVolume &&input); void process(Ctl &ctl) override; void finalize(bool canceled, std::exception_ptr &eptr) override; }; static bool check(unsigned char gizmo_type); static bool check(const DataBase &input, bool check_fontfile, bool use_surface = false); static bool check(const CreateVolumeParams &input); static bool check(const DataCreateObject &input); static bool check(const DataUpdate &input, bool is_main_thread = false, bool use_surface = false); static bool check(const CreateSurfaceVolumeData &input, bool is_main_thread = false); static bool check(const DataCreateVolume &input, bool is_main_thread = false); static bool check(const UpdateSurfaceVolumeData &input, bool is_main_thread = false); bool start_create_object_job(const CreateVolumeParams &input, DataBasePtr emboss_data, const Vec2d &coor); bool start_create_volume_without_position(CreateVolumeParams &input, DataBasePtr data); bool start_create_volume_job( Worker &worker, const ModelObject &object, const std::optional &volume_tr, DataBasePtr data, ModelVolumeType volume_type, unsigned char gizmo_type); bool start_create_volume_on_surface_job(CreateVolumeParams &input, DataBasePtr data, const Vec2d &mouse_pos); bool start_create_volume(CreateVolumeParams &input, DataBasePtr data, const Vec2d &mouse_pos); static ExPolygons create_shape(DataBase &input); static TriangleMesh create_mesh_per_glyph(DataBase &input); static TriangleMesh try_create_mesh(DataBase &input); static TriangleMesh create_mesh(DataBase &input); static std::vector create_meshs(DataBase &input); static indexed_triangle_set cut_surface_to_its(const ExPolygons &shapes, const Transform3d &tr, const SurfaceVolumeData::ModelSources &sources, DataBase &input); static TriangleMesh cut_per_glyph_surface(DataBase &input1, const SurfaceVolumeData &input2); static TriangleMesh cut_surface(DataBase &input1, const SurfaceVolumeData &input2); static void _update_volume(TriangleMesh &&mesh, const DataUpdate &data, const Transform3d *tr = nullptr); static void create_volume( TriangleMesh &&mesh, const ObjectID &object_id, const ModelVolumeType type, const std::optional &trmat, const DataBase &data, unsigned char gizmo_type); /// Update text volume /// /// Volume to be updated /// New Triangle mesh for volume /// Data to write into volume bool start_update_volume(DataUpdate &&data, const ModelVolume &volume, const Selection &selection, RaycastManager &raycaster); /// /// Copied triangles from object to be able create mesh for cut surface from /// /// Define embossed volume /// Source data for cut surface from SurfaceVolumeData::ModelSources create_volume_sources(const ModelVolume &volume); /// /// Copied triangles from object to be able create mesh for cut surface from /// /// Source object volumes for cut surface from /// Source volume id /// Source data for cut surface from SurfaceVolumeData::ModelSources create_sources(const ModelVolumePtrs &volumes, std::optional text_volume_id = {}); } } // namespace Slic3r::GUI } // namespace Slic3r #endif // slic3r_EmbossJob_hpp_