mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-02-03 01:18:44 +03:00
PRUSA 2.7.0
This commit is contained in:
@@ -228,6 +228,7 @@ GLGizmoCut3D::GLGizmoCut3D(GLCanvas3D& parent, const std::string& icon_filename,
|
||||
{"Shape" , _u8L("Shape")},
|
||||
{"Depth" , _u8L("Depth")},
|
||||
{"Size" , _u8L("Size")},
|
||||
{"Rotation" , _u8L("Rotation")},
|
||||
{"Groove" , _u8L("Groove")},
|
||||
{"Width" , _u8L("Width")},
|
||||
{"Flap Angle" , _u8L("Flap Angle")},
|
||||
@@ -559,10 +560,10 @@ bool GLGizmoCut3D::render_double_input(const std::string& label, double& value_i
|
||||
|
||||
bool GLGizmoCut3D::render_slider_double_input(const std::string& label, float& value_in, float& tolerance_in, float min_val/* = -0.1f*/, float max_tolerance/* = -0.1f*/)
|
||||
{
|
||||
constexpr float UndefMinVal = -0.1f;
|
||||
static constexpr const float UndefMinVal = -0.1f;
|
||||
const float f_mm_to_in = static_cast<float>(ObjectManipulation::mm_to_in);
|
||||
|
||||
auto render_slider = [this, UndefMinVal, f_mm_to_in]
|
||||
auto render_slider = [this, f_mm_to_in]
|
||||
(const std::string& label, float& val, float def_val, float max_val, const wxString& tooltip) {
|
||||
float min_val = val < 0.f ? UndefMinVal : def_val;
|
||||
float value = val;
|
||||
@@ -2326,6 +2327,10 @@ void GLGizmoCut3D::render_connectors_input_window(CutConnectors &connectors)
|
||||
connectors[idx].radius_tolerance = 0.5f * m_connector_size_tolerance;
|
||||
});
|
||||
|
||||
if (render_angle_input(m_labels_map["Rotation"], m_connector_angle, 0.f, 0.f, 180.f))
|
||||
apply_selected_connectors([this, &connectors](size_t idx) {
|
||||
connectors[idx].z_angle = m_connector_angle;
|
||||
});
|
||||
if (m_connector_type == CutConnectorType::Snap) {
|
||||
render_snap_specific_input(_u8L("Bulge"), _L("Bulge proportion related to radius"), m_snap_bulge_proportion, 0.15f, 5.f, 100.f * m_snap_space_proportion);
|
||||
render_snap_specific_input(_u8L("Space"), _L("Space proportion related to radius"), m_snap_space_proportion, 0.3f, 10.f, 50.f);
|
||||
@@ -2535,7 +2540,7 @@ void GLGizmoCut3D::render_groove_float_input(const std::string& label, float& in
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_groove_angle_input(const std::string& label, float& in_val, const float& init_val, float min_val, float max_val)
|
||||
bool GLGizmoCut3D::render_angle_input(const std::string& label, float& in_val, const float& init_val, float min_val, float max_val)
|
||||
{
|
||||
bool is_changed{ false };
|
||||
|
||||
@@ -2548,13 +2553,15 @@ void GLGizmoCut3D::render_groove_angle_input(const std::string& label, float& in
|
||||
const float old_val = val;
|
||||
|
||||
const std::string format = "%.0f " + _u8L("°");
|
||||
m_imgui->slider_float(("##groove_" + label).c_str(), &val, min_val, max_val, format.c_str(), 1.f, true, from_u8(label));
|
||||
m_imgui->slider_float(("##angle_" + label).c_str(), &val, min_val, max_val, format.c_str(), 1.f, true, from_u8(label));
|
||||
|
||||
m_is_slider_editing_done |= m_imgui->get_last_slider_status().deactivated_after_edit;
|
||||
if (!is_approx(old_val, val)) {
|
||||
if (m_imgui->get_last_slider_status().can_take_snapshot) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", _L("Groove change"), label), UndoRedo::SnapshotType::GizmoAction);
|
||||
// TRN: This is an entry in the Undo/Redo stack. The whole line will be 'Edited: (name of whatever was edited)'.
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", _L("Edited"), label), UndoRedo::SnapshotType::GizmoAction);
|
||||
m_imgui->get_last_slider_status().invalidate_snapshot();
|
||||
if (m_mode == size_t(CutMode::cutTongueAndGroove))
|
||||
m_groove_editing = true;
|
||||
}
|
||||
in_val = deg2rad(val);
|
||||
@@ -2565,14 +2572,19 @@ void GLGizmoCut3D::render_groove_angle_input(const std::string& label, float& in
|
||||
|
||||
m_imgui->disabled_begin(is_approx(in_val, init_val));
|
||||
const std::string act_name = _u8L("Reset");
|
||||
if (render_reset_button(("##groove_" + label + act_name).c_str(), act_name)) {
|
||||
if (render_reset_button(("##angle_" + label + act_name).c_str(), act_name)) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), format_wxstr("%1%: %2%", act_name, label), UndoRedo::SnapshotType::GizmoAction);
|
||||
in_val = init_val;
|
||||
is_changed = true;
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
|
||||
if (is_changed) {
|
||||
return is_changed;
|
||||
}
|
||||
|
||||
void GLGizmoCut3D::render_groove_angle_input(const std::string& label, float& in_val, const float& init_val, float min_val, float max_val)
|
||||
{
|
||||
if (render_angle_input(label, in_val, init_val, min_val, max_val)) {
|
||||
update_plane_model();
|
||||
reset_cut_by_contours();
|
||||
}
|
||||
@@ -2790,6 +2802,8 @@ void GLGizmoCut3D::validate_connector_settings()
|
||||
m_connector_size = 2.5f;
|
||||
if (m_connector_size_tolerance < 0.f)
|
||||
m_connector_size_tolerance = 0.f;
|
||||
if (m_connector_angle < 0.f || m_connector_angle > float(PI) )
|
||||
m_connector_angle = 0.f;
|
||||
|
||||
if (m_connector_type == CutConnectorType::Undef)
|
||||
m_connector_type = CutConnectorType::Plug;
|
||||
@@ -2809,6 +2823,7 @@ void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors)
|
||||
float depth_ratio_tolerance { UndefFloat };
|
||||
float radius { UndefFloat };
|
||||
float radius_tolerance { UndefFloat };
|
||||
float angle { UndefFloat };
|
||||
CutConnectorType type { CutConnectorType::Undef };
|
||||
CutConnectorStyle style { CutConnectorStyle::Undef };
|
||||
CutConnectorShape shape { CutConnectorShape::Undef };
|
||||
@@ -2822,6 +2837,7 @@ void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors)
|
||||
depth_ratio_tolerance = connector.height_tolerance;
|
||||
radius = connector.radius;
|
||||
radius_tolerance = connector.radius_tolerance;
|
||||
angle = connector.z_angle;
|
||||
type = connector.attribs.type;
|
||||
style = connector.attribs.style;
|
||||
shape = connector.attribs.shape;
|
||||
@@ -2839,6 +2855,8 @@ void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors)
|
||||
radius = UndefFloat;
|
||||
if (!is_approx(radius_tolerance, connector.radius_tolerance))
|
||||
radius_tolerance = UndefFloat;
|
||||
if (!is_approx(angle, connector.z_angle))
|
||||
angle = UndefFloat;
|
||||
|
||||
if (type != connector.attribs.type)
|
||||
type = CutConnectorType::Undef;
|
||||
@@ -2854,6 +2872,7 @@ void GLGizmoCut3D::init_input_window_data(CutConnectors &connectors)
|
||||
m_connector_size = 2.f * radius;
|
||||
m_connector_size_tolerance = 2.f * radius_tolerance;
|
||||
m_connector_type = type;
|
||||
m_connector_angle = angle;
|
||||
m_connector_style = int(style);
|
||||
m_connector_shape_id = int(shape);
|
||||
}
|
||||
@@ -3020,7 +3039,7 @@ void GLGizmoCut3D::toggle_model_objects_visibility()
|
||||
{
|
||||
bool has_active_volume = false;
|
||||
std::vector<std::shared_ptr<SceneRaycasterItem>>* raycasters = m_parent.get_raycasters_for_picking(SceneRaycaster::EType::Volume);
|
||||
for (const auto raycaster : *raycasters)
|
||||
for (const std::shared_ptr<SceneRaycasterItem> &raycaster : *raycasters)
|
||||
if (raycaster->is_active()) {
|
||||
has_active_volume = true;
|
||||
break;
|
||||
@@ -3106,6 +3125,7 @@ void GLGizmoCut3D::render_connectors()
|
||||
pos += 0.05 * m_clp_normal;
|
||||
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * translation_transform(pos) * m_rotation_m *
|
||||
rotation_transform(-connector.z_angle * Vec3d::UnitZ()) *
|
||||
scale_transform(Vec3f(connector.radius, connector.radius, height).cast<double>());
|
||||
|
||||
render_model(m_shapes[connector.attribs].model, render_color, view_model_matrix);
|
||||
@@ -3232,6 +3252,31 @@ void update_object_cut_id(CutObjectBase& cut_id, ModelObjectCutAttributes attrib
|
||||
}
|
||||
}
|
||||
|
||||
static void check_objects_after_cut(const ModelObjectPtrs& objects)
|
||||
{
|
||||
std::vector<std::string> err_objects_names;
|
||||
for (const ModelObject* object : objects) {
|
||||
std::vector<std::string> connectors_names;
|
||||
connectors_names.reserve(object->volumes.size());
|
||||
for (const ModelVolume* vol : object->volumes)
|
||||
if (vol->cut_info.is_connector)
|
||||
connectors_names.push_back(vol->name);
|
||||
const size_t connectors_count = connectors_names.size();
|
||||
sort_remove_duplicates(connectors_names);
|
||||
if (connectors_count != connectors_names.size())
|
||||
err_objects_names.push_back(object->name);
|
||||
}
|
||||
if (err_objects_names.empty())
|
||||
return;
|
||||
|
||||
wxString names = from_u8(err_objects_names[0]);
|
||||
for (size_t i = 1; i < err_objects_names.size(); i++)
|
||||
names += ", " + from_u8(err_objects_names[i]);
|
||||
WarningDialog(wxGetApp().plater(), format_wxstr("Objects(%1%) have duplicated connectors. "
|
||||
"Some connectors may be missing in slicing result.\n"
|
||||
"Please report to PrusaSlicer team in which scenario this issue happened.\n"
|
||||
"Thank you.", names)).ShowModal();
|
||||
}
|
||||
void synchronize_model_after_cut(Model& model, const CutObjectBase& cut_id)
|
||||
{
|
||||
for (ModelObject* obj : model.objects)
|
||||
@@ -3296,6 +3341,7 @@ void GLGizmoCut3D::perform_cut(const Selection& selection)
|
||||
const ModelObjectPtrs& new_objects = cut_by_contour ? cut.perform_by_contour(m_part_selection.get_cut_parts(), dowels_count):
|
||||
cut_with_groove ? cut.perform_with_groove(m_groove, m_rotation_m) :
|
||||
cut.perform_with_plane();
|
||||
check_objects_after_cut(new_objects);
|
||||
// save cut_id to post update synchronization
|
||||
const CutObjectBase cut_id = cut_mo->cut_id;
|
||||
|
||||
@@ -3508,6 +3554,7 @@ bool GLGizmoCut3D::add_connector(CutConnectors& connectors, const Vec2d& mouse_p
|
||||
connectors.emplace_back(pos, m_rotation_m,
|
||||
m_connector_size * 0.5f, m_connector_depth_ratio,
|
||||
m_connector_size_tolerance * 0.5f, m_connector_depth_ratio_tolerance,
|
||||
m_connector_angle,
|
||||
CutConnectorAttributes( CutConnectorType(m_connector_type),
|
||||
CutConnectorStyle(m_connector_style),
|
||||
CutConnectorShape(m_connector_shape_id)));
|
||||
@@ -3732,6 +3779,7 @@ void GLGizmoCut3D::apply_cut_connectors(ModelObject* mo, const std::string& conn
|
||||
|
||||
// Transform the new modifier to be aligned inside the instance
|
||||
new_volume->set_transformation(translation_transform(connector.pos) * connector.rotation_m *
|
||||
rotation_transform(-connector.z_angle * Vec3d::UnitZ()) *
|
||||
scale_transform(Vec3f(connector.radius, connector.radius, connector.height).cast<double>()));
|
||||
|
||||
new_volume->cut_info = { connector.attribs.type, connector.radius_tolerance, connector.height_tolerance };
|
||||
|
||||
@@ -135,6 +135,7 @@ class GLGizmoCut3D : public GLGizmoBase
|
||||
|
||||
float m_connector_depth_ratio{ 3.f };
|
||||
float m_connector_size{ 2.5f };
|
||||
float m_connector_angle{ 0.f };
|
||||
|
||||
float m_connector_depth_ratio_tolerance{ 0.1f };
|
||||
float m_connector_size_tolerance{ 0.f };
|
||||
@@ -303,6 +304,7 @@ protected:
|
||||
void render_color_marker(float size, const ImU32& color);
|
||||
void render_groove_float_input(const std::string &label, float &in_val, const float &init_val, float &in_tolerance);
|
||||
void render_groove_angle_input(const std::string &label, float &in_val, const float &init_val, float min_val, float max_val);
|
||||
bool render_angle_input(const std::string& label, float& in_val, const float& init_val, float min_val, float max_val);
|
||||
void render_snap_specific_input(const std::string& label, const wxString& tooltip, float& in_val, const float& init_val, const float min_val, const float max_val);
|
||||
void render_cut_plane_input_window(CutConnectors &connectors);
|
||||
void init_input_window_data(CutConnectors &connectors);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
#include "GLGizmoRotate.hpp"
|
||||
#include "slic3r/GUI/IconManager.hpp"
|
||||
#include "slic3r/GUI/SurfaceDrag.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp"
|
||||
#include "slic3r/GUI/I18N.hpp" // TODO: not needed
|
||||
#include "slic3r/GUI/TextLines.hpp"
|
||||
#include "slic3r/Utils/RaycastManager.hpp"
|
||||
#include "slic3r/Utils/EmbossStyleManager.hpp"
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "libslic3r/Emboss.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/TextConfiguration.hpp"
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
@@ -33,7 +32,7 @@ namespace Slic3r::GUI {
|
||||
class GLGizmoEmboss : public GLGizmoBase
|
||||
{
|
||||
public:
|
||||
GLGizmoEmboss(GLCanvas3D& parent);
|
||||
explicit GLGizmoEmboss(GLCanvas3D& parent);
|
||||
|
||||
//B34
|
||||
void create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos, std::string m_text);
|
||||
@@ -43,12 +42,12 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
|
||||
/// <param name="mouse_pos">Define position of new volume</param>
|
||||
void create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos);
|
||||
bool create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos);
|
||||
/// <summary>
|
||||
/// Create new text without given position
|
||||
/// </summary>
|
||||
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
|
||||
void create_volume(ModelVolumeType volume_type);
|
||||
bool create_volume(ModelVolumeType volume_type);
|
||||
//B34
|
||||
void change_height(double height);
|
||||
|
||||
@@ -65,6 +64,12 @@ public:
|
||||
/// <returns>True on success start job otherwise False</returns>
|
||||
bool do_mirror(size_t axis);
|
||||
|
||||
/// <summary>
|
||||
/// Call on change inside of object conatining projected volume
|
||||
/// </summary>
|
||||
/// <param name="job_cancel">Way to stop re_emboss job</param>
|
||||
/// <returns>True on success otherwise False</returns>
|
||||
static bool re_emboss(const ModelVolume &text, std::shared_ptr<std::atomic<bool>> job_cancel = nullptr);
|
||||
protected:
|
||||
bool on_init() override;
|
||||
std::string on_get_name() const override;
|
||||
@@ -90,10 +95,10 @@ protected:
|
||||
/// <returns>Propagete normaly return false.</returns>
|
||||
bool on_mouse(const wxMouseEvent &mouse_event) override;
|
||||
|
||||
bool wants_enter_leave_snapshots() const override { return true; }
|
||||
std::string get_gizmo_entering_text() const override { return _u8L("Enter emboss gizmo"); }
|
||||
std::string get_gizmo_leaving_text() const override { return _u8L("Leave emboss gizmo"); }
|
||||
std::string get_action_snapshot_name() const override { return _u8L("Embossing actions"); }
|
||||
bool wants_enter_leave_snapshots() const override;
|
||||
std::string get_gizmo_entering_text() const override;
|
||||
std::string get_gizmo_leaving_text() const override;
|
||||
std::string get_action_snapshot_name() const override;
|
||||
private:
|
||||
void volume_transformation_changing();
|
||||
void volume_transformation_changed();
|
||||
@@ -111,7 +116,6 @@ private:
|
||||
void draw_window();
|
||||
void draw_text_input();
|
||||
void draw_model_type();
|
||||
void fix_transformation(const FontProp &from, const FontProp &to);
|
||||
void draw_style_list();
|
||||
void draw_delete_style_button();
|
||||
void draw_style_rename_popup();
|
||||
@@ -120,8 +124,6 @@ private:
|
||||
void draw_style_save_as_popup();
|
||||
void draw_style_add_button();
|
||||
void init_font_name_texture();
|
||||
struct FaceName;
|
||||
void draw_font_preview(FaceName &face, bool is_visible);
|
||||
void draw_font_list_line();
|
||||
void draw_font_list();
|
||||
void draw_height(bool use_inch);
|
||||
@@ -130,8 +132,6 @@ private:
|
||||
|
||||
// call after set m_style_manager.get_style().prop.size_in_mm
|
||||
bool set_height();
|
||||
// call after set m_style_manager.get_style().prop.emboss
|
||||
bool set_depth();
|
||||
|
||||
bool draw_italic_button();
|
||||
bool draw_bold_button();
|
||||
@@ -139,30 +139,25 @@ private:
|
||||
|
||||
bool select_facename(const wxString& facename);
|
||||
|
||||
void do_translate(const Vec3d& relative_move);
|
||||
void do_rotate(float relative_z_angle);
|
||||
|
||||
bool rev_input_mm(const std::string &name, float &value, const float *default_value,
|
||||
const std::string &undo_tooltip, float step, float step_fast, const char *format,
|
||||
bool use_inch, const std::optional<float>& scale);
|
||||
template<typename T> bool rev_input_mm(const std::string &name, T &value, const T *default_value,
|
||||
const std::string &undo_tooltip, T step, T step_fast, const char *format, bool use_inch, const std::optional<float>& scale) const;
|
||||
|
||||
/// <summary>
|
||||
/// Reversible input float with option to restor default value
|
||||
/// TODO: make more general, static and move to ImGuiWrapper
|
||||
/// </summary>
|
||||
/// <returns>True when value changed otherwise FALSE.</returns>
|
||||
bool rev_input(const std::string &name, float &value, const float *default_value,
|
||||
const std::string &undo_tooltip, float step, float step_fast, const char *format,
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
bool rev_checkbox(const std::string &name, bool &value, const bool* default_value, const std::string &undo_tooltip);
|
||||
template<typename T> bool rev_input(const std::string &name, T &value, const T *default_value,
|
||||
const std::string &undo_tooltip, T step, T step_fast, const char *format, ImGuiInputTextFlags flags = 0) const;
|
||||
bool rev_checkbox(const std::string &name, bool &value, const bool* default_value, const std::string &undo_tooltip) const;
|
||||
bool rev_slider(const std::string &name, std::optional<int>& value, const std::optional<int> *default_value,
|
||||
const std::string &undo_tooltip, int v_min, int v_max, const std::string &format, const wxString &tooltip);
|
||||
const std::string &undo_tooltip, int v_min, int v_max, const std::string &format, const wxString &tooltip) const;
|
||||
bool rev_slider(const std::string &name, std::optional<float>& value, const std::optional<float> *default_value,
|
||||
const std::string &undo_tooltip, float v_min, float v_max, const std::string &format, const wxString &tooltip);
|
||||
const std::string &undo_tooltip, float v_min, float v_max, const std::string &format, const wxString &tooltip) const;
|
||||
bool rev_slider(const std::string &name, float &value, const float *default_value,
|
||||
const std::string &undo_tooltip, float v_min, float v_max, const std::string &format, const wxString &tooltip);
|
||||
template<typename T, typename Draw>
|
||||
bool revertible(const std::string &name, T &value, const T *default_value, const std::string &undo_tooltip, float undo_offset, Draw draw);
|
||||
const std::string &undo_tooltip, float v_min, float v_max, const std::string &format, const wxString &tooltip) const;
|
||||
template<typename T, typename Draw> bool revertible(const std::string &name, T &value, const T *default_value,
|
||||
const std::string &undo_tooltip, float undo_offset, Draw draw) const;
|
||||
|
||||
bool m_should_set_minimal_windows_size = false;
|
||||
void set_minimal_window_size(bool is_advance_edit_style);
|
||||
@@ -174,71 +169,13 @@ private:
|
||||
void on_mouse_change_selection(const wxMouseEvent &mouse_event);
|
||||
|
||||
// When open text loaded from .3mf it could be written with unknown font
|
||||
bool m_is_unknown_font;
|
||||
bool m_is_unknown_font = false;
|
||||
void create_notification_not_valid_font(const TextConfiguration& tc);
|
||||
void create_notification_not_valid_font(const std::string& text);
|
||||
void remove_notification_not_valid_font();
|
||||
|
||||
// This configs holds GUI layout size given by translated texts.
|
||||
// etc. When language changes, GUI is recreated and this class constructed again,
|
||||
// so the change takes effect. (info by GLGizmoFdmSupports.hpp)
|
||||
struct GuiCfg
|
||||
{
|
||||
// Detect invalid config values when change monitor DPI
|
||||
double screen_scale;
|
||||
float main_toolbar_height;
|
||||
|
||||
// Zero means it is calculated in init function
|
||||
ImVec2 minimal_window_size = ImVec2(0, 0);
|
||||
ImVec2 minimal_window_size_with_advance = ImVec2(0, 0);
|
||||
ImVec2 minimal_window_size_with_collections = ImVec2(0, 0);
|
||||
float height_of_volume_type_selector = 0.f;
|
||||
float input_width = 0.f;
|
||||
float delete_pos_x = 0.f;
|
||||
float max_style_name_width = 0.f;
|
||||
unsigned int icon_width = 0;
|
||||
|
||||
// maximal width and height of style image
|
||||
Vec2i max_style_image_size = Vec2i(0, 0);
|
||||
|
||||
float indent = 0.f;
|
||||
float input_offset = 0.f;
|
||||
float advanced_input_offset = 0.f;
|
||||
|
||||
float lock_offset = 0.f;
|
||||
|
||||
ImVec2 text_size;
|
||||
|
||||
// maximal size of face name image
|
||||
Vec2i face_name_size = Vec2i(100, 0);
|
||||
float face_name_texture_offset_x = 0.f;
|
||||
|
||||
// maximal texture generate jobs running at once
|
||||
unsigned int max_count_opened_font_files = 10;
|
||||
|
||||
// Only translations needed for calc GUI size
|
||||
struct Translations
|
||||
{
|
||||
std::string font;
|
||||
std::string height;
|
||||
std::string depth;
|
||||
|
||||
// advanced
|
||||
std::string use_surface;
|
||||
std::string per_glyph;
|
||||
std::string alignment;
|
||||
std::string char_gap;
|
||||
std::string line_gap;
|
||||
std::string boldness;
|
||||
std::string skew_ration;
|
||||
std::string from_surface;
|
||||
std::string rotation;
|
||||
std::string collection;
|
||||
};
|
||||
Translations translations;
|
||||
};
|
||||
std::optional<const GuiCfg> m_gui_cfg;
|
||||
static GuiCfg create_gui_configuration();
|
||||
struct GuiCfg;
|
||||
std::unique_ptr<const GuiCfg> m_gui_cfg;
|
||||
|
||||
// Is open tree with advanced options
|
||||
bool m_is_advanced_edit_style = false;
|
||||
@@ -252,62 +189,9 @@ private:
|
||||
// Keep information about stored styles and loaded actual style to compare with
|
||||
Emboss::StyleManager m_style_manager;
|
||||
|
||||
struct FaceName{
|
||||
wxString wx_name;
|
||||
std::string name_truncated = "";
|
||||
size_t texture_index = 0;
|
||||
// State for generation of texture
|
||||
// when start generate create share pointers
|
||||
std::shared_ptr<std::atomic<bool>> cancel = nullptr;
|
||||
// R/W only on main thread - finalize of job
|
||||
std::shared_ptr<bool> is_created = nullptr;
|
||||
};
|
||||
|
||||
// Keep sorted list of loadable face names
|
||||
struct Facenames
|
||||
{
|
||||
// flag to keep need of enumeration fonts from OS
|
||||
// false .. wants new enumeration check by Hash
|
||||
// true .. already enumerated(During opened combo box)
|
||||
bool is_init = false;
|
||||
|
||||
bool has_truncated_names = false;
|
||||
|
||||
// data of can_load() faces
|
||||
std::vector<FaceName> faces = {};
|
||||
// Sorter set of Non valid face names in OS
|
||||
std::vector<wxString> bad = {};
|
||||
|
||||
// Configuration of font encoding
|
||||
static constexpr wxFontEncoding encoding = wxFontEncoding::wxFONTENCODING_SYSTEM;
|
||||
|
||||
// Identify if preview texture exists
|
||||
GLuint texture_id = 0;
|
||||
|
||||
// protection for open too much font files together
|
||||
// Gtk:ERROR:../../../../gtk/gtkiconhelper.c:494:ensure_surface_for_gicon: assertion failed (error == NULL): Failed to load /usr/share/icons/Yaru/48x48/status/image-missing.png: Error opening file /usr/share/icons/Yaru/48x48/status/image-missing.png: Too many open files (g-io-error-quark, 31)
|
||||
// This variable must exist until no CreateFontImageJob is running
|
||||
unsigned int count_opened_font_files = 0;
|
||||
|
||||
// Configuration for texture height
|
||||
const int count_cached_textures = 32;
|
||||
|
||||
// index for new generated texture index(must be lower than count_cached_textures)
|
||||
size_t texture_index = 0;
|
||||
|
||||
// hash created from enumerated font from OS
|
||||
// check when new font was installed
|
||||
size_t hash = 0;
|
||||
|
||||
// filtration pattern
|
||||
std::string search = "";
|
||||
std::vector<bool> hide; // result of filtration
|
||||
} m_face_names;
|
||||
static bool store(const Facenames &facenames);
|
||||
static bool load(Facenames &facenames);
|
||||
|
||||
static void init_face_names(Facenames &facenames);
|
||||
static void init_truncated_names(Facenames &face_names, float max_width);
|
||||
// pImpl to hide implementation of FaceNames to .cpp file
|
||||
struct Facenames; // forward declaration
|
||||
std::unique_ptr<Facenames> m_face_names;
|
||||
|
||||
// Text to emboss
|
||||
std::string m_text; // Sequence of Unicode UTF8 symbols
|
||||
@@ -317,7 +201,7 @@ private:
|
||||
|
||||
// current selected volume
|
||||
// NOTE: Be carefull could be uninitialized (removed from Model)
|
||||
ModelVolume *m_volume;
|
||||
ModelVolume *m_volume = nullptr;
|
||||
|
||||
// When work with undo redo stack there could be situation that
|
||||
// m_volume point to unexisting volume so One need also objectID
|
||||
@@ -327,7 +211,7 @@ private:
|
||||
bool m_text_contain_unknown_glyph = false;
|
||||
|
||||
// cancel for previous update of volume to cancel finalize part
|
||||
std::shared_ptr<std::atomic<bool>> m_job_cancel;
|
||||
std::shared_ptr<std::atomic<bool>> m_job_cancel = nullptr;
|
||||
|
||||
// Keep information about curvature of text line around surface
|
||||
TextLinesModel m_text_lines;
|
||||
@@ -341,8 +225,8 @@ private:
|
||||
// Keep data about dragging only during drag&drop
|
||||
std::optional<SurfaceDrag> m_surface_drag;
|
||||
|
||||
// TODO: it should be accessible by other gizmo too.
|
||||
// May be move to plater?
|
||||
// Keep old scene triangle data in AABB trees,
|
||||
// all the time it need actualize before use.
|
||||
RaycastManager m_raycast_manager;
|
||||
|
||||
// For text on scaled objects
|
||||
|
||||
@@ -57,7 +57,7 @@ bool GLGizmoMmuSegmentation::on_is_activable() const
|
||||
return GLGizmoPainterBase::on_is_activable() && wxGetApp().extruders_edited_cnt() > 1;
|
||||
}
|
||||
|
||||
static std::vector<ColorRGBA> get_extruders_colors()
|
||||
std::vector<ColorRGBA> get_extruders_colors()
|
||||
{
|
||||
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
std::vector<ColorRGBA> ret;
|
||||
@@ -524,6 +524,7 @@ void GLGizmoMmuSegmentation::update_model_object() const
|
||||
|
||||
void GLGizmoMmuSegmentation::init_model_triangle_selectors()
|
||||
{
|
||||
const int extruders_count = wxGetApp().extruders_edited_cnt();
|
||||
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||
m_triangle_selectors.clear();
|
||||
|
||||
@@ -538,8 +539,8 @@ void GLGizmoMmuSegmentation::init_model_triangle_selectors()
|
||||
// This mesh does not account for the possible Z up SLA offset.
|
||||
const TriangleMesh *mesh = &mv->mesh();
|
||||
|
||||
int extruder_idx = (mv->extruder_id() > 0) ? mv->extruder_id() - 1 : 0;
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorMmGui>(*mesh, m_modified_extruders_colors, m_original_extruders_colors[size_t(extruder_idx)]));
|
||||
size_t extruder_idx = get_extruder_color_idx(*mv, extruders_count);
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorMmGui>(*mesh, m_modified_extruders_colors, m_original_extruders_colors[extruder_idx]));
|
||||
// Reset of TriangleSelector is done inside TriangleSelectorMmGUI's constructor, so we don't need it to perform it again in deserialize().
|
||||
m_triangle_selectors.back()->deserialize(mv->mmu_segmentation_facets.get_data(), false);
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
@@ -588,12 +589,6 @@ void TriangleSelectorMmGui::render(ImGuiWrapper* imgui, const Transform3d& matri
|
||||
if (!shader)
|
||||
return;
|
||||
assert(shader->get_name() == "mm_gouraud");
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_matrix * matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
const Matrix3d view_normal_matrix = view_matrix.matrix().block(0, 0, 3, 3) * matrix.matrix().block(0, 0, 3, 3).inverse().transpose();
|
||||
shader->set_uniform("view_normal_matrix", view_normal_matrix);
|
||||
|
||||
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) {
|
||||
if (m_gizmo_scene.has_VBOs(color_idx)) {
|
||||
|
||||
@@ -66,8 +66,9 @@ public:
|
||||
|
||||
class TriangleSelectorMmGui : public TriangleSelectorGUI {
|
||||
public:
|
||||
TriangleSelectorMmGui() = delete;
|
||||
// Plus 1 in the initialization of m_gizmo_scene is because the first position is allocated for non-painted triangles, and the indices above colors.size() are allocated for seed fill.
|
||||
TriangleSelectorMmGui(const TriangleMesh& mesh, const std::vector<ColorRGBA>& colors, const ColorRGBA& default_volume_color)
|
||||
explicit TriangleSelectorMmGui(const TriangleMesh& mesh, const std::vector<ColorRGBA>& colors, const ColorRGBA& default_volume_color)
|
||||
: TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color), m_gizmo_scene(2 * (colors.size() + 1)) {}
|
||||
~TriangleSelectorMmGui() override = default;
|
||||
|
||||
@@ -148,6 +149,15 @@ private:
|
||||
std::map<std::string, wxString> m_desc;
|
||||
};
|
||||
|
||||
std::vector<ColorRGBA> get_extruders_colors();
|
||||
|
||||
inline size_t get_extruder_color_idx(const ModelVolume &model_volume, const int extruders_count)
|
||||
{
|
||||
if (const int extruder_id = model_volume.extruder_id(); extruder_id <= 0 || extruder_id > extruders_count)
|
||||
return 0;
|
||||
else
|
||||
return extruder_id - 1;
|
||||
}
|
||||
} // namespace Slic3r
|
||||
|
||||
|
||||
|
||||
@@ -200,10 +200,12 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection)
|
||||
const auto [box, box_trafo] = m_force_local_coordinate ?
|
||||
selection.get_bounding_box_in_reference_system(ECoordinatesType::Local) : selection.get_bounding_box_in_current_reference_system();
|
||||
m_bounding_box = box;
|
||||
m_center = box_trafo.translation();
|
||||
const std::pair<Vec3d, double> sphere = selection.get_bounding_sphere();
|
||||
m_center = sphere.first;
|
||||
m_radius = Offset + sphere.second;
|
||||
m_orient_matrix = box_trafo;
|
||||
|
||||
m_radius = Offset + m_bounding_box.radius();
|
||||
m_orient_matrix.translation() = m_center;
|
||||
m_snap_coarse_in_radius = m_radius / 3.0f;
|
||||
m_snap_coarse_out_radius = 2.0f * m_snap_coarse_in_radius;
|
||||
m_snap_fine_in_radius = m_radius;
|
||||
|
||||
2239
src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp
Normal file
2239
src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp
Normal file
File diff suppressed because it is too large
Load Diff
203
src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp
Normal file
203
src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#ifndef slic3r_GLGizmoSVG_hpp_
|
||||
#define slic3r_GLGizmoSVG_hpp_
|
||||
|
||||
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code,
|
||||
// which overrides our localization "L" macro.
|
||||
#include "GLGizmoBase.hpp"
|
||||
#include "GLGizmoRotate.hpp"
|
||||
#include "slic3r/GUI/SurfaceDrag.hpp"
|
||||
#include "slic3r/GUI/GLTexture.hpp"
|
||||
#include "slic3r/Utils/RaycastManager.hpp"
|
||||
#include "slic3r/GUI/IconManager.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
#include "libslic3r/Emboss.hpp"
|
||||
#include "libslic3r/Point.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace Slic3r{
|
||||
class ModelVolume;
|
||||
enum class ModelVolumeType : int;
|
||||
}
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
struct Texture{
|
||||
unsigned id{0};
|
||||
unsigned width{0};
|
||||
unsigned height{0};
|
||||
};
|
||||
|
||||
class GLGizmoSVG : public GLGizmoBase
|
||||
{
|
||||
public:
|
||||
explicit GLGizmoSVG(GLCanvas3D &parent);
|
||||
|
||||
/// <summary>
|
||||
/// Create new embossed text volume by type on position of mouse
|
||||
/// </summary>
|
||||
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
|
||||
/// <param name="mouse_pos">Define position of new volume</param>
|
||||
/// <returns>True on succesfull start creation otherwise False</returns>
|
||||
bool create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos); // first open file dialog
|
||||
|
||||
/// <summary>
|
||||
/// Create new text without given position
|
||||
/// </summary>
|
||||
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
|
||||
/// <returns>True on succesfull start creation otherwise False</returns>
|
||||
bool create_volume(ModelVolumeType volume_type); // first open file dialog
|
||||
|
||||
/// <summary>
|
||||
/// Create volume from already selected svg file
|
||||
/// </summary>
|
||||
/// <param name="svg_file">File path</param>
|
||||
/// <param name="mouse_pos">Position on screen where to create volume</param>
|
||||
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
|
||||
/// <returns>True on succesfull start creation otherwise False</returns>
|
||||
bool create_volume(std::string_view svg_file, const Vec2d &mouse_pos, ModelVolumeType volume_type = ModelVolumeType::MODEL_PART);
|
||||
bool create_volume(std::string_view svg_file, ModelVolumeType volume_type = ModelVolumeType::MODEL_PART);
|
||||
|
||||
/// <summary>
|
||||
/// Check whether volume is object containing only emboss volume
|
||||
/// </summary>
|
||||
/// <param name="volume">Pointer to volume</param>
|
||||
/// <returns>True when object otherwise False</returns>
|
||||
static bool is_svg_object(const ModelVolume &volume);
|
||||
|
||||
/// <summary>
|
||||
/// Check whether volume has emboss data
|
||||
/// </summary>
|
||||
/// <param name="volume">Pointer to volume</param>
|
||||
/// <returns>True when constain emboss data otherwise False</returns>
|
||||
static bool is_svg(const ModelVolume &volume);
|
||||
|
||||
protected:
|
||||
bool on_init() override;
|
||||
std::string on_get_name() const override;
|
||||
void on_render() override;
|
||||
void on_register_raycasters_for_picking() override;
|
||||
void on_unregister_raycasters_for_picking() override;
|
||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||
bool on_is_activable() const override { return true; }
|
||||
bool on_is_selectable() const override { return false; }
|
||||
void on_set_state() override;
|
||||
void data_changed(bool is_serializing) override; // selection changed
|
||||
void on_set_hover_id() override{ m_rotate_gizmo.set_hover_id(m_hover_id); }
|
||||
void on_enable_grabber(unsigned int id) override { m_rotate_gizmo.enable_grabber(); }
|
||||
void on_disable_grabber(unsigned int id) override { m_rotate_gizmo.disable_grabber(); }
|
||||
void on_start_dragging() override;
|
||||
void on_stop_dragging() override;
|
||||
void on_dragging(const UpdateData &data) override;
|
||||
|
||||
/// <summary>
|
||||
/// Rotate by text on dragging rotate grabers
|
||||
/// </summary>
|
||||
/// <param name="mouse_event">Information about mouse</param>
|
||||
/// <returns>Propagete normaly return false.</returns>
|
||||
bool on_mouse(const wxMouseEvent &mouse_event) override;
|
||||
|
||||
bool wants_enter_leave_snapshots() const override;
|
||||
std::string get_gizmo_entering_text() const override;
|
||||
std::string get_gizmo_leaving_text() const override;
|
||||
std::string get_action_snapshot_name() const override;
|
||||
private:
|
||||
void set_volume_by_selection();
|
||||
void reset_volume();
|
||||
|
||||
// create volume from text - main functionality
|
||||
bool process();
|
||||
void close();
|
||||
void draw_window();
|
||||
void draw_preview();
|
||||
void draw_filename();
|
||||
void draw_depth();
|
||||
void draw_size();
|
||||
void draw_use_surface();
|
||||
void draw_distance();
|
||||
void draw_rotation();
|
||||
void draw_mirroring();
|
||||
void draw_face_the_camera();
|
||||
void draw_model_type();
|
||||
|
||||
// process mouse event
|
||||
bool on_mouse_for_rotation(const wxMouseEvent &mouse_event);
|
||||
bool on_mouse_for_translate(const wxMouseEvent &mouse_event);
|
||||
|
||||
void volume_transformation_changed();
|
||||
|
||||
struct GuiCfg;
|
||||
std::unique_ptr<const GuiCfg> m_gui_cfg;
|
||||
|
||||
// actual selected only one volume - with emboss data
|
||||
ModelVolume *m_volume = nullptr;
|
||||
|
||||
// Is used to edit eboss and send changes to job
|
||||
// Inside volume is current state of shape WRT Volume
|
||||
EmbossShape m_volume_shape; // copy from m_volume for edit
|
||||
|
||||
// same index as volumes in
|
||||
std::vector<std::string> m_shape_warnings;
|
||||
|
||||
// When work with undo redo stack there could be situation that
|
||||
// m_volume point to unexisting volume so One need also objectID
|
||||
ObjectID m_volume_id;
|
||||
|
||||
// cancel for previous update of volume to cancel finalize part
|
||||
std::shared_ptr<std::atomic<bool>> m_job_cancel = nullptr;
|
||||
|
||||
// Rotation gizmo
|
||||
GLGizmoRotate m_rotate_gizmo;
|
||||
std::optional<float> m_angle;
|
||||
std::optional<float> m_distance;
|
||||
|
||||
// Value is set only when dragging rotation to calculate actual angle
|
||||
std::optional<float> m_rotate_start_angle;
|
||||
|
||||
// TODO: it should be accessible by other gizmo too.
|
||||
// May be move to plater?
|
||||
RaycastManager m_raycast_manager;
|
||||
|
||||
// When true keep up vector otherwise relative rotation
|
||||
bool m_keep_up = true;
|
||||
|
||||
// Keep size aspect ratio when True.
|
||||
bool m_keep_ratio = true;
|
||||
|
||||
// setted only when wanted to use - not all the time
|
||||
std::optional<ImVec2> m_set_window_offset;
|
||||
|
||||
// Keep data about dragging only during drag&drop
|
||||
std::optional<SurfaceDrag> m_surface_drag;
|
||||
|
||||
// For volume on scaled objects
|
||||
std::optional<float> m_scale_width;
|
||||
std::optional<float> m_scale_height;
|
||||
std::optional<float> m_scale_depth;
|
||||
void calculate_scale();
|
||||
float get_scale_for_tolerance();
|
||||
|
||||
// keep SVG data rendered on GPU
|
||||
Texture m_texture;
|
||||
|
||||
// bounding box of shape
|
||||
// Note: Scaled mm to int value by m_volume_shape.scale
|
||||
BoundingBox m_shape_bb;
|
||||
|
||||
std::string m_filename_preview;
|
||||
|
||||
IconManager m_icon_manager;
|
||||
IconManager::Icons m_icons;
|
||||
|
||||
// only temporary solution
|
||||
static const std::string M_ICON_FILENAME;
|
||||
};
|
||||
} // namespace Slic3r::GUI
|
||||
|
||||
#endif // slic3r_GLGizmoSVG_hpp_
|
||||
@@ -37,7 +37,7 @@ static void call_after_if_active(std::function<void()> fn, GUI_App* app = &wxGet
|
||||
});
|
||||
}
|
||||
|
||||
static std::set<ObjectID> get_volume_ids(const Selection &selection)
|
||||
static std::set<ObjectID> get_selected_volume_ids(const Selection &selection)
|
||||
{
|
||||
const Selection::IndicesList &volume_ids = selection.get_volume_idxs();
|
||||
const ModelObjectPtrs &model_objects = selection.get_model()->objects;
|
||||
@@ -64,19 +64,6 @@ static std::set<ObjectID> get_volume_ids(const Selection &selection)
|
||||
return result;
|
||||
}
|
||||
|
||||
// return ModelVolume from selection by object id
|
||||
static ModelVolume *get_volume(const ObjectID &id, const Selection &selection) {
|
||||
const Selection::IndicesList &volume_ids = selection.get_volume_idxs();
|
||||
const ModelObjectPtrs &model_objects = selection.get_model()->objects;
|
||||
for (auto volume_id : volume_ids) {
|
||||
const GLVolume *selected_volume = selection.get_volume(volume_id);
|
||||
const GLVolume::CompositeID &cid = selected_volume->composite_id;
|
||||
ModelObject *obj = model_objects[cid.object_id];
|
||||
ModelVolume *volume = obj->volumes[cid.volume_id];
|
||||
if (id == volume->id()) return volume;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static std::string create_volumes_name(const std::set<ObjectID>& ids, const Selection &selection){
|
||||
assert(!ids.empty());
|
||||
@@ -88,7 +75,7 @@ static std::string create_volumes_name(const std::set<ObjectID>& ids, const Sele
|
||||
else
|
||||
name += " + ";
|
||||
|
||||
const ModelVolume *volume = get_volume(id, selection);
|
||||
const ModelVolume *volume = get_selected_volume(id, selection);
|
||||
assert(volume != nullptr);
|
||||
name += volume->name;
|
||||
}
|
||||
@@ -181,11 +168,11 @@ void GLGizmoSimplify::on_render_input_window(float x, float y, float bottom_limi
|
||||
{
|
||||
create_gui_cfg();
|
||||
const Selection &selection = m_parent.get_selection();
|
||||
auto act_volume_ids = get_volume_ids(selection);
|
||||
auto act_volume_ids = get_selected_volume_ids(selection);
|
||||
if (act_volume_ids.empty()) {
|
||||
stop_worker_thread_request();
|
||||
close();
|
||||
if (! m_parent.get_selection().is_single_volume()) {
|
||||
if (m_parent.get_selection().volumes_count() != 1) {
|
||||
MessageDialog msg((wxWindow*)wxGetApp().mainframe,
|
||||
_L("Simplification is currently only allowed when a single part is selected"),
|
||||
_L("Error"));
|
||||
@@ -471,7 +458,7 @@ void GLGizmoSimplify::process()
|
||||
const Selection& selection = m_parent.get_selection();
|
||||
State::Data its;
|
||||
for (const auto &id : m_volume_ids) {
|
||||
const ModelVolume *volume = get_volume(id, selection);
|
||||
const ModelVolume *volume = get_selected_volume(id, selection);
|
||||
its[id] = std::make_unique<indexed_triangle_set>(volume->mesh().its); // copy
|
||||
}
|
||||
|
||||
@@ -549,7 +536,7 @@ void GLGizmoSimplify::apply_simplify() {
|
||||
for (const auto &item: m_state.result) {
|
||||
const ObjectID &id = item.first;
|
||||
const indexed_triangle_set &its = *item.second;
|
||||
ModelVolume *volume = get_volume(id, selection);
|
||||
ModelVolume *volume = get_selected_volume(id, selection);
|
||||
assert(volume != nullptr);
|
||||
ModelObject *obj = volume->get_object();
|
||||
|
||||
@@ -725,7 +712,7 @@ void GLGizmoSimplify::on_render()
|
||||
const Selection & selection = m_parent.get_selection();
|
||||
|
||||
// Check that the GLVolume still belongs to the ModelObject we work on.
|
||||
if (m_volume_ids != get_volume_ids(selection)) return;
|
||||
if (m_volume_ids != get_selected_volume_ids(selection)) return;
|
||||
|
||||
const ModelObjectPtrs &model_objects = selection.get_model()->objects;
|
||||
const Selection::IndicesList &volume_idxs = selection.get_volume_idxs();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoSimplify.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoEmboss.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoSVG.hpp"
|
||||
#include "slic3r/GUI/Gizmos/GLGizmoMeasure.hpp"
|
||||
|
||||
#include "libslic3r/format.hpp"
|
||||
@@ -109,6 +110,7 @@ bool GLGizmosManager::init()
|
||||
m_gizmos.emplace_back(new GLGizmoMmuSegmentation(m_parent, "mmu_segmentation.svg", 9));
|
||||
m_gizmos.emplace_back(new GLGizmoMeasure(m_parent, "measure.svg", 10));
|
||||
m_gizmos.emplace_back(new GLGizmoEmboss(m_parent));
|
||||
m_gizmos.emplace_back(new GLGizmoSVG(m_parent));
|
||||
m_gizmos.emplace_back(new GLGizmoSimplify(m_parent));
|
||||
|
||||
m_common_gizmos_data.reset(new CommonGizmosDataPool(&m_parent));
|
||||
|
||||
@@ -79,6 +79,7 @@ public:
|
||||
MmuSegmentation,
|
||||
Measure,
|
||||
Emboss,
|
||||
Svg,
|
||||
Simplify,
|
||||
Undefined
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user