mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-13 09:41:50 +08:00
add NSVG utils into cmakelists
Move trunc to ImGuiWrapper
This commit is contained in:
parent
35b54eb455
commit
1259b878fb
@ -166,6 +166,8 @@ add_library(libslic3r STATIC
|
|||||||
MultiPoint.cpp
|
MultiPoint.cpp
|
||||||
MultiPoint.hpp
|
MultiPoint.hpp
|
||||||
MutablePriorityQueue.hpp
|
MutablePriorityQueue.hpp
|
||||||
|
NSVGUtils.cpp
|
||||||
|
NSVGUtils.hpp
|
||||||
ObjectID.cpp
|
ObjectID.cpp
|
||||||
ObjectID.hpp
|
ObjectID.hpp
|
||||||
PerimeterGenerator.cpp
|
PerimeterGenerator.cpp
|
||||||
|
@ -47,12 +47,6 @@ GLGizmoEmboss::GLGizmoEmboss(GLCanvas3D &parent)
|
|||||||
, 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_rotate_gizmo(parent, GLGizmoRotate::Axis::Z) // grab id = 2 (Z axis)
|
, m_rotate_gizmo(parent, GLGizmoRotate::Axis::Z) // grab id = 2 (Z axis)
|
||||||
, m_move_grabber(
|
|
||||||
GLModel(),
|
|
||||||
0, // grab id
|
|
||||||
DEFAULT_BASE_COLOR,
|
|
||||||
DEFAULT_DRAG_COLOR
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
m_rotate_gizmo.set_group_id(0);
|
m_rotate_gizmo.set_group_id(0);
|
||||||
// TODO: add suggestion to use https://fontawesome.com/
|
// TODO: add suggestion to use https://fontawesome.com/
|
||||||
@ -135,7 +129,7 @@ void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mous
|
|||||||
|
|
||||||
int instance_idx = selection.get_instance_idx();
|
int instance_idx = selection.get_instance_idx();
|
||||||
if (instance_idx < 0) return;
|
if (instance_idx < 0) return;
|
||||||
assert(instance_idx < mo->instances.size());
|
assert(static_cast<size_t>(instance_idx) < mo->instances.size());
|
||||||
|
|
||||||
const ModelInstance *mi = mo->instances[instance_idx];
|
const ModelInstance *mi = mo->instances[instance_idx];
|
||||||
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
const Transform3d instance_trafo = mi->get_transformation().get_matrix();
|
||||||
@ -252,8 +246,6 @@ bool GLGizmoEmboss::on_init()
|
|||||||
std::array<float, 4> gray_color = {.6f, .6f, .6f, .3f};
|
std::array<float, 4> gray_color = {.6f, .6f, .6f, .3f};
|
||||||
m_rotate_gizmo.set_highlight_color(gray_color);
|
m_rotate_gizmo.set_highlight_color(gray_color);
|
||||||
|
|
||||||
m_move_grabber.shape.init_from(its_make_cube(1., 1., 1.));
|
|
||||||
|
|
||||||
m_shortcut_key = WXK_CONTROL_T;
|
m_shortcut_key = WXK_CONTROL_T;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -267,7 +259,6 @@ void GLGizmoEmboss::on_render() {
|
|||||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||||
|
|
||||||
m_rotate_gizmo.render();
|
m_rotate_gizmo.render();
|
||||||
m_move_grabber.shape.render();
|
|
||||||
|
|
||||||
if (!m_preview.is_initialized()) return;
|
if (!m_preview.is_initialized()) return;
|
||||||
|
|
||||||
@ -844,7 +835,7 @@ 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,
|
std::string current_name = ImGuiWrapper::trunc(m_font_list[m_font_selected].name,
|
||||||
max_width);
|
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())) {
|
||||||
@ -872,7 +863,7 @@ void GLGizmoEmboss::draw_font_list()
|
|||||||
|
|
||||||
for (FontItem &f : m_font_list) {
|
for (FontItem &f : m_font_list) {
|
||||||
ImGui::PushID(f.name.c_str());
|
ImGui::PushID(f.name.c_str());
|
||||||
std::string name = imgui_trunc(f.name, max_width);
|
std::string name = ImGuiWrapper::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 =
|
auto flags =
|
||||||
@ -1544,36 +1535,6 @@ std::string GLGizmoEmboss::get_file_name(const std::string &file_path)
|
|||||||
return file_path.substr(offset, count);
|
return file_path.substr(offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLGizmoEmboss::imgui_trunc(const std::string &text, float width)
|
|
||||||
{
|
|
||||||
static const char *tail = " ..";
|
|
||||||
float tail_width = ImGui::CalcTextSize(tail).x;
|
|
||||||
float text_width = ImGui::CalcTextSize(text.c_str()).x;
|
|
||||||
if (text_width < width) return text;
|
|
||||||
float letter_width = ImGui::CalcTextSize("n").x;
|
|
||||||
float allowed_width = width - tail_width;
|
|
||||||
unsigned count_letter = static_cast<unsigned>(allowed_width /
|
|
||||||
letter_width);
|
|
||||||
text_width = ImGui::CalcTextSize(text.substr(0, count_letter).c_str()).x;
|
|
||||||
if (text_width < allowed_width) {
|
|
||||||
// increase letter count
|
|
||||||
do {
|
|
||||||
++count_letter;
|
|
||||||
text_width =
|
|
||||||
ImGui::CalcTextSize(text.substr(0, count_letter).c_str()).x;
|
|
||||||
} while (text_width < allowed_width);
|
|
||||||
--count_letter;
|
|
||||||
} else {
|
|
||||||
// decrease letter count
|
|
||||||
do {
|
|
||||||
--count_letter;
|
|
||||||
text_width =
|
|
||||||
ImGui::CalcTextSize(text.substr(0, count_letter).c_str()).x;
|
|
||||||
} while (text_width > allowed_width);
|
|
||||||
}
|
|
||||||
return text.substr(0, count_letter) + tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Slic3r::GUI {
|
namespace Slic3r::GUI {
|
||||||
|
|
||||||
class Priv
|
class Priv
|
||||||
@ -1782,75 +1743,5 @@ void GLGizmoEmboss::update_emboss_volume(TriangleMesh && mesh,
|
|||||||
canvas->reload_scene(true);
|
canvas->reload_scene(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NSVGUtils::flatten_cubic_bez(Polygon &polygon,
|
|
||||||
float tessTol,
|
|
||||||
Vec2f p1,
|
|
||||||
Vec2f p2,
|
|
||||||
Vec2f p3,
|
|
||||||
Vec2f p4,
|
|
||||||
int level)
|
|
||||||
{
|
|
||||||
Vec2f p12 = (p1 + p2) * 0.5f;
|
|
||||||
Vec2f p23 = (p2 + p3) * 0.5f;
|
|
||||||
Vec2f p34 = (p3 + p4) * 0.5f;
|
|
||||||
Vec2f p123 = (p12 + p23) * 0.5f;
|
|
||||||
|
|
||||||
Vec2f pd = p4 - p1;
|
|
||||||
Vec2f pd2 = p2 - p4;
|
|
||||||
float d2 = std::abs(pd2.x() * pd.y() - pd2.y() * pd.x());
|
|
||||||
Vec2f pd3 = p3 - p4;
|
|
||||||
float d3 = std::abs(pd3.x() * pd.y() - pd3.y() * pd.x());
|
|
||||||
float d23 = d2 + d3;
|
|
||||||
|
|
||||||
if ((d23 * d23) < tessTol * (pd.x() * pd.x() + pd.y() * pd.y())) {
|
|
||||||
polygon.points.emplace_back(p4.x(), p4.y());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
--level;
|
|
||||||
if (level == 0) return;
|
|
||||||
Vec2f p234 = (p23 + p34) * 0.5f;
|
|
||||||
Vec2f p1234 = (p123 + p234) * 0.5f;
|
|
||||||
flatten_cubic_bez(polygon, tessTol, p1, p12, p123, p1234, level);
|
|
||||||
flatten_cubic_bez(polygon, tessTol, p1234, p234, p34, p4, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExPolygons NSVGUtils::to_ExPolygons(NSVGimage *image,
|
|
||||||
float tessTol,
|
|
||||||
int max_level)
|
|
||||||
{
|
|
||||||
Polygons polygons;
|
|
||||||
for (NSVGshape *shape = image->shapes; shape != NULL;
|
|
||||||
shape = shape->next) {
|
|
||||||
if (!(shape->flags & NSVG_FLAGS_VISIBLE)) continue;
|
|
||||||
Slic3r::Polygon polygon;
|
|
||||||
if (shape->fill.type != NSVG_PAINT_NONE) {
|
|
||||||
for (NSVGpath *path = shape->paths; path != NULL;
|
|
||||||
path = path->next) {
|
|
||||||
// Flatten path
|
|
||||||
polygon.points.emplace_back(path->pts[0], path->pts[1]);
|
|
||||||
for (size_t i = 0; i < path->npts - 1; i += 3) {
|
|
||||||
float *p = &path->pts[i * 2];
|
|
||||||
Vec2f p1(p[0], p[1]), p2(p[2], p[3]), p3(p[4], p[5]),
|
|
||||||
p4(p[6], p[7]);
|
|
||||||
flatten_cubic_bez(polygon, tessTol, p1, p2, p3, p4,
|
|
||||||
max_level);
|
|
||||||
}
|
|
||||||
if (path->closed) {
|
|
||||||
polygons.push_back(polygon);
|
|
||||||
polygon = Slic3r::Polygon();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
polygons.push_back(polygon);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix Y axis
|
|
||||||
for (Polygon &polygon : polygons)
|
|
||||||
for (Point &p : polygon.points) p.y() *= -1;
|
|
||||||
|
|
||||||
return Slic3r::union_ex(polygons);
|
|
||||||
}
|
|
||||||
|
|
||||||
// any existing icon filename to not influence GUI
|
// any existing icon filename to not influence GUI
|
||||||
const std::string GLGizmoEmboss::M_ICON_FILENAME = "cut.svg";
|
const std::string GLGizmoEmboss::M_ICON_FILENAME = "cut.svg";
|
||||||
|
@ -159,30 +159,6 @@ private:
|
|||||||
// Rotation gizmo
|
// Rotation gizmo
|
||||||
GLGizmoRotate m_rotate_gizmo;
|
GLGizmoRotate m_rotate_gizmo;
|
||||||
|
|
||||||
struct MyGrabber
|
|
||||||
{
|
|
||||||
GLModel shape;
|
|
||||||
int grab_id;
|
|
||||||
std::array<float, 4> color;
|
|
||||||
std::array<float, 4> hovered_color;
|
|
||||||
|
|
||||||
MyGrabber(GLModel shape,
|
|
||||||
int grab_id,
|
|
||||||
std::array<float, 4> color,
|
|
||||||
std::array<float, 4> hovered_color)
|
|
||||||
: shape(shape)
|
|
||||||
, grab_id(grab_id)
|
|
||||||
, color(color)
|
|
||||||
, hovered_color(hovered_color)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void render() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Translate on surface of model
|
|
||||||
MyGrabber m_move_grabber;
|
|
||||||
|
|
||||||
// preview position
|
// preview position
|
||||||
GLModel m_preview;
|
GLModel m_preview;
|
||||||
Transform3d m_preview_trmat;
|
Transform3d m_preview_trmat;
|
||||||
@ -234,8 +210,6 @@ public:
|
|||||||
// TODO: move to file utils
|
// TODO: move to file utils
|
||||||
static std::string get_file_name(const std::string &file_path);
|
static std::string get_file_name(const std::string &file_path);
|
||||||
|
|
||||||
// TODO: Move to imgui utils
|
|
||||||
std::string imgui_trunc(const std::string &text, float width);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r::GUI
|
} // namespace Slic3r::GUI
|
||||||
|
@ -1041,6 +1041,45 @@ bool ImGuiWrapper::want_any_input() const
|
|||||||
return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput;
|
return io.WantCaptureMouse || io.WantCaptureKeyboard || io.WantTextInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ImGuiWrapper::trunc(const std::string &text,
|
||||||
|
float width,
|
||||||
|
const char * tail)
|
||||||
|
{
|
||||||
|
float text_width = ImGui::CalcTextSize(text.c_str()).x;
|
||||||
|
if (text_width < width) return text;
|
||||||
|
float letter_width = ImGui::CalcTextSize("n").x; // average letter width
|
||||||
|
assert(width > letter_width);
|
||||||
|
if (width < letter_width) return "Error: too small widht to trunc";
|
||||||
|
float tail_width = ImGui::CalcTextSize(tail).x;
|
||||||
|
assert(width > tail_width);
|
||||||
|
if (width < tail_width) return "Error: Can't add tail and not be under wanted width.";
|
||||||
|
float allowed_width = width - tail_width;
|
||||||
|
unsigned count_letter = static_cast<unsigned>(allowed_width / letter_width);
|
||||||
|
std::string result_text = text.substr(0, count_letter);
|
||||||
|
text_width = ImGui::CalcTextSize(result_text.c_str()).x;
|
||||||
|
if (text_width < allowed_width) {
|
||||||
|
// increase letter count
|
||||||
|
while (true) {
|
||||||
|
++count_letter;
|
||||||
|
std::string act_text = text.substr(0, count_letter);
|
||||||
|
text_width = ImGui::CalcTextSize(act_text.c_str()).x;
|
||||||
|
if (text_width < allowed_width) return result_text;
|
||||||
|
result_text = std::move(act_text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// decrease letter count
|
||||||
|
while (true) {
|
||||||
|
--count_letter;
|
||||||
|
result_text = text.substr(0, count_letter);
|
||||||
|
text_width = ImGui::CalcTextSize(result_text.c_str()).x;
|
||||||
|
if (text_width > allowed_width) return result_text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
return "Should not be accessible";
|
||||||
|
}
|
||||||
|
|
||||||
ImVec2 ImGuiWrapper::suggest_location(const ImVec2 & dialog_size,
|
ImVec2 ImGuiWrapper::suggest_location(const ImVec2 & dialog_size,
|
||||||
const Slic3r::Polygon &interest)
|
const Slic3r::Polygon &interest)
|
||||||
{
|
{
|
||||||
|
@ -128,6 +128,19 @@ public:
|
|||||||
bool want_text_input() const;
|
bool want_text_input() const;
|
||||||
bool want_any_input() const;
|
bool want_any_input() const;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncate text by ImGui draw function to specific width
|
||||||
|
/// NOTE 1: ImGui must be initialized
|
||||||
|
/// NOTE 2: Calculation for actual acive imgui font
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">text to be truncated</param>
|
||||||
|
/// <param name="width">maximal widht before truncate</param>
|
||||||
|
/// <param name="tail">strung put on end of text to be visible truncation</param>
|
||||||
|
/// <returns>Truncated text</returns>
|
||||||
|
static std::string trunc(const std::string &text,
|
||||||
|
float width,
|
||||||
|
const char * tail = " ..");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Suggest loacation of dialog window,
|
/// Suggest loacation of dialog window,
|
||||||
/// dependent on actual visible thing on platter
|
/// dependent on actual visible thing on platter
|
||||||
|
Loading…
x
Reference in New Issue
Block a user