mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 05:15:59 +08:00
Emboss on thread - partialy - test for linux
This commit is contained in:
parent
378d8af7ac
commit
f16648bd3a
@ -178,6 +178,8 @@ set(SLIC3R_GUI_SOURCES
|
|||||||
GUI/Jobs/PlaterJob.cpp
|
GUI/Jobs/PlaterJob.cpp
|
||||||
GUI/Jobs/ArrangeJob.hpp
|
GUI/Jobs/ArrangeJob.hpp
|
||||||
GUI/Jobs/ArrangeJob.cpp
|
GUI/Jobs/ArrangeJob.cpp
|
||||||
|
GUI/Jobs/EmbossJob.cpp
|
||||||
|
GUI/Jobs/EmbossJob.hpp
|
||||||
GUI/Jobs/RotoptimizeJob.hpp
|
GUI/Jobs/RotoptimizeJob.hpp
|
||||||
GUI/Jobs/RotoptimizeJob.cpp
|
GUI/Jobs/RotoptimizeJob.cpp
|
||||||
GUI/Jobs/FillBedJob.hpp
|
GUI/Jobs/FillBedJob.hpp
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "slic3r/GUI/MsgDialog.hpp"
|
#include "slic3r/GUI/MsgDialog.hpp"
|
||||||
#include "slic3r/GUI/format.hpp"
|
#include "slic3r/GUI/format.hpp"
|
||||||
#include "slic3r/GUI/CameraUtils.hpp"
|
#include "slic3r/GUI/CameraUtils.hpp"
|
||||||
|
#include "slic3r/GUI/Jobs/EmbossJob.hpp"
|
||||||
|
#include "slic3r/GUI/Jobs/NotificationProgressIndicator.hpp"
|
||||||
|
|
||||||
// TODO: remove include
|
// TODO: remove include
|
||||||
#include "libslic3r/SVG.hpp" // debug store
|
#include "libslic3r/SVG.hpp" // debug store
|
||||||
@ -184,7 +186,9 @@ public:
|
|||||||
return std::string(fullFileName.c_str());
|
return std::string(fullFileName.c_str());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
@ -193,12 +197,15 @@ using namespace Slic3r::GUI;
|
|||||||
GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
|
GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
|
||||||
: GLGizmoBase(parent, M_ICON_FILENAME, -2)
|
: GLGizmoBase(parent, M_ICON_FILENAME, -2)
|
||||||
, m_font_selected(0)
|
, m_font_selected(0)
|
||||||
|
, m_font(nullptr)
|
||||||
, m_volume(nullptr)
|
, m_volume(nullptr)
|
||||||
, m_exist_notification(false)
|
, m_exist_notification(false)
|
||||||
, m_is_initialized(false) // initialize on first opening gizmo
|
, m_is_initialized(false) // initialize on first opening gizmo
|
||||||
|
, m_job(std::make_unique<EmbossJob>())
|
||||||
{
|
{
|
||||||
// TODO: add suggestion to use https://fontawesome.com/
|
// TODO: add suggestion to use https://fontawesome.com/
|
||||||
// (copy & paste) unicode symbols from web
|
// (copy & paste) unicode symbols from web
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLGizmoEmboss::~GLGizmoEmboss() {}
|
GLGizmoEmboss::~GLGizmoEmboss() {}
|
||||||
@ -261,7 +268,6 @@ void GLGizmoEmboss::set_volume_type(ModelVolumeType volume_type)
|
|||||||
{
|
{
|
||||||
if (m_volume == nullptr) return;
|
if (m_volume == nullptr) return;
|
||||||
m_volume->set_type(volume_type);
|
m_volume->set_type(volume_type);
|
||||||
refresh_object_list();
|
|
||||||
m_parent.reload_scene(true);
|
m_parent.reload_scene(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +466,24 @@ ModelVolume *GLGizmoEmboss::get_selected_volume(const Selection &selection,
|
|||||||
bool GLGizmoEmboss::process()
|
bool GLGizmoEmboss::process()
|
||||||
{
|
{
|
||||||
// exist loaded font?
|
// exist loaded font?
|
||||||
if (!m_font.has_value()) return false;
|
if (m_font == nullptr) return false;
|
||||||
|
|
||||||
|
|
||||||
|
EmbossJob::Data data;
|
||||||
|
data.font = m_font;
|
||||||
|
data.text_configuration = create_configuration();
|
||||||
|
data.volume_name = create_volume_name();
|
||||||
|
data.volume_ptr = m_volume;
|
||||||
|
|
||||||
|
const Selection &selection = m_parent.get_selection();
|
||||||
|
if (!selection.is_empty() && selection.get_object_idx() >= 0) {
|
||||||
|
int object_idx = selection.get_object_idx();
|
||||||
|
Model &model = wxGetApp().plater()->model();
|
||||||
|
data.object_ptr = model.objects[object_idx];
|
||||||
|
}
|
||||||
|
m_job->restart(data);
|
||||||
|
return true;
|
||||||
|
|
||||||
ExPolygons shapes = Emboss::text2shapes(*m_font, m_text.c_str(), m_font_prop);
|
ExPolygons shapes = Emboss::text2shapes(*m_font, m_text.c_str(), m_font_prop);
|
||||||
// exist 2d shape made by text ?
|
// exist 2d shape made by text ?
|
||||||
// (no shape means that font doesnt have any of text symbols)
|
// (no shape means that font doesnt have any of text symbols)
|
||||||
@ -488,7 +511,7 @@ bool GLGizmoEmboss::add_volume(const std::string & name,
|
|||||||
|
|
||||||
GUI_App &app = wxGetApp();
|
GUI_App &app = wxGetApp();
|
||||||
Plater * plater = app.plater();
|
Plater * plater = app.plater();
|
||||||
plater->take_snapshot(_L("Add") + " " + name);
|
plater->take_snapshot(_L("Emboss text") + ": " + name);
|
||||||
if (m_volume == nullptr) {
|
if (m_volume == nullptr) {
|
||||||
// decide to add as volume or new object
|
// decide to add as volume or new object
|
||||||
const Selection &selection = m_parent.get_selection();
|
const Selection &selection = m_parent.get_selection();
|
||||||
@ -498,25 +521,28 @@ bool GLGizmoEmboss::add_volume(const std::string & name,
|
|||||||
app.obj_list()->load_mesh_object(tm, name, true, &text_configuration);
|
app.obj_list()->load_mesh_object(tm, name, true, &text_configuration);
|
||||||
app.mainframe->update_title();
|
app.mainframe->update_title();
|
||||||
|
|
||||||
// load mesh cause close gizmo, soo I open it again
|
// load mesh cause close gizmo, on windows but not on linux
|
||||||
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::EType::Emboss);
|
// Open gizmo again when it is closed
|
||||||
|
GLGizmosManager& mng = m_parent.get_gizmos_manager();
|
||||||
|
if (mng.get_current_type() != GLGizmosManager::Emboss)
|
||||||
|
mng.open_gizmo(GLGizmosManager::Emboss);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// create new volume inside of object
|
// create new volume inside of object
|
||||||
int object_idx = selection.get_object_idx();
|
int object_idx = selection.get_object_idx();
|
||||||
ModelObject *obj = plater->model().objects[object_idx];
|
ModelObject *obj = plater->model().objects[object_idx];
|
||||||
m_volume = obj->add_volume(std::move(tm));
|
m_volume = obj->add_volume(std::move(tm));
|
||||||
|
// set a default extruder value, since user can't add it manually
|
||||||
|
m_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// update volume
|
||||||
m_volume->set_mesh(std::move(tm));
|
m_volume->set_mesh(std::move(tm));
|
||||||
m_volume->set_new_unique_id();
|
m_volume->set_new_unique_id();
|
||||||
m_volume->calculate_convex_hull();
|
m_volume->calculate_convex_hull();
|
||||||
m_volume->get_object()->invalidate_bounding_box();
|
m_volume->get_object()->invalidate_bounding_box();
|
||||||
}
|
}
|
||||||
m_volume->name = name;
|
m_volume->name = name;
|
||||||
|
|
||||||
// set a default extruder value, since user can't add it manually
|
|
||||||
m_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
|
||||||
m_volume->text_configuration = create_configuration();
|
m_volume->text_configuration = create_configuration();
|
||||||
|
|
||||||
// update volume name in object list
|
// update volume name in object list
|
||||||
@ -543,7 +569,7 @@ void GLGizmoEmboss::draw_window()
|
|||||||
bool loaded = load_font(font_index);
|
bool loaded = load_font(font_index);
|
||||||
}
|
}
|
||||||
#endif // ALLOW_DEBUG_MODE
|
#endif // ALLOW_DEBUG_MODE
|
||||||
if (!m_font.has_value()) {
|
if (m_font == nullptr) {
|
||||||
ImGui::Text(_u8L("Warning: No font is selected. Select correct one.").c_str());
|
ImGui::Text(_u8L("Warning: No font is selected. Select correct one.").c_str());
|
||||||
}
|
}
|
||||||
draw_font_list();
|
draw_font_list();
|
||||||
@ -562,7 +588,7 @@ void GLGizmoEmboss::draw_window()
|
|||||||
if (ImGui::Button(_u8L("Close").c_str())) close();
|
if (ImGui::Button(_u8L("Close").c_str())) close();
|
||||||
|
|
||||||
// Option to create text volume when reselecting volumes
|
// Option to create text volume when reselecting volumes
|
||||||
m_imgui->disabled_begin(!m_font.has_value());
|
m_imgui->disabled_begin(m_font == nullptr);
|
||||||
if (m_volume == nullptr) {
|
if (m_volume == nullptr) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::Button(_u8L("Generate preview").c_str())) process();
|
if (ImGui::Button(_u8L("Generate preview").c_str())) process();
|
||||||
@ -694,7 +720,7 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
load_imgui_font();
|
load_imgui_font();
|
||||||
if (m_font.has_value()) m_font->cache.clear();
|
if (m_font != nullptr) m_font->cache.clear();
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
||||||
@ -710,7 +736,7 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
process();
|
process();
|
||||||
|
|
||||||
// when more collection add selector
|
// when more collection add selector
|
||||||
if (m_font.has_value() && m_font->count > 1) {
|
if (m_font != nullptr && m_font->count > 1) {
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
||||||
if (ImGui::BeginCombo(_u8L("Font collection").c_str(),
|
if (ImGui::BeginCombo(_u8L("Font collection").c_str(),
|
||||||
std::to_string(m_font->index).c_str())) {
|
std::to_string(m_font->index).c_str())) {
|
||||||
@ -789,19 +815,23 @@ bool GLGizmoEmboss::create_default_model_object()
|
|||||||
void GLGizmoEmboss::refresh_object_list()
|
void GLGizmoEmboss::refresh_object_list()
|
||||||
{
|
{
|
||||||
const Selection &selection = m_parent.get_selection();
|
const Selection &selection = m_parent.get_selection();
|
||||||
if (selection.is_empty() || selection.get_object_idx() < 0 ||
|
if (selection.is_empty() ||
|
||||||
|
selection.get_object_idx() < 0 ||
|
||||||
m_volume == nullptr)
|
m_volume == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ObjectList * obj_list = wxGetApp().obj_list();
|
ObjectList * obj_list = wxGetApp().obj_list();
|
||||||
ModelVolume *volume = m_volume; // copy for lambda
|
ModelVolume *volume = m_volume; // copy for lambda
|
||||||
auto add_to_selection = [volume](const ModelVolume *vol) {
|
|
||||||
return vol == volume;
|
// select only actual volume
|
||||||
};
|
// when new volume is created change selection to this volume
|
||||||
wxDataViewItemArray sel =
|
auto add_to_selection = [volume](const ModelVolume *vol) { return vol == volume;};
|
||||||
obj_list->reorder_volumes_and_get_selection(selection.get_object_idx(),
|
wxDataViewItemArray sel = obj_list->reorder_volumes_and_get_selection(
|
||||||
add_to_selection);
|
selection.get_object_idx(), add_to_selection);
|
||||||
if (!sel.IsEmpty()) obj_list->select_item(sel.front());
|
|
||||||
|
if (!sel.IsEmpty())
|
||||||
|
obj_list->select_item(sel.front());
|
||||||
|
|
||||||
obj_list->selection_changed();
|
obj_list->selection_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,7 +854,8 @@ bool GLGizmoEmboss::load_font()
|
|||||||
std::optional<Emboss::Font> font_opt = Emboss::load_font(
|
std::optional<Emboss::Font> font_opt = Emboss::load_font(
|
||||||
fi.path.c_str());
|
fi.path.c_str());
|
||||||
if (!font_opt.has_value()) return false;
|
if (!font_opt.has_value()) return false;
|
||||||
m_font = font_opt;
|
// TODO: fix copy of font data
|
||||||
|
m_font = std::make_shared<Emboss::Font>(std::move(*font_opt));
|
||||||
load_imgui_font();
|
load_imgui_font();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -842,7 +873,8 @@ bool GLGizmoEmboss::load_font(const wxFont &font)
|
|||||||
{
|
{
|
||||||
auto font_opt = WxFontUtils::load_font(font);
|
auto font_opt = WxFontUtils::load_font(font);
|
||||||
if (!font_opt.has_value()) return false;
|
if (!font_opt.has_value()) return false;
|
||||||
m_font = font_opt;
|
// TODO: fix copy of font data
|
||||||
|
m_font = std::make_shared<Emboss::Font>(std::move(*font_opt));
|
||||||
WxFontUtils::update_property(m_font_prop, font);
|
WxFontUtils::update_property(m_font_prop, font);
|
||||||
m_font_prop.emboss = m_font_prop.size_in_mm / 2.f;
|
m_font_prop.emboss = m_font_prop.size_in_mm / 2.f;
|
||||||
load_imgui_font();
|
load_imgui_font();
|
||||||
@ -888,7 +920,7 @@ void GLGizmoEmboss::check_imgui_font_range()
|
|||||||
|
|
||||||
void GLGizmoEmboss::load_imgui_font()
|
void GLGizmoEmboss::load_imgui_font()
|
||||||
{
|
{
|
||||||
if (!m_font.has_value()) return;
|
if (m_font == nullptr) return;
|
||||||
|
|
||||||
ImFontGlyphRangesBuilder builder;
|
ImFontGlyphRangesBuilder builder;
|
||||||
builder.AddRanges(m_imgui->get_glyph_ranges());
|
builder.AddRanges(m_imgui->get_glyph_ranges());
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "libslic3r/Emboss.hpp"
|
#include "libslic3r/Emboss.hpp"
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
@ -20,6 +21,8 @@
|
|||||||
class wxFont;
|
class wxFont;
|
||||||
namespace Slic3r{class AppConfig;}
|
namespace Slic3r{class AppConfig;}
|
||||||
namespace Slic3r::GUI {
|
namespace Slic3r::GUI {
|
||||||
|
class EmbossJob;
|
||||||
|
|
||||||
class GLGizmoEmboss : public GLGizmoBase
|
class GLGizmoEmboss : public GLGizmoBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -115,21 +118,13 @@ private:
|
|||||||
FontList m_font_list;
|
FontList m_font_list;
|
||||||
size_t m_font_selected;// index to m_font_list
|
size_t m_font_selected;// index to m_font_list
|
||||||
|
|
||||||
std::optional<Emboss::Font> m_font;
|
// to share data with job thread
|
||||||
|
std::shared_ptr<Emboss::Font> m_font;
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
|
|
||||||
FontProp m_font_prop;
|
FontProp m_font_prop;
|
||||||
|
|
||||||
// text position
|
// thread to process object on change text
|
||||||
struct Orientation
|
std::unique_ptr<EmbossJob> m_job;
|
||||||
{
|
|
||||||
Vec3f origin = Vec3f(0.f, 0.f, 0.f);
|
|
||||||
Vec3f normal = Vec3f(0.f, 0.f, 1.f);
|
|
||||||
Vec3f up = Vec3f(0.f, 1.f, 0.f);
|
|
||||||
Orientation() = default;
|
|
||||||
};
|
|
||||||
Orientation m_orientation;
|
|
||||||
|
|
||||||
// actual volume
|
// actual volume
|
||||||
ModelVolume *m_volume;
|
ModelVolume *m_volume;
|
||||||
|
160
src/slic3r/GUI/Jobs/EmbossJob.cpp
Normal file
160
src/slic3r/GUI/Jobs/EmbossJob.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#include "EmbossJob.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/Model.hpp"
|
||||||
|
|
||||||
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_ObjectList.hpp"
|
||||||
|
#include "slic3r/GUI/MainFrame.hpp"
|
||||||
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
|
|
||||||
|
using namespace Slic3r;
|
||||||
|
using namespace GUI;
|
||||||
|
|
||||||
|
//EmbossJob::EmbossJob(): Job(std::make_shared<NotificationProgressIndicator>(wxGetApp().plater()->get_notification_manager())){}
|
||||||
|
EmbossJob::EmbossJob() : Job(std::make_shared<EmbossJob::Progress>()) {}
|
||||||
|
|
||||||
|
void EmbossJob::restart(const Data &data)
|
||||||
|
{
|
||||||
|
if (Job::is_running()) {
|
||||||
|
std::lock_guard lk(m_mutex);
|
||||||
|
bool create_restart = !m_data_next.has_value();
|
||||||
|
m_data_next = data; // copy
|
||||||
|
if (create_restart) {
|
||||||
|
if (m_restart_thread.joinable()) m_restart_thread.join();
|
||||||
|
m_restart_thread = std::thread([this]() {
|
||||||
|
Job::cancel();
|
||||||
|
Job::join();
|
||||||
|
std::lock_guard lk(m_mutex);
|
||||||
|
m_data = std::move(m_data_next);
|
||||||
|
|
||||||
|
// after move optional, data is UNDEFINED
|
||||||
|
m_data_next = {};
|
||||||
|
Job::start();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_data = data; // copy
|
||||||
|
Job::start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void EmbossJob::prepare() {}
|
||||||
|
|
||||||
|
void EmbossJob::process() {
|
||||||
|
// check if data was set
|
||||||
|
if (!m_data.has_value()) return;
|
||||||
|
// check if exist valid font
|
||||||
|
if (m_data->font == nullptr) return;
|
||||||
|
|
||||||
|
// Do NOT process empty string
|
||||||
|
const TextConfiguration &cfg = m_data->text_configuration;
|
||||||
|
const std::string &text = cfg.text;
|
||||||
|
if (text.empty()) return;
|
||||||
|
|
||||||
|
const FontProp &prop = cfg.font_prop;
|
||||||
|
ExPolygons shapes = Emboss::text2shapes(*m_data->font, text.c_str(), prop);
|
||||||
|
|
||||||
|
// exist 2d shape made by text ?
|
||||||
|
// (no shape means that font hasn't any of text symbols)
|
||||||
|
if (shapes.empty()) return;
|
||||||
|
|
||||||
|
float scale = prop.size_in_mm / m_data->font->ascent;
|
||||||
|
auto project = std::make_unique<Emboss::ProjectScale>(
|
||||||
|
std::make_unique<Emboss::ProjectZ>(prop.emboss / scale), scale);
|
||||||
|
|
||||||
|
indexed_triangle_set its = Emboss::polygons2model(shapes, *project);
|
||||||
|
|
||||||
|
// for sure that some object is created from shape
|
||||||
|
if (its.indices.empty()) return;
|
||||||
|
m_result = its;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmbossJob::finalize() {
|
||||||
|
// check result was created
|
||||||
|
if (!m_result.has_value()) return;
|
||||||
|
if (m_result->indices.empty()) return;
|
||||||
|
// move object data
|
||||||
|
TriangleMesh tm(std::move(*m_result));
|
||||||
|
m_result = {};
|
||||||
|
|
||||||
|
// center triangle mesh
|
||||||
|
Vec3d shift = tm.bounding_box().center();
|
||||||
|
tm.translate(-shift.cast<float>());
|
||||||
|
|
||||||
|
GUI_App &app = wxGetApp();
|
||||||
|
Plater * plater = app.plater();
|
||||||
|
GLCanvas3D *canvas = plater->canvas3D();
|
||||||
|
std::string name = m_data->volume_name;
|
||||||
|
|
||||||
|
|
||||||
|
plater->take_snapshot(_L("Emboss text") + ": " + name);
|
||||||
|
ModelVolume *volume = m_data->volume_ptr;
|
||||||
|
if (volume == nullptr) {
|
||||||
|
// decide to add as volume or new object
|
||||||
|
if (m_data->object_ptr == nullptr) {
|
||||||
|
// create new object
|
||||||
|
app.obj_list()->load_mesh_object(tm, name, true, &m_data->text_configuration);
|
||||||
|
app.mainframe->update_title();
|
||||||
|
|
||||||
|
// TODO: find Why ???
|
||||||
|
// load mesh cause close gizmo, on windows but not on linux
|
||||||
|
// Open gizmo again when it is closed
|
||||||
|
GLGizmosManager &mng = canvas->get_gizmos_manager();
|
||||||
|
if (mng.get_current_type() != GLGizmosManager::Emboss)
|
||||||
|
mng.open_gizmo(GLGizmosManager::Emboss);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// create new volume inside of object
|
||||||
|
ModelObject *obj = m_data->object_ptr;
|
||||||
|
volume = obj->add_volume(std::move(tm));
|
||||||
|
|
||||||
|
// set a default extruder value, since user can't add it manually
|
||||||
|
volume->config.set_key_value("extruder", new ConfigOptionInt(0));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// update volume
|
||||||
|
volume->set_mesh(std::move(tm));
|
||||||
|
volume->set_new_unique_id();
|
||||||
|
volume->calculate_convex_hull();
|
||||||
|
volume->get_object()->invalidate_bounding_box();
|
||||||
|
}
|
||||||
|
|
||||||
|
volume->name = name;
|
||||||
|
volume->text_configuration = m_data->text_configuration;
|
||||||
|
|
||||||
|
// update volume name in object list
|
||||||
|
select_volume(volume);
|
||||||
|
|
||||||
|
//ObjectList *obj_list = wxGetApp().obj_list();
|
||||||
|
//obj_list->selection_changed();
|
||||||
|
|
||||||
|
// after applied another font notification is no more valid
|
||||||
|
//remove_notification_not_valid_font();
|
||||||
|
|
||||||
|
// Job promiss to refresh is not working
|
||||||
|
canvas->reload_scene(true);
|
||||||
|
|
||||||
|
// set data to model
|
||||||
|
Job::finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmbossJob::select_volume(ModelVolume *volume)
|
||||||
|
{
|
||||||
|
if (volume == nullptr) return;
|
||||||
|
|
||||||
|
ObjectList * obj_list = wxGetApp().obj_list();
|
||||||
|
|
||||||
|
// select only actual volume
|
||||||
|
// when new volume is created change selection to this volume
|
||||||
|
auto add_to_selection = [volume](const ModelVolume *vol) {
|
||||||
|
return vol == volume;
|
||||||
|
};
|
||||||
|
const Selection &selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||||
|
wxDataViewItemArray sel =
|
||||||
|
obj_list->reorder_volumes_and_get_selection(selection.get_object_idx(),
|
||||||
|
add_to_selection);
|
||||||
|
|
||||||
|
if (!sel.IsEmpty()) obj_list->select_item(sel.front());
|
||||||
|
obj_list->selection_changed();
|
||||||
|
}
|
67
src/slic3r/GUI/Jobs/EmbossJob.hpp
Normal file
67
src/slic3r/GUI/Jobs/EmbossJob.hpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#ifndef slic3r_EmbossJob_hpp_
|
||||||
|
#define slic3r_EmbossJob_hpp_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "Job.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/Emboss.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
class ModelVolume;
|
||||||
|
class ModelObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Slic3r::GUI {
|
||||||
|
|
||||||
|
// thread process of conversion from text to model
|
||||||
|
// [optionaly] union with model
|
||||||
|
class EmbossJob : protected Job
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
std::shared_ptr<Emboss::Font> font;
|
||||||
|
TextConfiguration text_configuration;
|
||||||
|
std::string volume_name;
|
||||||
|
// when nulltrp new volume will be created
|
||||||
|
ModelVolume *volume_ptr;
|
||||||
|
// when nullptr volume is created in new object
|
||||||
|
ModelObject *object_ptr;
|
||||||
|
};
|
||||||
|
EmbossJob();
|
||||||
|
void restart(const Data &data);
|
||||||
|
protected:
|
||||||
|
// Launched just before start(), a job can use it to prepare internals
|
||||||
|
virtual void prepare() override;
|
||||||
|
|
||||||
|
// The method where the actual work of the job should be defined.
|
||||||
|
virtual void process() override;
|
||||||
|
|
||||||
|
// Launched when the job is finished. It refreshes the 3Dscene by def.
|
||||||
|
virtual void finalize() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<Data> m_data;
|
||||||
|
std::optional<indexed_triangle_set> m_result;
|
||||||
|
|
||||||
|
std::mutex m_mutex; // protect next data
|
||||||
|
std::optional<Data> m_data_next;
|
||||||
|
std::thread m_restart_thread;
|
||||||
|
|
||||||
|
// TODO: move to objec list utils
|
||||||
|
void select_volume(ModelVolume * volume);
|
||||||
|
|
||||||
|
|
||||||
|
class Progress : public ProgressIndicator
|
||||||
|
{
|
||||||
|
// Inherited via ProgressIndicator
|
||||||
|
virtual void set_range(int range) override {}
|
||||||
|
virtual void set_cancel_callback(CancelFn = CancelFn()) override {}
|
||||||
|
virtual void set_progress(int pr) override {}
|
||||||
|
virtual void set_status_text(const char *) override {}
|
||||||
|
virtual int get_range() const override { return 100; }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} // namespace Slic3r::GUI
|
||||||
|
|
||||||
|
#endif // slic3r_EmbossJob_hpp_
|
Loading…
x
Reference in New Issue
Block a user