mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-14 05:01:51 +08:00
Set fine position
This commit is contained in:
parent
2bf876e96c
commit
378d8af7ac
@ -1,6 +1,8 @@
|
|||||||
#include "CameraUtils.hpp"
|
#include "CameraUtils.hpp"
|
||||||
#include <igl/project.h> // projecting points
|
#include <igl/project.h> // projecting points
|
||||||
|
|
||||||
|
#include "slic3r/GUI/3DScene.hpp" // GLVolume
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
using namespace GUI;
|
using namespace GUI;
|
||||||
|
|
||||||
@ -33,3 +35,18 @@ Points CameraUtils::project(const Camera & camera,
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Slic3r::Polygon CameraUtils::create_hull2d(const Camera & camera,
|
||||||
|
const GLVolume &volume)
|
||||||
|
{
|
||||||
|
const indexed_triangle_set &its = volume.convex_hull()->its;
|
||||||
|
const Transform3d &trafoMat = volume.get_instance_transformation()
|
||||||
|
.get_matrix();
|
||||||
|
std::vector<Vec3d> vertices;
|
||||||
|
vertices.reserve(its.vertices.size());
|
||||||
|
for (const Vec3f &vertex : its.vertices)
|
||||||
|
vertices.emplace_back(trafoMat * vertex.cast<double>());
|
||||||
|
|
||||||
|
Points vertices_2d = project(camera, vertices);
|
||||||
|
return Geometry::convex_hull(vertices_2d);
|
||||||
|
}
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
|
namespace Slic3r {
|
||||||
|
class GLVolume;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Slic3r::GUI {
|
namespace Slic3r::GUI {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Help divide camera data and camera functions
|
/// Help divide camera data and camera functions
|
||||||
/// This utility work with camera data by static funtions
|
/// This utility work with camera data by static funtions
|
||||||
@ -16,14 +18,22 @@ public:
|
|||||||
CameraUtils() = delete; // only static functions
|
CameraUtils() = delete; // only static functions
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// project point throw camera to 2d coordinate into imgui window
|
/// Project point throw camera to 2d coordinate into imgui window
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="its">IN/OUT triangle mesh to be simplified.</param>
|
/// <param name="camera">Projection params</param>
|
||||||
/// <param name="its">IN/OUT triangle mesh to be simplified.</param>
|
/// <param name="points">Point to project.</param>
|
||||||
/// <returns>projected points by camera into coordinate of camera.
|
/// <returns>projected points by camera into coordinate of camera.
|
||||||
/// x(from left to right), y(from top to bottom)</returns>
|
/// x(from left to right), y(from top to bottom)</returns>
|
||||||
static Points project(const Camera& camera, const std::vector<Vec3d> &points);
|
static Points project(const Camera& camera, const std::vector<Vec3d> &points);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create hull around GLVolume in 2d space of camera
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="camera">Projection params</param>
|
||||||
|
/// <param name="volume">Outline by 3d object</param>
|
||||||
|
/// <returns>Polygon around object</returns>
|
||||||
|
static Polygon create_hull2d(const Camera &camera, const GLVolume &volume);
|
||||||
|
|
||||||
};
|
};
|
||||||
} // Slic3r::GUI
|
} // Slic3r::GUI
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
// TODO: remove include
|
// TODO: remove include
|
||||||
#include "libslic3r/SVG.hpp" // debug store
|
#include "libslic3r/SVG.hpp" // debug store
|
||||||
|
#include "libslic3r/Geometry.hpp" // covex hull 2d
|
||||||
|
|
||||||
#include "libslic3r/Model.hpp"
|
#include "libslic3r/Model.hpp"
|
||||||
#include "libslic3r/ClipperUtils.hpp" // union_ex
|
#include "libslic3r/ClipperUtils.hpp" // union_ex
|
||||||
@ -40,7 +41,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// uncomment for easier debug
|
// uncomment for easier debug
|
||||||
// #define ALLOW_DEBUG_MODE
|
//#define ALLOW_DEBUG_MODE
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
class WxFontUtils
|
class WxFontUtils
|
||||||
@ -184,7 +185,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // __linux__
|
#endif // __linux__
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
using namespace Slic3r;
|
using namespace Slic3r;
|
||||||
@ -203,17 +203,76 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
|
|||||||
|
|
||||||
GLGizmoEmboss::~GLGizmoEmboss() {}
|
GLGizmoEmboss::~GLGizmoEmboss() {}
|
||||||
|
|
||||||
|
void GLGizmoEmboss::set_fine_position()
|
||||||
|
{
|
||||||
|
const Selection & selection = m_parent.get_selection();
|
||||||
|
const Selection::IndicesList indices = selection.get_volume_idxs();
|
||||||
|
// no selected volume
|
||||||
|
if (indices.empty()) return;
|
||||||
|
const GLVolume *volume = selection.get_volume(*indices.begin());
|
||||||
|
// bad volume selected (e.g. deleted one)
|
||||||
|
if (volume == nullptr) return;
|
||||||
|
|
||||||
|
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||||
|
Polygon hull = CameraUtils::create_hull2d(camera, *volume);
|
||||||
|
|
||||||
|
// TODO: fix width
|
||||||
|
ImVec2 windows_size = m_gui_cfg->draw_advanced ?
|
||||||
|
m_gui_cfg->minimal_window_size_with_advance :
|
||||||
|
m_gui_cfg->minimal_window_size;
|
||||||
|
ImVec2 offset = ImGuiWrapper::suggest_location(windows_size, hull);
|
||||||
|
m_gui_cfg->offset = offset;
|
||||||
|
return;
|
||||||
|
|
||||||
|
Polygon rect({Point(offset.x, offset.y),
|
||||||
|
Point(offset.x + windows_size.x, offset.y),
|
||||||
|
Point(offset.x + windows_size.x, offset.y + windows_size.y),
|
||||||
|
Point(offset.x, offset.y + windows_size.y)});
|
||||||
|
ImGuiWrapper::draw(hull);
|
||||||
|
ImGuiWrapper::draw(rect);
|
||||||
|
// m_gui_cfg->offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
|
static void draw_fine_position(const Selection &selection)
|
||||||
|
{
|
||||||
|
const Selection::IndicesList indices = selection.get_volume_idxs();
|
||||||
|
// no selected volume
|
||||||
|
if (indices.empty()) return;
|
||||||
|
const GLVolume *volume = selection.get_volume(*indices.begin());
|
||||||
|
// bad volume selected (e.g. deleted one)
|
||||||
|
if (volume == nullptr) return;
|
||||||
|
|
||||||
|
const Camera &camera = wxGetApp().plater()->get_camera();
|
||||||
|
Slic3r::Polygon hull = CameraUtils::create_hull2d(camera, *volume);
|
||||||
|
|
||||||
|
ImVec2 windows_size(174, 202);
|
||||||
|
ImVec2 offset = ImGuiWrapper::suggest_location(windows_size, hull);
|
||||||
|
Slic3r::Polygon rect(
|
||||||
|
{Point(offset.x, offset.y), Point(offset.x + windows_size.x, offset.y),
|
||||||
|
Point(offset.x + windows_size.x, offset.y + windows_size.y),
|
||||||
|
Point(offset.x, offset.y + windows_size.y)});
|
||||||
|
ImGuiWrapper::draw(hull);
|
||||||
|
ImGuiWrapper::draw(rect);
|
||||||
|
}
|
||||||
|
#endif // ALLOW_DEBUG_MODE
|
||||||
|
|
||||||
|
void GLGizmoEmboss::set_volume_type(ModelVolumeType volume_type)
|
||||||
|
{
|
||||||
|
if (m_volume == nullptr) return;
|
||||||
|
m_volume->set_type(volume_type);
|
||||||
|
refresh_object_list();
|
||||||
|
m_parent.reload_scene(true);
|
||||||
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::on_init()
|
bool GLGizmoEmboss::on_init()
|
||||||
{
|
{
|
||||||
//m_grabbers.emplace_back();
|
// m_grabbers.emplace_back();
|
||||||
m_shortcut_key = WXK_CONTROL_T;
|
m_shortcut_key = WXK_CONTROL_T;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLGizmoEmboss::on_get_name() const
|
std::string GLGizmoEmboss::on_get_name() const { return _u8L("Emboss"); }
|
||||||
{
|
|
||||||
return _u8L("Emboss");
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLGizmoEmboss::on_render() {}
|
void GLGizmoEmboss::on_render() {}
|
||||||
void GLGizmoEmboss::on_render_for_picking() {}
|
void GLGizmoEmboss::on_render_for_picking() {}
|
||||||
@ -221,19 +280,39 @@ void GLGizmoEmboss::on_render_for_picking() {}
|
|||||||
void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
|
void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
|
||||||
{
|
{
|
||||||
check_selection();
|
check_selection();
|
||||||
int flag = //ImGuiWindowFlags_AlwaysAutoResize |
|
int flag = // ImGuiWindowFlags_AlwaysAutoResize |
|
||||||
// ImGuiWindowFlags_NoResize |
|
// ImGuiWindowFlags_NoResize |
|
||||||
ImGuiWindowFlags_NoCollapse;
|
ImGuiWindowFlags_NoCollapse;
|
||||||
|
|
||||||
|
ImVec2 min_window_size = m_gui_cfg->draw_advanced ?
|
||||||
|
m_gui_cfg->minimal_window_size_with_advance :
|
||||||
|
m_gui_cfg->minimal_window_size;
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, min_window_size);
|
||||||
|
// ImGui::SetNextWindowSize(ImVec2(0, min_window_size.y),
|
||||||
|
// ImGuiCond_::ImGuiCond_Always);
|
||||||
|
|
||||||
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
|
// draw suggested position of window
|
||||||
|
draw_fine_position(m_parent.get_selection());
|
||||||
|
#endif // ALLOW_DEBUG_MODE
|
||||||
|
|
||||||
|
// check if is set window offset
|
||||||
|
if (m_gui_cfg->offset.has_value()) {
|
||||||
|
ImGui::SetNextWindowPos(*m_gui_cfg->offset, ImGuiCond_Always);
|
||||||
|
// clear request on offset
|
||||||
|
m_gui_cfg->offset = {};
|
||||||
|
}
|
||||||
|
|
||||||
m_imgui->begin(on_get_name(), flag);
|
m_imgui->begin(on_get_name(), flag);
|
||||||
draw_window();
|
draw_window();
|
||||||
m_imgui->end();
|
m_imgui->end();
|
||||||
|
ImGui::PopStyleVar(); // WindowMinSize
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::on_set_state()
|
void GLGizmoEmboss::on_set_state()
|
||||||
{
|
{
|
||||||
// Closing gizmo. e.g. selecting another one
|
// Closing gizmo. e.g. selecting another one
|
||||||
if (GLGizmoBase::m_state == GLGizmoBase::Off) {
|
if (GLGizmoBase::m_state == GLGizmoBase::Off) {
|
||||||
|
|
||||||
// refuse outgoing during text preview
|
// refuse outgoing during text preview
|
||||||
if (false) {
|
if (false) {
|
||||||
GLGizmoBase::m_state = GLGizmoBase::On;
|
GLGizmoBase::m_state = GLGizmoBase::On;
|
||||||
@ -279,10 +358,8 @@ void GLGizmoEmboss::initialize()
|
|||||||
m_gui_cfg->icon_width = ImGui::GetTextLineHeight();
|
m_gui_cfg->icon_width = ImGui::GetTextLineHeight();
|
||||||
m_gui_cfg->icon_width_with_spacing = m_gui_cfg->icon_width + space;
|
m_gui_cfg->icon_width_with_spacing = m_gui_cfg->icon_width + space;
|
||||||
|
|
||||||
|
|
||||||
float scroll_width = m_gui_cfg->icon_width_with_spacing; // fix
|
float scroll_width = m_gui_cfg->icon_width_with_spacing; // fix
|
||||||
m_gui_cfg->combo_font_width =
|
m_gui_cfg->combo_font_width = m_gui_cfg->max_font_name_width +
|
||||||
m_gui_cfg->max_font_name_width +
|
|
||||||
2 * m_gui_cfg->icon_width_with_spacing +
|
2 * m_gui_cfg->icon_width_with_spacing +
|
||||||
scroll_width;
|
scroll_width;
|
||||||
|
|
||||||
@ -290,8 +367,10 @@ void GLGizmoEmboss::initialize()
|
|||||||
m_gui_cfg->delete_pos_x = m_gui_cfg->rename_pos_x +
|
m_gui_cfg->delete_pos_x = m_gui_cfg->rename_pos_x +
|
||||||
m_gui_cfg->icon_width_with_spacing;
|
m_gui_cfg->icon_width_with_spacing;
|
||||||
|
|
||||||
m_gui_cfg->text_size =
|
m_gui_cfg->text_size = ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() *
|
||||||
ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * m_gui_cfg->count_line_of_text);
|
m_gui_cfg->count_line_of_text);
|
||||||
|
|
||||||
|
m_gui_cfg->advanced_input_width = ImGui::CalcTextSize("M").x * 6;
|
||||||
|
|
||||||
// TODO: What to do when icon was NOT loaded?
|
// TODO: What to do when icon was NOT loaded?
|
||||||
bool success = init_icons();
|
bool success = init_icons();
|
||||||
@ -318,7 +397,8 @@ FontList GLGizmoEmboss::create_default_font_list() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::set_default_configuration() {
|
void GLGizmoEmboss::set_default_configuration()
|
||||||
|
{
|
||||||
m_text = _u8L("Embossed text");
|
m_text = _u8L("Embossed text");
|
||||||
m_font_prop = FontProp();
|
m_font_prop = FontProp();
|
||||||
load_font(); // reload actual font - because of font size
|
load_font(); // reload actual font - because of font size
|
||||||
@ -327,16 +407,15 @@ void GLGizmoEmboss::set_default_configuration() {
|
|||||||
#include "imgui/imgui_internal.h" // to unfocus input --> ClearActiveID
|
#include "imgui/imgui_internal.h" // to unfocus input --> ClearActiveID
|
||||||
void GLGizmoEmboss::check_selection()
|
void GLGizmoEmboss::check_selection()
|
||||||
{
|
{
|
||||||
ModelVolume* vol = get_selected_volume();
|
ModelVolume *vol = get_selected_volume();
|
||||||
// is same volume selected?
|
// is same volume selected?
|
||||||
if (vol!= nullptr && m_volume == vol) return;
|
if (vol != nullptr && m_volume == vol) return;
|
||||||
|
|
||||||
// for changed volume notification is NOT valid
|
// for changed volume notification is NOT valid
|
||||||
remove_notification_not_valid_font();
|
remove_notification_not_valid_font();
|
||||||
|
|
||||||
// Do not use focused input value when switch volume(it must swith value)
|
// Do not use focused input value when switch volume(it must swith value)
|
||||||
if (m_volume != nullptr)
|
if (m_volume != nullptr) ImGui::ClearActiveID();
|
||||||
ImGui::ClearActiveID();
|
|
||||||
|
|
||||||
// is select embossed volume?
|
// is select embossed volume?
|
||||||
if (load_configuration(vol)) {
|
if (load_configuration(vol)) {
|
||||||
@ -397,15 +476,8 @@ bool GLGizmoEmboss::process()
|
|||||||
return add_volume(create_volume_name(), its);
|
return add_volume(create_volume_name(), its);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::set_volume_type(ModelVolumeType volume_type)
|
bool GLGizmoEmboss::add_volume(const std::string & name,
|
||||||
{
|
indexed_triangle_set &its)
|
||||||
if (m_volume == nullptr) return;
|
|
||||||
m_volume->set_type(volume_type);
|
|
||||||
refresh_object_list();
|
|
||||||
m_parent.reload_scene(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLGizmoEmboss::add_volume(const std::string &name, indexed_triangle_set &its)
|
|
||||||
{
|
{
|
||||||
if (its.indices.empty()) return false;
|
if (its.indices.empty()) return false;
|
||||||
// add object
|
// add object
|
||||||
@ -414,7 +486,7 @@ bool GLGizmoEmboss::add_volume(const std::string &name, indexed_triangle_set &it
|
|||||||
Vec3d shift = tm.bounding_box().center();
|
Vec3d shift = tm.bounding_box().center();
|
||||||
tm.translate(-shift.cast<float>());
|
tm.translate(-shift.cast<float>());
|
||||||
|
|
||||||
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("Add") + " " + name);
|
||||||
if (m_volume == nullptr) {
|
if (m_volume == nullptr) {
|
||||||
@ -454,70 +526,22 @@ bool GLGizmoEmboss::add_volume(const std::string &name, indexed_triangle_set &it
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::close() {
|
void GLGizmoEmboss::close()
|
||||||
|
{
|
||||||
// close gizmo == open it again
|
// close gizmo == open it again
|
||||||
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
m_parent.get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw(const Slic3r::Polygon &polygon,
|
|
||||||
ImU32 color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 0.65f)),
|
|
||||||
float thickness = 1.f)
|
|
||||||
{
|
|
||||||
// minimal one line
|
|
||||||
if (polygon.size()<2) return;
|
|
||||||
|
|
||||||
auto dl = ImGui::GetOverlayDrawList();
|
|
||||||
//auto dl = ImGui::GetWindowDrawList();
|
|
||||||
const Point* prev_point = &polygon.points.back();
|
|
||||||
for (const Point &point : polygon.points) {
|
|
||||||
ImVec2 p1(prev_point->x(), prev_point->y());
|
|
||||||
ImVec2 p2(point.x(), point.y());
|
|
||||||
dl->AddLine(p1, p2, color, thickness);
|
|
||||||
prev_point = &point;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "libslic3r/Geometry.hpp"
|
|
||||||
static void draw_hull(const GLVolume& volume)
|
|
||||||
{
|
|
||||||
const TriangleMesh &tm = *volume.convex_hull();
|
|
||||||
ImGui::Text("hull size %d", (int) tm.its.vertices.size());
|
|
||||||
|
|
||||||
//Slic3r::Polygon test_triangle({Point(100, 100), Point(200, 150), Point(120, 210)});
|
|
||||||
//draw(test_triangle);
|
|
||||||
|
|
||||||
// transform 3d hull
|
|
||||||
Geometry::Transformation trafo = volume.get_instance_transformation();
|
|
||||||
const Transform3d & trafoMat = trafo.get_matrix();
|
|
||||||
std::vector<Vec3d> vertices;
|
|
||||||
vertices.reserve(tm.its.vertices.size());
|
|
||||||
for (const Vec3f &vertex : tm.its.vertices)
|
|
||||||
vertices.emplace_back(trafoMat * vertex.cast<double>());
|
|
||||||
|
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
|
||||||
Points vertices_2d = CameraUtils::project(camera, vertices);
|
|
||||||
Slic3r::Polygon chull = Geometry::convex_hull(vertices_2d);
|
|
||||||
draw(chull, ImGui::GetColorU32(ImVec4(0.7f, 0.1f, 0.2f, 0.75f)), 3.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GLGizmoEmboss::draw_window()
|
void GLGizmoEmboss::draw_window()
|
||||||
{
|
{
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
if(ImGui::Button("re-process")) process();
|
if (ImGui::Button("re-process")) process();
|
||||||
if(ImGui::Button("add svg")) choose_svg_file();
|
if (ImGui::Button("add svg")) choose_svg_file();
|
||||||
if(ImGui::Button("use system font")) {
|
if (ImGui::Button("use system font")) {
|
||||||
size_t font_index = m_font_list.size();
|
size_t font_index = m_font_list.size();
|
||||||
m_font_list.emplace_back(WxFontUtils::get_os_font());
|
m_font_list.emplace_back(WxFontUtils::get_os_font());
|
||||||
bool loaded = load_font(font_index);
|
bool loaded = load_font(font_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Selection &selection = m_parent.get_selection();
|
|
||||||
const GLVolume * volume = selection.get_volume(
|
|
||||||
*selection.get_volume_idxs().begin());
|
|
||||||
if (volume != nullptr) draw_hull(*volume);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // ALLOW_DEBUG_MODE
|
#endif // ALLOW_DEBUG_MODE
|
||||||
if (!m_font.has_value()) {
|
if (!m_font.has_value()) {
|
||||||
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());
|
||||||
@ -525,8 +549,14 @@ void GLGizmoEmboss::draw_window()
|
|||||||
draw_font_list();
|
draw_font_list();
|
||||||
draw_text_input();
|
draw_text_input();
|
||||||
|
|
||||||
static bool advanced = false;
|
bool &advanced = m_gui_cfg->draw_advanced;
|
||||||
ImGui::Checkbox(_u8L("Advance").c_str(), &advanced);
|
if (ImGui::Checkbox(_u8L("Advance").c_str(), &advanced)) {
|
||||||
|
ImVec2 window_size =
|
||||||
|
advanced ?
|
||||||
|
ImVec2(0, m_gui_cfg->minimal_window_size_with_advance.y) :
|
||||||
|
m_gui_cfg->minimal_window_size;
|
||||||
|
ImGui::SetWindowSize(window_size, ImGuiCond_Always);
|
||||||
|
}
|
||||||
if (advanced) draw_advanced();
|
if (advanced) draw_advanced();
|
||||||
|
|
||||||
if (ImGui::Button(_u8L("Close").c_str())) close();
|
if (ImGui::Button(_u8L("Close").c_str())) close();
|
||||||
@ -542,9 +572,10 @@ void GLGizmoEmboss::draw_window()
|
|||||||
|
|
||||||
void GLGizmoEmboss::draw_font_list()
|
void GLGizmoEmboss::draw_font_list()
|
||||||
{
|
{
|
||||||
const float& max_width = m_gui_cfg->max_font_name_width;
|
const float & max_width = m_gui_cfg->max_font_name_width;
|
||||||
std::optional<size_t> rename_index;
|
std::optional<size_t> rename_index;
|
||||||
std::string current_name = imgui_trunc(m_font_list[m_font_selected].name, max_width);
|
std::string current_name = imgui_trunc(m_font_list[m_font_selected].name,
|
||||||
|
max_width);
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width);
|
||||||
if (ImGui::BeginCombo("##font_selector", current_name.c_str())) {
|
if (ImGui::BeginCombo("##font_selector", current_name.c_str())) {
|
||||||
// first line
|
// first line
|
||||||
@ -552,14 +583,17 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
choose_font_by_wxdialog();
|
choose_font_by_wxdialog();
|
||||||
store_font_list();
|
store_font_list();
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_u8L("Choose from installed font inside dialog.").c_str());
|
} else if (ImGui::IsItemHovered())
|
||||||
|
ImGui::SetTooltip(
|
||||||
|
_u8L("Choose from installed font inside dialog.").c_str());
|
||||||
|
|
||||||
// select font file by file browser
|
// select font file by file browser
|
||||||
//if (ImGui::Button(_u8L("Add File").c_str())) {
|
// if (ImGui::Button(_u8L("Add File").c_str())) {
|
||||||
// choose_true_type_file();
|
// choose_true_type_file();
|
||||||
// store_font_list();
|
// store_font_list();
|
||||||
// ImGui::CloseCurrentPopup();
|
// ImGui::CloseCurrentPopup();
|
||||||
//} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_u8L("add file with font(.ttf, .ttc)").c_str());
|
//} else if (ImGui::IsItemHovered()) ImGui::SetTooltip(_u8L("add file
|
||||||
|
//with font(.ttf, .ttc)").c_str());
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
@ -568,7 +602,8 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
std::string name = imgui_trunc(f.name, max_width);
|
std::string name = imgui_trunc(f.name, max_width);
|
||||||
size_t index = &f - &m_font_list.front();
|
size_t index = &f - &m_font_list.front();
|
||||||
bool is_selected = index == m_font_selected;
|
bool is_selected = index == m_font_selected;
|
||||||
auto flags = ImGuiSelectableFlags_AllowItemOverlap; // allow clic buttons
|
auto flags =
|
||||||
|
ImGuiSelectableFlags_AllowItemOverlap; // allow clic buttons
|
||||||
if (ImGui::Selectable(name.c_str(), is_selected, flags)) {
|
if (ImGui::Selectable(name.c_str(), is_selected, flags)) {
|
||||||
size_t prev_font_selected = m_font_selected;
|
size_t prev_font_selected = m_font_selected;
|
||||||
m_font_selected = index;
|
m_font_selected = index;
|
||||||
@ -598,19 +633,21 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rename modal window popup
|
// rename modal window popup
|
||||||
const char *rename_popup_id = "Rename_font";
|
const char * rename_popup_id = "Rename_font";
|
||||||
static size_t rename_id;
|
static size_t rename_id;
|
||||||
if (rename_index.has_value() && !ImGui::IsPopupOpen(rename_popup_id)) {
|
if (rename_index.has_value() && !ImGui::IsPopupOpen(rename_popup_id)) {
|
||||||
ImGui::OpenPopup(rename_popup_id);
|
ImGui::OpenPopup(rename_popup_id);
|
||||||
rename_id = *rename_index;
|
rename_id = *rename_index;
|
||||||
}
|
}
|
||||||
if (ImGui::BeginPopupModal(rename_popup_id)) {
|
if (ImGui::BeginPopupModal(rename_popup_id)) {
|
||||||
FontItem &fi = m_font_list[rename_id];
|
FontItem & fi = m_font_list[rename_id];
|
||||||
std::string rename_popup = GUI::format(_u8L("Change font name (%1%): "), fi.name);
|
std::string rename_popup =
|
||||||
|
GUI::format(_u8L("Change font name (%1%): "), fi.name);
|
||||||
ImGui::Text(rename_popup.c_str());
|
ImGui::Text(rename_popup.c_str());
|
||||||
ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width);
|
ImGui::SetNextItemWidth(m_gui_cfg->combo_font_width);
|
||||||
if (ImGui::InputText("##font name", &fi.name, ImGuiInputTextFlags_EnterReturnsTrue) ||
|
if (ImGui::InputText("##font name", &fi.name,
|
||||||
ImGui::Button("ok")){
|
ImGuiInputTextFlags_EnterReturnsTrue) ||
|
||||||
|
ImGui::Button("ok")) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
store_font_list();
|
store_font_list();
|
||||||
}
|
}
|
||||||
@ -621,16 +658,16 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
void GLGizmoEmboss::draw_text_input()
|
void GLGizmoEmboss::draw_text_input()
|
||||||
{
|
{
|
||||||
static const ImGuiInputTextFlags flags =
|
static const ImGuiInputTextFlags flags =
|
||||||
ImGuiInputTextFlags_AllowTabInput |
|
ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_AutoSelectAll;
|
||||||
ImGuiInputTextFlags_AutoSelectAll ;
|
|
||||||
|
|
||||||
ImVector<ImFont *> &fonts = m_imgui_font_atlas.Fonts;
|
ImVector<ImFont *> &fonts = m_imgui_font_atlas.Fonts;
|
||||||
ImFont *imgui_font = fonts.empty()? nullptr : fonts.front();
|
ImFont * imgui_font = fonts.empty() ? nullptr : fonts.front();
|
||||||
bool exist_font = imgui_font != nullptr && imgui_font->IsLoaded();
|
bool exist_font = imgui_font != nullptr && imgui_font->IsLoaded();
|
||||||
if (exist_font) ImGui::PushFont(imgui_font);
|
if (exist_font) ImGui::PushFont(imgui_font);
|
||||||
|
|
||||||
bool exist_change = false;
|
bool exist_change = false;
|
||||||
if (ImGui::InputTextMultiline("##Text", &m_text, m_gui_cfg->text_size, flags)) {
|
if (ImGui::InputTextMultiline("##Text", &m_text, m_gui_cfg->text_size,
|
||||||
|
flags)) {
|
||||||
process();
|
process();
|
||||||
exist_change = true;
|
exist_change = true;
|
||||||
}
|
}
|
||||||
@ -641,11 +678,14 @@ void GLGizmoEmboss::draw_text_input()
|
|||||||
if (exist_change) check_imgui_font_range();
|
if (exist_change) check_imgui_font_range();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::draw_advanced() {
|
void GLGizmoEmboss::draw_advanced()
|
||||||
if (ImGui::InputFloat(_u8L("Size[in mm]").c_str(), &m_font_prop.size_in_mm)) {
|
{
|
||||||
|
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
||||||
|
if (ImGui::InputFloat(_u8L("Size[in mm]").c_str(),
|
||||||
|
&m_font_prop.size_in_mm)) {
|
||||||
if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10;
|
if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10;
|
||||||
// store font size into path
|
// store font size into path
|
||||||
FontItem& fi = m_font_list[m_font_selected];
|
FontItem &fi = m_font_list[m_font_selected];
|
||||||
if (fi.type == WxFontUtils::get_actual_type()) {
|
if (fi.type == WxFontUtils::get_actual_type()) {
|
||||||
std::optional<wxFont> wx_font = WxFontUtils::load_wxFont(fi.path);
|
std::optional<wxFont> wx_font = WxFontUtils::load_wxFont(fi.path);
|
||||||
if (wx_font.has_value()) {
|
if (wx_font.has_value()) {
|
||||||
@ -657,13 +697,21 @@ void GLGizmoEmboss::draw_advanced() {
|
|||||||
if (m_font.has_value()) m_font->cache.clear();
|
if (m_font.has_value()) m_font->cache.clear();
|
||||||
process();
|
process();
|
||||||
}
|
}
|
||||||
|
ImGui::SetNextItemWidth(m_gui_cfg->advanced_input_width);
|
||||||
if (ImGui::InputFloat(_u8L("Emboss[in mm]").c_str(), &m_font_prop.emboss)) process();
|
if (ImGui::InputFloat(_u8L("Emboss[in mm]").c_str(), &m_font_prop.emboss))
|
||||||
if (ImGui::InputInt(_u8L("CharGap[in font points]").c_str(), &m_font_prop.char_gap)) process();
|
process();
|
||||||
if (ImGui::InputInt(_u8L("LineGap[in font points]").c_str(), &m_font_prop.line_gap)) process();
|
ImGui::SetNextItemWidth(2*m_gui_cfg->advanced_input_width);
|
||||||
|
if (ImGui::InputInt(_u8L("CharGap[in font points]").c_str(),
|
||||||
|
&m_font_prop.char_gap))
|
||||||
|
process();
|
||||||
|
ImGui::SetNextItemWidth(2*m_gui_cfg->advanced_input_width);
|
||||||
|
if (ImGui::InputInt(_u8L("LineGap[in font points]").c_str(),
|
||||||
|
&m_font_prop.line_gap))
|
||||||
|
process();
|
||||||
|
|
||||||
// when more collection add selector
|
// when more collection add selector
|
||||||
if (m_font.has_value() && m_font->count > 1) {
|
if (m_font.has_value() && m_font->count > 1) {
|
||||||
|
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())) {
|
||||||
for (unsigned int i = 0; i < m_font->count; ++i) {
|
for (unsigned int i = 0; i < m_font->count; ++i) {
|
||||||
@ -682,12 +730,22 @@ void GLGizmoEmboss::draw_advanced() {
|
|||||||
|
|
||||||
#ifdef ALLOW_DEBUG_MODE
|
#ifdef ALLOW_DEBUG_MODE
|
||||||
std::string descriptor = m_font_list[m_font_selected].path;
|
std::string descriptor = m_font_list[m_font_selected].path;
|
||||||
ImGui::Text("family = %s", (m_font_prop.family.has_value()?m_font_prop.family->c_str() : " --- "));
|
ImGui::Text("family = %s", (m_font_prop.family.has_value() ?
|
||||||
ImGui::Text("face name = %s", (m_font_prop.face_name.has_value()?m_font_prop.face_name->c_str() : " --- "));
|
m_font_prop.family->c_str() :
|
||||||
ImGui::Text("style = %s", (m_font_prop.style.has_value()?m_font_prop.style->c_str() : " --- "));
|
" --- "));
|
||||||
ImGui::Text("weight = %s", (m_font_prop.weight.has_value()? m_font_prop.weight->c_str() : " --- "));
|
ImGui::Text("face name = %s", (m_font_prop.face_name.has_value() ?
|
||||||
|
m_font_prop.face_name->c_str() :
|
||||||
|
" --- "));
|
||||||
|
ImGui::Text("style = %s",
|
||||||
|
(m_font_prop.style.has_value() ? m_font_prop.style->c_str() :
|
||||||
|
" --- "));
|
||||||
|
ImGui::Text("weight = %s", (m_font_prop.weight.has_value() ?
|
||||||
|
m_font_prop.weight->c_str() :
|
||||||
|
" --- "));
|
||||||
ImGui::Text("descriptor = %s", descriptor.c_str());
|
ImGui::Text("descriptor = %s", descriptor.c_str());
|
||||||
ImGui::Image(m_imgui_font_atlas.TexID, ImVec2(m_imgui_font_atlas.TexWidth, m_imgui_font_atlas.TexHeight));
|
ImGui::Image(m_imgui_font_atlas.TexID,
|
||||||
|
ImVec2(m_imgui_font_atlas.TexWidth,
|
||||||
|
m_imgui_font_atlas.TexHeight));
|
||||||
#endif // ALLOW_DEBUG_MODE
|
#endif // ALLOW_DEBUG_MODE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -701,7 +759,8 @@ bool GLGizmoEmboss::create_default_model_object()
|
|||||||
// e.g. selected font don't have letter for "Emboss text"
|
// e.g. selected font don't have letter for "Emboss text"
|
||||||
|
|
||||||
// try select another font
|
// try select another font
|
||||||
for (size_t font_index = 0; font_index < m_font_list.size(); ++font_index) {
|
for (size_t font_index = 0; font_index < m_font_list.size();
|
||||||
|
++font_index) {
|
||||||
if (!load_font(font_index)) continue;
|
if (!load_font(font_index)) continue;
|
||||||
// Is fixed by change to font from font list?
|
// Is fixed by change to font from font list?
|
||||||
if (process()) return true;
|
if (process()) return true;
|
||||||
@ -730,16 +789,18 @@ 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() ||
|
if (selection.is_empty() || selection.get_object_idx() < 0 ||
|
||||||
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; };
|
auto add_to_selection = [volume](const ModelVolume *vol) {
|
||||||
wxDataViewItemArray sel = obj_list->reorder_volumes_and_get_selection(
|
return vol == volume;
|
||||||
selection.get_object_idx(), add_to_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());
|
if (!sel.IsEmpty()) obj_list->select_item(sel.front());
|
||||||
obj_list->selection_changed();
|
obj_list->selection_changed();
|
||||||
}
|
}
|
||||||
@ -752,13 +813,16 @@ bool GLGizmoEmboss::load_font(size_t font_index)
|
|||||||
return is_loaded;
|
return is_loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::load_font() {
|
bool GLGizmoEmboss::load_font()
|
||||||
|
{
|
||||||
if (m_font_selected >= m_font_list.size()) return false;
|
if (m_font_selected >= m_font_list.size()) return false;
|
||||||
FontItem& fi = m_font_list[m_font_selected];
|
FontItem &fi = m_font_list[m_font_selected];
|
||||||
if (fi.type == FontItem::Type::file_path) {
|
if (fi.type == FontItem::Type::file_path) {
|
||||||
// fill font name after load from .3mf
|
// fill font name after load from .3mf
|
||||||
if (fi.name.empty()) fi.name = Slic3r::GUI::GLGizmoEmboss::get_file_name(fi.path);
|
if (fi.name.empty())
|
||||||
std::optional<Emboss::Font> font_opt = Emboss::load_font(fi.path.c_str());
|
fi.name = Slic3r::GUI::GLGizmoEmboss::get_file_name(fi.path);
|
||||||
|
std::optional<Emboss::Font> font_opt = Emboss::load_font(
|
||||||
|
fi.path.c_str());
|
||||||
if (!font_opt.has_value()) return false;
|
if (!font_opt.has_value()) return false;
|
||||||
m_font = font_opt;
|
m_font = font_opt;
|
||||||
load_imgui_font();
|
load_imgui_font();
|
||||||
@ -769,11 +833,12 @@ bool GLGizmoEmboss::load_font() {
|
|||||||
if (!wx_font.has_value()) return false;
|
if (!wx_font.has_value()) return false;
|
||||||
|
|
||||||
// fill font name after load from .3mf
|
// fill font name after load from .3mf
|
||||||
if (fi.name.empty()) fi.name = WxFontUtils::get_human_readable_name(*wx_font);
|
if (fi.name.empty())
|
||||||
|
fi.name = WxFontUtils::get_human_readable_name(*wx_font);
|
||||||
return load_font(*wx_font);
|
return load_font(*wx_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::load_font(const wxFont& font)
|
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;
|
||||||
@ -821,7 +886,8 @@ void GLGizmoEmboss::check_imgui_font_range()
|
|||||||
if (exist_unknown) load_imgui_font();
|
if (exist_unknown) load_imgui_font();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::load_imgui_font() {
|
void GLGizmoEmboss::load_imgui_font()
|
||||||
|
{
|
||||||
if (!m_font.has_value()) return;
|
if (!m_font.has_value()) return;
|
||||||
|
|
||||||
ImFontGlyphRangesBuilder builder;
|
ImFontGlyphRangesBuilder builder;
|
||||||
@ -843,9 +909,10 @@ void GLGizmoEmboss::load_imgui_font() {
|
|||||||
m_imgui_font_atlas.Flags |= ImFontAtlasFlags_NoMouseCursors |
|
m_imgui_font_atlas.Flags |= ImFontAtlasFlags_NoMouseCursors |
|
||||||
ImFontAtlasFlags_NoPowerOfTwoHeight;
|
ImFontAtlasFlags_NoPowerOfTwoHeight;
|
||||||
m_imgui_font_atlas.Clear();
|
m_imgui_font_atlas.Clear();
|
||||||
m_imgui_font_atlas.AddFontFromMemoryTTF(
|
m_imgui_font_atlas.AddFontFromMemoryTTF((void *) m_font->buffer.data(),
|
||||||
(void *) m_font->buffer.data(), m_font->buffer.size(),
|
m_font->buffer.size(), font_size,
|
||||||
font_size, &font_config, m_imgui_font_ranges.Data);
|
&font_config,
|
||||||
|
m_imgui_font_ranges.Data);
|
||||||
|
|
||||||
unsigned char *pixels;
|
unsigned char *pixels;
|
||||||
int width, height;
|
int width, height;
|
||||||
@ -854,7 +921,9 @@ void GLGizmoEmboss::load_imgui_font() {
|
|||||||
// Upload texture to graphics system
|
// Upload texture to graphics system
|
||||||
GLint last_texture;
|
GLint last_texture;
|
||||||
glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
ScopeGuard sg([last_texture]() { glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));});
|
ScopeGuard sg([last_texture]() {
|
||||||
|
glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture));
|
||||||
|
});
|
||||||
|
|
||||||
GLuint font_texture;
|
GLuint font_texture;
|
||||||
glsafe(::glGenTextures(1, &font_texture));
|
glsafe(::glGenTextures(1, &font_texture));
|
||||||
@ -877,9 +946,9 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
|
|||||||
// set previous selected font
|
// set previous selected font
|
||||||
FontItem &selected_font_item = m_font_list[m_font_selected];
|
FontItem &selected_font_item = m_font_list[m_font_selected];
|
||||||
if (selected_font_item.type == WxFontUtils::get_actual_type()) {
|
if (selected_font_item.type == WxFontUtils::get_actual_type()) {
|
||||||
std::optional<wxFont> selected_font = WxFontUtils::load_wxFont(selected_font_item.path);
|
std::optional<wxFont> selected_font = WxFontUtils::load_wxFont(
|
||||||
if (selected_font.has_value())
|
selected_font_item.path);
|
||||||
data.SetInitialFont(*selected_font);
|
if (selected_font.has_value()) data.SetInitialFont(*selected_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFontDialog font_dialog(wxGetApp().mainframe, data);
|
wxFontDialog font_dialog(wxGetApp().mainframe, data);
|
||||||
@ -899,15 +968,16 @@ bool GLGizmoEmboss::choose_font_by_wxdialog()
|
|||||||
if (!use_deserialized_font) m_font_selected = font_index;
|
if (!use_deserialized_font) m_font_selected = font_index;
|
||||||
// Try load and use new added font
|
// Try load and use new added font
|
||||||
if ((!use_deserialized_font && !load_font(font)) ||
|
if ((!use_deserialized_font && !load_font(font)) ||
|
||||||
(use_deserialized_font && !load_font(font_index)) ||
|
(use_deserialized_font && !load_font(font_index)) || !process()) {
|
||||||
!process()) {
|
|
||||||
// reverse index for font_selected
|
// reverse index for font_selected
|
||||||
std::swap(font_index, m_font_selected); // when not process
|
std::swap(font_index, m_font_selected); // when not process
|
||||||
// remove form font list
|
// remove form font list
|
||||||
m_font_list.pop_back();
|
m_font_list.pop_back();
|
||||||
// reverse property
|
// reverse property
|
||||||
m_font_prop = old_font_prop; // when not process
|
m_font_prop = old_font_prop; // when not process
|
||||||
wxString message = GUI::format_wxstr(_L("Font '%1%' can't be used. Please select another."), font_item.name);
|
wxString message = GUI::format_wxstr(
|
||||||
|
_L("Font '%1%' can't be used. Please select another."),
|
||||||
|
font_item.name);
|
||||||
wxString title = _L("Selected font is NOT True-type.");
|
wxString title = _L("Selected font is NOT True-type.");
|
||||||
MessageDialog not_loaded_font_message(nullptr, message, title, wxOK);
|
MessageDialog not_loaded_font_message(nullptr, message, title, wxOK);
|
||||||
not_loaded_font_message.ShowModal();
|
not_loaded_font_message.ShowModal();
|
||||||
@ -950,11 +1020,12 @@ bool GLGizmoEmboss::choose_svg_file()
|
|||||||
wxString fontDir = wxEmptyString;
|
wxString fontDir = wxEmptyString;
|
||||||
wxString selectedFile = wxEmptyString;
|
wxString selectedFile = wxEmptyString;
|
||||||
wxFileDialog dialog(nullptr, _L("Choose SVG file:"), fontDir,
|
wxFileDialog dialog(nullptr, _L("Choose SVG file:"), fontDir,
|
||||||
selectedFile, file_wildcards(FT_SVG), wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
selectedFile, file_wildcards(FT_SVG),
|
||||||
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
||||||
if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files);
|
if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files);
|
||||||
if (input_files.IsEmpty()) return false;
|
if (input_files.IsEmpty()) return false;
|
||||||
if (input_files.size() != 1) return false;
|
if (input_files.size() != 1) return false;
|
||||||
auto &input_file = input_files.front();
|
auto & input_file = input_files.front();
|
||||||
std::string path = std::string(input_file.c_str());
|
std::string path = std::string(input_file.c_str());
|
||||||
std::string name = get_file_name(path);
|
std::string name = get_file_name(path);
|
||||||
|
|
||||||
@ -963,20 +1034,22 @@ bool GLGizmoEmboss::choose_svg_file()
|
|||||||
nsvgDelete(image);
|
nsvgDelete(image);
|
||||||
|
|
||||||
BoundingBox bb;
|
BoundingBox bb;
|
||||||
for (const auto &p: polys) bb.merge(p.contour.points);
|
for (const auto &p : polys) bb.merge(p.contour.points);
|
||||||
float scale = m_font_prop.size_in_mm / std::max(bb.max.x(), bb.max.y());
|
float scale = m_font_prop.size_in_mm / std::max(bb.max.x(), bb.max.y());
|
||||||
auto project = std::make_unique<Emboss::ProjectScale>(
|
auto project = std::make_unique<Emboss::ProjectScale>(
|
||||||
std::make_unique<Emboss::ProjectZ>(m_font_prop.emboss / scale), scale);
|
std::make_unique<Emboss::ProjectZ>(m_font_prop.emboss / scale), scale);
|
||||||
indexed_triangle_set its = Emboss::polygons2model(polys, *project);
|
indexed_triangle_set its = Emboss::polygons2model(polys, *project);
|
||||||
// test store:
|
// test store:
|
||||||
//for (auto &poly : polys) poly.scale(1e5);
|
// for (auto &poly : polys) poly.scale(1e5);
|
||||||
//SVG svg("converted.svg", BoundingBox(polys.front().contour.points));
|
// SVG svg("converted.svg", BoundingBox(polys.front().contour.points));
|
||||||
//svg.draw(polys);
|
// svg.draw(polys);
|
||||||
return add_volume(name, its);
|
return add_volume(name, its);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextConfiguration GLGizmoEmboss::create_configuration() {
|
TextConfiguration GLGizmoEmboss::create_configuration()
|
||||||
return TextConfiguration(m_font_list[m_font_selected], m_font_prop, m_text);
|
{
|
||||||
|
return TextConfiguration(m_font_list[m_font_selected], m_font_prop,
|
||||||
|
m_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
||||||
@ -1011,11 +1084,13 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
|||||||
|
|
||||||
if (!load_font()) {
|
if (!load_font()) {
|
||||||
// create similar font
|
// create similar font
|
||||||
auto wx_font = WxFontUtils::create_wxFont(c_font_item, configuration.font_prop);
|
auto wx_font = WxFontUtils::create_wxFont(c_font_item,
|
||||||
|
configuration.font_prop);
|
||||||
if (wx_font.has_value()) {
|
if (wx_font.has_value()) {
|
||||||
// fix not loadable font item
|
// fix not loadable font item
|
||||||
m_font_list[m_font_selected] = WxFontUtils::get_font_item(*wx_font);
|
m_font_list[m_font_selected] = WxFontUtils::get_font_item(
|
||||||
if(!load_font(*wx_font)) return false;
|
*wx_font);
|
||||||
|
if (!load_font(*wx_font)) return false;
|
||||||
} else {
|
} else {
|
||||||
// can't create similar font use previous
|
// can't create similar font use previous
|
||||||
m_font_list.erase(m_font_list.begin() + m_font_selected);
|
m_font_list.erase(m_font_list.begin() + m_font_selected);
|
||||||
@ -1035,17 +1110,22 @@ void GLGizmoEmboss::create_notification_not_valid_font(
|
|||||||
m_exist_notification = true;
|
m_exist_notification = true;
|
||||||
|
|
||||||
auto type = NotificationType::UnknownFont;
|
auto type = NotificationType::UnknownFont;
|
||||||
auto level = NotificationManager::NotificationLevel::WarningNotificationLevel;
|
auto level =
|
||||||
|
NotificationManager::NotificationLevel::WarningNotificationLevel;
|
||||||
|
|
||||||
const auto& origin_family = tc.font_prop.face_name;
|
const auto &origin_family = tc.font_prop.face_name;
|
||||||
const auto& actual_family = m_font_prop.face_name;
|
const auto &actual_family = m_font_prop.face_name;
|
||||||
const auto& fi = m_font_list[m_font_selected];
|
const auto &fi = m_font_list[m_font_selected];
|
||||||
|
|
||||||
const std::string& origin_font_name = origin_family.has_value()? *origin_family : tc.font_item.path;
|
const std::string &origin_font_name = origin_family.has_value() ?
|
||||||
const std::string &actual_font_name = actual_family.has_value()? *actual_family : fi.name;
|
*origin_family :
|
||||||
|
tc.font_item.path;
|
||||||
|
const std::string &actual_font_name = actual_family.has_value() ?
|
||||||
|
*actual_family :
|
||||||
|
fi.name;
|
||||||
|
|
||||||
std::string text = GUI::format(_L(
|
std::string text =
|
||||||
"Can't load exactly same font(\"%1%\"), "
|
GUI::format(_L("Can't load exactly same font(\"%1%\"), "
|
||||||
"Aplication select similar one(\"%2%\"). "
|
"Aplication select similar one(\"%2%\"). "
|
||||||
"When you edit text, similar font will be applied."),
|
"When you edit text, similar font will be applied."),
|
||||||
origin_font_name, actual_font_name);
|
origin_font_name, actual_font_name);
|
||||||
@ -1053,7 +1133,8 @@ void GLGizmoEmboss::create_notification_not_valid_font(
|
|||||||
notification_manager->push_notification(type, level, text);
|
notification_manager->push_notification(type, level, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::remove_notification_not_valid_font() {
|
void GLGizmoEmboss::remove_notification_not_valid_font()
|
||||||
|
{
|
||||||
if (!m_exist_notification) return;
|
if (!m_exist_notification) return;
|
||||||
m_exist_notification = false;
|
m_exist_notification = false;
|
||||||
auto type = NotificationType::UnknownFont;
|
auto type = NotificationType::UnknownFont;
|
||||||
@ -1065,8 +1146,9 @@ std::string GLGizmoEmboss::create_volume_name()
|
|||||||
{
|
{
|
||||||
const size_t &max_len = m_gui_cfg->max_count_char_in_volume_name;
|
const size_t &max_len = m_gui_cfg->max_count_char_in_volume_name;
|
||||||
return _u8L("Text") + " - " +
|
return _u8L("Text") + " - " +
|
||||||
((m_text.size() > max_len)?
|
((m_text.size() > max_len) ?
|
||||||
(m_text.substr(0, max_len - 3) + " ..") : m_text);
|
(m_text.substr(0, max_len - 3) + " ..") :
|
||||||
|
m_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoEmboss::init_icons()
|
bool GLGizmoEmboss::init_icons()
|
||||||
@ -1074,10 +1156,8 @@ bool GLGizmoEmboss::init_icons()
|
|||||||
std::string path = resources_dir() + "/icons/white/";
|
std::string path = resources_dir() + "/icons/white/";
|
||||||
|
|
||||||
// icon order has to match the enum IconType
|
// icon order has to match the enum IconType
|
||||||
std::vector<std::string> filenames = {
|
std::vector<std::string> filenames = {path + "wrench.svg",
|
||||||
path +"wrench.svg",
|
path + "delete.svg"};
|
||||||
path +"delete.svg"
|
|
||||||
};
|
|
||||||
|
|
||||||
// state order has to match the enum IconState
|
// state order has to match the enum IconState
|
||||||
std::vector<std::pair<int, bool>> states;
|
std::vector<std::pair<int, bool>> states;
|
||||||
@ -1089,7 +1169,10 @@ bool GLGizmoEmboss::init_icons()
|
|||||||
// make size pair number
|
// make size pair number
|
||||||
if (sprite_size_px % 2 != 0) ++sprite_size_px;
|
if (sprite_size_px % 2 != 0) ++sprite_size_px;
|
||||||
bool compress = false;
|
bool compress = false;
|
||||||
return m_icons_texture.load_from_svg_files_as_sprites_array(filenames, states, sprite_size_px, compress);
|
return m_icons_texture.load_from_svg_files_as_sprites_array(filenames,
|
||||||
|
states,
|
||||||
|
sprite_size_px,
|
||||||
|
compress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::draw_icon(IconType icon, IconState state)
|
void GLGizmoEmboss::draw_icon(IconType icon, IconState state)
|
||||||
@ -1108,16 +1191,12 @@ void GLGizmoEmboss::draw_icon(IconType icon, IconState state)
|
|||||||
size_t count_states = 3; // activable | hovered | disabled
|
size_t count_states = 3; // activable | hovered | disabled
|
||||||
ImVec2 icon_size(tex_width / count_states, tex_height / count_icons);
|
ImVec2 icon_size(tex_width / count_states, tex_height / count_icons);
|
||||||
|
|
||||||
ImVec2 start(
|
ImVec2 start(static_cast<unsigned>(state) * icon_size.x,
|
||||||
static_cast<unsigned>(state)*icon_size.x,
|
static_cast<unsigned>(icon) * icon_size.y);
|
||||||
static_cast<unsigned>(icon)*icon_size.y);
|
|
||||||
|
|
||||||
ImVec2 uv0(
|
ImVec2 uv0(start.x / tex_width, start.y / tex_height);
|
||||||
start.x/tex_width,
|
|
||||||
start.y/tex_height);
|
|
||||||
|
|
||||||
ImVec2 uv1(
|
ImVec2 uv1((start.x + icon_size.x) / tex_width,
|
||||||
(start.x + icon_size.x) / tex_width,
|
|
||||||
(start.y + icon_size.y) / tex_height);
|
(start.y + icon_size.y) / tex_height);
|
||||||
|
|
||||||
ImGui::Image(tex_id, icon_size, uv0, uv1);
|
ImGui::Image(tex_id, icon_size, uv0, uv1);
|
||||||
@ -1128,8 +1207,11 @@ bool GLGizmoEmboss::draw_button(IconType icon, bool disable)
|
|||||||
float line_spacing = ImGui::GetTextLineHeightWithSpacing() -
|
float line_spacing = ImGui::GetTextLineHeightWithSpacing() -
|
||||||
ImGui::GetTextLineHeight();
|
ImGui::GetTextLineHeight();
|
||||||
float cursor_pos_y = ImGui::GetCursorPosY();
|
float cursor_pos_y = ImGui::GetCursorPosY();
|
||||||
ImGui::SetCursorPosY(cursor_pos_y - line_spacing/2);
|
ImGui::SetCursorPosY(cursor_pos_y - line_spacing / 2);
|
||||||
ScopeGuard sg([cursor_pos_y]() { ImGui::SetCursorPosY(cursor_pos_y); ImGui::NewLine();});
|
ScopeGuard sg([cursor_pos_y]() {
|
||||||
|
ImGui::SetCursorPosY(cursor_pos_y);
|
||||||
|
ImGui::NewLine();
|
||||||
|
});
|
||||||
|
|
||||||
if (disable) {
|
if (disable) {
|
||||||
draw_icon(icon, IconState::disabled);
|
draw_icon(icon, IconState::disabled);
|
||||||
@ -1144,8 +1226,12 @@ bool GLGizmoEmboss::draw_button(IconType icon, bool disable)
|
|||||||
if (ImGui::IsItemClicked()) return true;
|
if (ImGui::IsItemClicked()) return true;
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
switch (icon) {
|
switch (icon) {
|
||||||
case IconType::rename: ImGui::SetTooltip(_u8L("rename").c_str()); break;
|
case IconType::rename:
|
||||||
case IconType::erase: ImGui::SetTooltip(_u8L("delete").c_str()); break;
|
ImGui::SetTooltip(_u8L("rename").c_str());
|
||||||
|
break;
|
||||||
|
case IconType::erase:
|
||||||
|
ImGui::SetTooltip(_u8L("delete").c_str());
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
// redraw image over previous
|
// redraw image over previous
|
||||||
@ -1203,16 +1289,20 @@ std::optional<FontItem> GLGizmoEmboss::get_font_item(
|
|||||||
{
|
{
|
||||||
auto path_it = app_cfg_section.find(APP_CONFIG_FONT_DESCRIPTOR);
|
auto path_it = app_cfg_section.find(APP_CONFIG_FONT_DESCRIPTOR);
|
||||||
if (path_it == app_cfg_section.end()) return {};
|
if (path_it == app_cfg_section.end()) return {};
|
||||||
const std::string& path = path_it->second;
|
const std::string &path = path_it->second;
|
||||||
|
|
||||||
auto name_it = app_cfg_section.find(APP_CONFIG_FONT_NAME);
|
auto name_it = app_cfg_section.find(APP_CONFIG_FONT_NAME);
|
||||||
static const std::string default_name = "font_name";
|
static const std::string default_name = "font_name";
|
||||||
const std::string& name = (name_it == app_cfg_section.end()) ?
|
const std::string & name = (name_it == app_cfg_section.end()) ?
|
||||||
default_name : name_it->second;
|
default_name :
|
||||||
|
name_it->second;
|
||||||
return FontItem(name, path, WxFontUtils::get_actual_type());
|
return FontItem(name, path, WxFontUtils::get_actual_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::set_font_item(AppConfig &cfg, const FontItem &fi, unsigned index) {
|
void GLGizmoEmboss::set_font_item(AppConfig & cfg,
|
||||||
|
const FontItem &fi,
|
||||||
|
unsigned index)
|
||||||
|
{
|
||||||
std::string section_name = get_app_config_font_section(index);
|
std::string section_name = get_app_config_font_section(index);
|
||||||
cfg.clear_section(section_name);
|
cfg.clear_section(section_name);
|
||||||
cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name);
|
cfg.set(section_name, APP_CONFIG_FONT_NAME, fi.name);
|
||||||
@ -1270,17 +1360,18 @@ std::optional<Emboss::Font> WxFontUtils::load_font(const wxFont &font)
|
|||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
// use file path
|
// use file path
|
||||||
const wxNativeFontInfo *info = font.GetNativeFontInfo();
|
const wxNativeFontInfo *info = font.GetNativeFontInfo();
|
||||||
if(info == nullptr) return {};
|
if (info == nullptr) return {};
|
||||||
CTFontDescriptorRef descriptor = info->GetCTFontDescriptor();
|
CTFontDescriptorRef descriptor = info->GetCTFontDescriptor();
|
||||||
CFURLRef typeref = (CFURLRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute);
|
CFURLRef typeref = (CFURLRef)
|
||||||
|
CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute);
|
||||||
CFStringRef url = CFURLGetString(typeref);
|
CFStringRef url = CFURLGetString(typeref);
|
||||||
if(url == NULL) return {};
|
if (url == NULL) return {};
|
||||||
wxString file_uri;
|
wxString file_uri;
|
||||||
wxCFTypeRef(url).GetValue(file_uri);
|
wxCFTypeRef(url).GetValue(file_uri);
|
||||||
std::string file_path(wxURI::Unescape(file_uri).c_str());
|
std::string file_path(wxURI::Unescape(file_uri).c_str());
|
||||||
size_t start = std::string("file://").size();
|
size_t start = std::string("file://").size();
|
||||||
if (file_path.empty() || file_path.size() <= start) return {};
|
if (file_path.empty() || file_path.size() <= start) return {};
|
||||||
file_path = file_path.substr(start, file_path.size()-start);
|
file_path = file_path.substr(start, file_path.size() - start);
|
||||||
return Emboss::load_font(file_path.c_str());
|
return Emboss::load_font(file_path.c_str());
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
static FontConfigHelp help;
|
static FontConfigHelp help;
|
||||||
@ -1294,7 +1385,8 @@ std::optional<Emboss::Font> WxFontUtils::load_font(const wxFont &font)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FontItem::Type WxFontUtils::get_actual_type() {
|
FontItem::Type WxFontUtils::get_actual_type()
|
||||||
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return FontItem::Type::wx_win_font_descr;
|
return FontItem::Type::wx_win_font_descr;
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
@ -1311,7 +1403,7 @@ FontItem WxFontUtils::get_font_item(const wxFont &font)
|
|||||||
std::string name = get_human_readable_name(font);
|
std::string name = get_human_readable_name(font);
|
||||||
std::string fontDesc = store_wxFont(font);
|
std::string fontDesc = store_wxFont(font);
|
||||||
FontItem::Type type = get_actual_type();
|
FontItem::Type type = get_actual_type();
|
||||||
//wxFont f = font; // copy
|
// wxFont f = font; // copy
|
||||||
return FontItem(name, fontDesc, type);
|
return FontItem(name, fontDesc, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,22 +1423,22 @@ std::string WxFontUtils::get_human_readable_name(const wxFont &font)
|
|||||||
if (!font.GetFaceName().empty()) {
|
if (!font.GetFaceName().empty()) {
|
||||||
return std::string(font.GetFaceName().c_str());
|
return std::string(font.GetFaceName().c_str());
|
||||||
} else {
|
} else {
|
||||||
return std::string((
|
return std::string((font.GetFamilyString() + " " +
|
||||||
font.GetFamilyString() + " " +
|
|
||||||
font.GetStyleString() + " " +
|
font.GetStyleString() + " " +
|
||||||
font.GetWeightString()
|
font.GetWeightString())
|
||||||
).c_str());
|
.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WxFontUtils::store_wxFont(const wxFont &font)
|
std::string WxFontUtils::store_wxFont(const wxFont &font)
|
||||||
{
|
{
|
||||||
//wxString os = wxPlatformInfo::Get().GetOperatingSystemIdName();
|
// wxString os = wxPlatformInfo::Get().GetOperatingSystemIdName();
|
||||||
wxString font_descriptor = font.GetNativeFontInfoDesc();
|
wxString font_descriptor = font.GetNativeFontInfoDesc();
|
||||||
return std::string(font_descriptor.c_str());
|
return std::string(font_descriptor.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<wxFont> WxFontUtils::load_wxFont(const std::string &font_descriptor)
|
std::optional<wxFont> WxFontUtils::load_wxFont(
|
||||||
|
const std::string &font_descriptor)
|
||||||
{
|
{
|
||||||
wxString font_descriptor_wx(font_descriptor);
|
wxString font_descriptor_wx(font_descriptor);
|
||||||
wxFont wx_font(font_descriptor_wx);
|
wxFont wx_font(font_descriptor_wx);
|
||||||
@ -1411,12 +1503,12 @@ std::optional<wxFont> WxFontUtils::create_wxFont(const FontItem &fi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Improve: load descriptor instead of store to font property to 3mf
|
// Improve: load descriptor instead of store to font property to 3mf
|
||||||
//switch (fi.type) {
|
// switch (fi.type) {
|
||||||
//case FontItem::Type::wx_lin_font_descr:
|
// case FontItem::Type::wx_lin_font_descr:
|
||||||
//case FontItem::Type::wx_win_font_descr:
|
// case FontItem::Type::wx_win_font_descr:
|
||||||
//case FontItem::Type::file_path:
|
// case FontItem::Type::file_path:
|
||||||
//case FontItem::Type::undefined:
|
// case FontItem::Type::undefined:
|
||||||
//default:
|
// default:
|
||||||
//}
|
//}
|
||||||
|
|
||||||
wxFont font(info);
|
wxFont font(info);
|
||||||
@ -1424,7 +1516,8 @@ std::optional<wxFont> WxFontUtils::create_wxFont(const FontItem &fi,
|
|||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WxFontUtils::update_property(FontProp &font_prop, const wxFont &font) {
|
void WxFontUtils::update_property(FontProp &font_prop, const wxFont &font)
|
||||||
|
{
|
||||||
// The point size is defined as 1/72 of the Anglo-Saxon inch (25.4 mm): it
|
// The point size is defined as 1/72 of the Anglo-Saxon inch (25.4 mm): it
|
||||||
// is approximately 0.0139 inch or 352.8 um. But it is too small, so I
|
// is approximately 0.0139 inch or 352.8 um. But it is too small, so I
|
||||||
// decide use point size as mm for emboss
|
// decide use point size as mm for emboss
|
||||||
@ -1502,12 +1595,10 @@ ExPolygons NSVGUtils::to_ExPolygons(NSVGimage *image,
|
|||||||
polygon.points.emplace_back(path->pts[0], path->pts[1]);
|
polygon.points.emplace_back(path->pts[0], path->pts[1]);
|
||||||
for (size_t i = 0; i < path->npts - 1; i += 3) {
|
for (size_t i = 0; i < path->npts - 1; i += 3) {
|
||||||
float *p = &path->pts[i * 2];
|
float *p = &path->pts[i * 2];
|
||||||
Vec2f
|
Vec2f p1(p[0], p[1]), p2(p[2], p[3]), p3(p[4], p[5]),
|
||||||
p1(p[0], p[1]),
|
|
||||||
p2(p[2], p[3]),
|
|
||||||
p3(p[4], p[5]),
|
|
||||||
p4(p[6], p[7]);
|
p4(p[6], p[7]);
|
||||||
flatten_cubic_bez(polygon, tessTol, p1, p2, p3, p4, max_level);
|
flatten_cubic_bez(polygon, tessTol, p1, p2, p3, p4,
|
||||||
|
max_level);
|
||||||
}
|
}
|
||||||
if (path->closed) {
|
if (path->closed) {
|
||||||
polygons.push_back(polygon);
|
polygons.push_back(polygon);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "admesh/stl.h" // indexed_triangle_set
|
#include "admesh/stl.h" // indexed_triangle_set
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "libslic3r/Emboss.hpp"
|
#include "libslic3r/Emboss.hpp"
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
@ -26,7 +27,7 @@ public:
|
|||||||
virtual ~GLGizmoEmboss();
|
virtual ~GLGizmoEmboss();
|
||||||
|
|
||||||
void set_volume_type(ModelVolumeType volume_type);
|
void set_volume_type(ModelVolumeType volume_type);
|
||||||
|
void set_fine_position();
|
||||||
protected:
|
protected:
|
||||||
virtual bool on_init() override;
|
virtual bool on_init() override;
|
||||||
virtual std::string on_get_name() const override;
|
virtual std::string on_get_name() const override;
|
||||||
@ -91,7 +92,15 @@ private:
|
|||||||
int min_imgui_font_size = 18;
|
int min_imgui_font_size = 18;
|
||||||
int max_imgui_font_size = 60;
|
int max_imgui_font_size = 60;
|
||||||
|
|
||||||
|
bool draw_advanced = false;
|
||||||
|
ImVec2 minimal_window_size = ImVec2(174, 202);
|
||||||
|
ImVec2 minimal_window_size_with_advance = ImVec2(174, 302);
|
||||||
|
|
||||||
|
// setted only when wanted to use - not all the time
|
||||||
|
std::optional<ImVec2> offset;
|
||||||
|
|
||||||
// Zero means it is calculated in init function
|
// Zero means it is calculated in init function
|
||||||
|
float advanced_input_width = 0.f;
|
||||||
float combo_font_width = 0.f;
|
float combo_font_width = 0.f;
|
||||||
float rename_pos_x = 0.f;
|
float rename_pos_x = 0.f;
|
||||||
float delete_pos_x = 0.f;
|
float delete_pos_x = 0.f;
|
||||||
|
@ -32,6 +32,11 @@
|
|||||||
#include "nanosvg/nanosvg.h"
|
#include "nanosvg/nanosvg.h"
|
||||||
#include "nanosvg/nanosvgrast.h"
|
#include "nanosvg/nanosvgrast.h"
|
||||||
|
|
||||||
|
// suggest location
|
||||||
|
#include "slic3r/GUI/GLCanvas3D.hpp"
|
||||||
|
#include "slic3r/GUI/Plater.hpp"
|
||||||
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
@ -957,6 +962,74 @@ bool ImGuiWrapper::want_any_input() const
|
|||||||
return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput;
|
return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImVec2 ImGuiWrapper::suggest_location(const ImVec2 & dialog_size,
|
||||||
|
const Slic3r::Polygon &interest)
|
||||||
|
{
|
||||||
|
Plater * plater = wxGetApp().plater();
|
||||||
|
GLCanvas3D *canvas = plater->get_current_canvas3D();
|
||||||
|
|
||||||
|
// IMPROVE 1: do not select place over menu
|
||||||
|
// BoundingBox top_menu;
|
||||||
|
// GLGizmosManager &gizmo_mng = canvas->get_gizmos_manager();
|
||||||
|
// BoundingBox side_menu; // gizmo_mng.get_size();
|
||||||
|
// BoundingBox left_bottom_menu; // is permanent?
|
||||||
|
// NotificationManager *notify_mng = plater->get_notification_manager();
|
||||||
|
// BoundingBox notifications; // notify_mng->get_size();
|
||||||
|
// m_window_width, m_window_height + position
|
||||||
|
|
||||||
|
// IMPROVE 2: use polygon of interest not only bounding box
|
||||||
|
BoundingBox bb(interest.points);
|
||||||
|
Point center = bb.center(); // interest.centroid();
|
||||||
|
|
||||||
|
// area size
|
||||||
|
Size size = canvas->get_canvas_size();
|
||||||
|
Point window_center(size.get_width() / 2, size.get_height() / 2);
|
||||||
|
|
||||||
|
// mov on side
|
||||||
|
Point bb_half_size = (bb.max - bb.min) / 2;
|
||||||
|
Point diff_center = window_center - center;
|
||||||
|
Vec2d diff_norm(diff_center.x() / (double) bb_half_size.x(),
|
||||||
|
diff_center.y() / (double) bb_half_size.y());
|
||||||
|
if (diff_norm.x() > 1.) diff_norm.x() = 1.;
|
||||||
|
if (diff_norm.x() < -1.) diff_norm.x() = -1.;
|
||||||
|
if (diff_norm.y() > 1.) diff_norm.y() = 1.;
|
||||||
|
if (diff_norm.y() < -1.) diff_norm.y() = -1.;
|
||||||
|
|
||||||
|
Vec2d abs_diff(abs(diff_norm.x()), abs(diff_norm.y()));
|
||||||
|
if (abs_diff.x() < 1. && abs_diff.y() < 1.) {
|
||||||
|
if (abs_diff.x() > abs_diff.y())
|
||||||
|
diff_norm.x() = (diff_norm.x() < 0.) ? (-1.) : 1.;
|
||||||
|
else
|
||||||
|
diff_norm.y() = (diff_norm.y() < 0.) ? (-1.) : 1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point half_dialog_size(dialog_size.x / 2., dialog_size.y / 2.);
|
||||||
|
Point move_size = bb_half_size + half_dialog_size;
|
||||||
|
Point offseted_center = center - half_dialog_size;
|
||||||
|
return ImVec2(offseted_center.x() + diff_norm.x() * move_size.x(),
|
||||||
|
offseted_center.y() + diff_norm.y() * move_size.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiWrapper::draw(
|
||||||
|
const Polygon &polygon,
|
||||||
|
ImDrawList * draw_list /* = ImGui::GetOverlayDrawList()*/,
|
||||||
|
ImU32 color /* = ImGui::GetColorU32(COL_ORANGE_LIGHT)*/,
|
||||||
|
float thickness /* = 3.f*/)
|
||||||
|
{
|
||||||
|
// minimal one line consist of 2 points
|
||||||
|
if (polygon.size() < 2) return;
|
||||||
|
// need a place to draw
|
||||||
|
if (draw_list == nullptr) return;
|
||||||
|
|
||||||
|
const Point *prev_point = &polygon.points.back();
|
||||||
|
for (const Point &point : polygon.points) {
|
||||||
|
ImVec2 p1(prev_point->x(), prev_point->y());
|
||||||
|
ImVec2 p2(point.x(), point.y());
|
||||||
|
draw_list->AddLine(p1, p2, color, thickness);
|
||||||
|
prev_point = &point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static const ImWchar ranges_keyboard_shortcuts[] =
|
static const ImWchar ranges_keyboard_shortcuts[] =
|
||||||
{
|
{
|
||||||
|
@ -107,6 +107,31 @@ public:
|
|||||||
bool want_text_input() const;
|
bool want_text_input() const;
|
||||||
bool want_any_input() const;
|
bool want_any_input() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Suggest loacation of dialog window,
|
||||||
|
/// dependent on actual visible thing on platter
|
||||||
|
/// like Gizmo menu size, notifications, ...
|
||||||
|
/// To be near of polygon interest and not over it.
|
||||||
|
/// And also not out of visible area.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dialog_size">Define width and height of diaog window</param>
|
||||||
|
/// <param name="interest">Area of interest. Result should be close to it</param>
|
||||||
|
/// <returns>Suggestion for dialog offest</returns>
|
||||||
|
static ImVec2 suggest_location(const ImVec2 & dialog_size,
|
||||||
|
const Slic3r::Polygon &interest);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Visualization of polygon
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="polygon">Define what to draw</param>
|
||||||
|
/// <param name="draw_list">Define where to draw it</param>
|
||||||
|
/// <param name="color">Color of polygon</param>
|
||||||
|
/// <param name="thickness">Width of polygon line</param>
|
||||||
|
static void draw(const Polygon &polygon,
|
||||||
|
ImDrawList * draw_list = ImGui::GetOverlayDrawList(),
|
||||||
|
ImU32 color = ImGui::GetColorU32(COL_ORANGE_LIGHT),
|
||||||
|
float thickness = 3.f);
|
||||||
|
|
||||||
static const ImVec4 COL_GREY_DARK;
|
static const ImVec4 COL_GREY_DARK;
|
||||||
static const ImVec4 COL_GREY_LIGHT;
|
static const ImVec4 COL_GREY_LIGHT;
|
||||||
static const ImVec4 COL_ORANGE_DARK;
|
static const ImVec4 COL_ORANGE_DARK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user