From 24c791b29dcfabdf6497fe5e6bbc1532cc2072b4 Mon Sep 17 00:00:00 2001 From: Filip Sykala - NTB T15p Date: Wed, 8 Mar 2023 16:40:03 +0100 Subject: [PATCH] Add svg to context menu --- src/slic3r/GUI/GLCanvas3D.cpp | 22 ++++-- src/slic3r/GUI/GUI_Factories.cpp | 38 ++++++++++ src/slic3r/GUI/GUI_Factories.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp | 84 +++++++++++++---------- src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 + src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 1 + 7 files changed, 108 insertions(+), 44 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d1d44709e6..e0c1f8ee2f 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3392,7 +3392,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) type == GLGizmosManager::EType::Move || type == GLGizmosManager::EType::Rotate || type == GLGizmosManager::EType::Scale || - type == GLGizmosManager::EType::Emboss) ) { + type == GLGizmosManager::EType::Emboss|| + type == GLGizmosManager::EType::Svg) ) { for (int hover_volume_id : m_hover_volume_idxs) { const GLVolume &hover_gl_volume = *m_volumes.volumes[hover_volume_id]; int object_idx = hover_gl_volume.object_idx(); @@ -3401,12 +3402,19 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) int hover_volume_idx = hover_gl_volume.volume_idx(); if (hover_volume_idx < 0 || static_cast(hover_volume_idx) >= hover_object->volumes.size()) continue; const ModelVolume* hover_volume = hover_object->volumes[hover_volume_idx]; - if (!hover_volume->text_configuration.has_value()) continue; - m_selection.add_volumes(Selection::EMode::Volume, {(unsigned) hover_volume_id}); - if (type != GLGizmosManager::EType::Emboss) - m_gizmos.open_gizmo(GLGizmosManager::EType::Emboss); - wxGetApp().obj_list()->update_selections(); - return; + + if (hover_volume->text_configuration.has_value()) { + m_selection.add_volumes(Selection::EMode::Volume, {(unsigned) hover_volume_id}); + if (type != GLGizmosManager::EType::Emboss) + m_gizmos.open_gizmo(GLGizmosManager::EType::Emboss); + wxGetApp().obj_list()->update_selections(); + return; + } else if (hover_volume->emboss_shape.has_value()) { + if (type != GLGizmosManager::EType::Svg) + m_gizmos.open_gizmo(GLGizmosManager::EType::Svg); + wxGetApp().obj_list()->update_selections(); + return; + } } } diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index df8ace79a3..daab5fafc9 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -14,6 +14,7 @@ #include "Selection.hpp" #include "format.hpp" #include "Gizmos/GLGizmoEmboss.hpp" +#include "Gizmos/GLGizmoSVG.hpp" #include #include "slic3r/Utils/FixModelByWin10.hpp" @@ -487,6 +488,7 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty } append_menu_item_add_text(sub_menu, type); + append_menu_item_add_svg(sub_menu, type); if (mode >= comAdvanced) { sub_menu->AppendSeparator(); @@ -533,6 +535,42 @@ void MenuFactory::append_menu_item_add_text(wxMenu* menu, ModelVolumeType type, } } +void MenuFactory::append_menu_item_add_svg(wxMenu *menu, ModelVolumeType type, bool is_submenu_item /* = true*/) +{ + auto open_svg = [type](wxCommandEvent &evt) { + GLCanvas3D* canvas = plater()->canvas3D(); + GLGizmosManager& mng = canvas->get_gizmos_manager(); + GLGizmoBase* gizmo = mng.get_gizmo(GLGizmosManager::Svg); + GLGizmoSVG* svg = dynamic_cast(gizmo); + assert(svg != nullptr); + if (svg == nullptr) return; + + ModelVolumeType volume_type = type; + // no selected object means create new object + if (volume_type == ModelVolumeType::INVALID) + volume_type = ModelVolumeType::MODEL_PART; + + auto screen_position = canvas->get_popup_menu_position(); + if (screen_position.has_value()) { + svg->create_volume(volume_type, *screen_position); + } else { + svg->create_volume(volume_type); + } + }; + + if ( type == ModelVolumeType::MODEL_PART + || type == ModelVolumeType::NEGATIVE_VOLUME + || type == ModelVolumeType::PARAMETER_MODIFIER + || type == ModelVolumeType::INVALID // cannot use gizmo without selected object + ) { + wxString item_name = is_submenu_item ? "" : _(ADD_VOLUME_MENU_ITEMS[int(type)].first) + ": "; + item_name += _L("SVG"); + menu->AppendSeparator(); + const std::string icon_name = is_submenu_item ? "" : ADD_VOLUME_MENU_ITEMS[int(type)].second; + append_menu_item(menu, wxID_ANY, item_name, "", open_svg, icon_name, menu); + } +} + void MenuFactory::append_menu_items_add_volume(MenuType menu_type) { wxMenu* menu = menu_type == mtObjectFFF ? &m_object_menu : menu_type == mtObjectSLA ? &m_sla_object_menu : nullptr; diff --git a/src/slic3r/GUI/GUI_Factories.hpp b/src/slic3r/GUI/GUI_Factories.hpp index 515311d0de..f6e84517d1 100644 --- a/src/slic3r/GUI/GUI_Factories.hpp +++ b/src/slic3r/GUI/GUI_Factories.hpp @@ -87,6 +87,7 @@ private: wxMenu* append_submenu_add_generic(wxMenu* menu, ModelVolumeType type); void append_menu_item_add_text(wxMenu* menu, ModelVolumeType type, bool is_submenu_item = true); + void append_menu_item_add_svg(wxMenu *menu, ModelVolumeType type, bool is_submenu_item = true); void append_menu_items_add_volume(MenuType type); wxMenuItem* append_menu_item_layers_editing(wxMenu* menu); wxMenuItem* append_menu_item_settings(wxMenu* menu); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index 546ef66d98..4d788ba54b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -9,10 +9,9 @@ #include "slic3r/GUI/MsgDialog.hpp" #include "slic3r/GUI/format.hpp" #include "slic3r/GUI/CameraUtils.hpp" -#include "slic3r/GUI/Jobs/EmbossJob.hpp" -#include "slic3r/GUI/Jobs/NotificationProgressIndicator.hpp" #include "slic3r/Utils/UndoRedo.hpp" +#include "libslic3r/Point.hpp" #include "libslic3r/SVG.hpp" // debug store #include "libslic3r/Geometry.hpp" // covex hull 2d #include "libslic3r/Timer.hpp" // covex hull 2d @@ -33,7 +32,6 @@ using namespace Slic3r; using namespace Slic3r::Emboss; using namespace Slic3r::GUI; -using namespace Slic3r::GUI::Emboss; namespace priv { // Variable keep limits for variables @@ -43,6 +41,9 @@ static const struct Limits // distance text object from surface MinMax angle{-180.f, 180.f}; // in degrees } limits; + +static std::string choose_svg_file(); +static std::string get_file_name(const std::string &file_path); } // namespace priv GLGizmoSVG::GLGizmoSVG(GLCanvas3D &parent) @@ -55,10 +56,35 @@ GLGizmoSVG::GLGizmoSVG(GLCanvas3D &parent) m_rotate_gizmo.set_force_local_coordinate(true); } +void GLGizmoSVG::create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos){ + std::string path = priv::choose_svg_file(); + if (path.empty()) return; + create_volume(path, volume_type, mouse_pos); +} +void GLGizmoSVG::create_volume(ModelVolumeType volume_type) { + std::string path = priv::choose_svg_file(); + if (path.empty()) return; + create_volume(path, volume_type); +} + void GLGizmoSVG::create_volume(const std::string &svg_file_path, ModelVolumeType volume_type, const Vec2d &mouse_pos) { + std::string name = priv::get_file_name(svg_file_path); + NSVGimage *image = nsvgParseFromFile(svg_file_path.c_str(), "mm", 96.0f); + ExPolygons polys = NSVGUtils::to_ExPolygons(image); + nsvgDelete(image); + + BoundingBox bb; + for (const auto &p : polys) + bb.merge(p.contour.points); + + double scale = 1e-4; + auto project = std::make_unique(std::make_unique(10 / scale), scale); + indexed_triangle_set its = polygons2model(polys, *project); + // add volume } void GLGizmoSVG::create_volume(const std::string &svg_file_path, ModelVolumeType volume_type) { + } bool GLGizmoSVG::is_svg(const ModelVolume *volume) { @@ -484,7 +510,10 @@ void GLGizmoSVG::draw_window() { ImGui::Text("Preview of svg image."); - if (ImGui::Button("choose svg file")) choose_svg_file(); + if (ImGui::Button("choose svg file")) + return; + + //choose_svg_file(); } void GLGizmoSVG::draw_model_type() @@ -563,9 +592,9 @@ void GLGizmoSVG::draw_model_type() // TODO: select volume back - Ask @Sasa } } -namespace priv { - -std::string get_file_name(const std::string &file_path) + + +std::string priv::get_file_name(const std::string &file_path) { size_t pos_last_delimiter = file_path.find_last_of("/\\"); size_t pos_point = file_path.find_last_of('.'); @@ -574,40 +603,25 @@ std::string get_file_name(const std::string &file_path) return file_path.substr(offset, count); } -} - -bool GLGizmoSVG::choose_svg_file() +std::string priv::choose_svg_file() { wxArrayString input_files; - wxString fontDir = wxEmptyString; - wxString selectedFile = wxEmptyString; - wxFileDialog dialog(nullptr, _L("Choose SVG file:"), fontDir, + wxString defaultDir = wxEmptyString; + wxString selectedFile = wxEmptyString; + + wxFileDialog dialog(nullptr, _L("Choose SVG file:"), defaultDir, selectedFile, file_wildcards(FT_SVG), wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (dialog.ShowModal() == wxID_OK) dialog.GetPaths(input_files); - if (input_files.IsEmpty()) return false; - if (input_files.size() != 1) return false; - auto & input_file = input_files.front(); - std::string path = std::string(input_file.c_str()); - std::string name = priv::get_file_name(path); + if (input_files.IsEmpty()) + return {}; + if (input_files.size() != 1) + return {}; - NSVGimage *image = nsvgParseFromFile(path.c_str(), "mm", 96.0f); - ExPolygons polys = NSVGUtils::to_ExPolygons(image); - nsvgDelete(image); - - BoundingBox bb; - for (const auto &p : polys) bb.merge(p.contour.points); - - double scale = 1e-4; - auto project = std::make_unique( - std::make_unique(10 / scale), scale); - indexed_triangle_set its = polygons2model(polys, *project); - return false; - // test store: - // for (auto &poly : polys) poly.scale(1e5); - // SVG svg("converted.svg", BoundingBox(polys.front().contour.points)); - // svg.draw(polys); - //return add_volume(name, its); + auto &input_file = input_files.front(); + std::string path = std::string(input_file.c_str()); + return path; } // any existing icon filename to not influence GUI diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp index 96519daa5e..7ca9637393 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.hpp @@ -38,12 +38,14 @@ public: /// Object part / Negative volume / Modifier /// Define position of new volume void create_volume(const std::string& svg_file_path, ModelVolumeType volume_type, const Vec2d &mouse_pos); + void create_volume(ModelVolumeType volume_type, const Vec2d &mouse_pos); // first open file dialog /// /// Create new text without given position /// /// Object part / Negative volume / Modifier void create_volume(const std::string &svg_file_path, ModelVolumeType volume_type); + void create_volume(ModelVolumeType volume_type); // first open file dialog /// /// Check whether volume is object containing only emboss volume @@ -102,8 +104,6 @@ private: bool on_mouse_for_rotation(const wxMouseEvent &mouse_event); bool on_mouse_for_translate(const wxMouseEvent &mouse_event); - bool choose_svg_file(); - // 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) diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index af93c07df3..5b30729b2f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -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)); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index 8c98596bfd..509a433fd4 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -79,6 +79,7 @@ public: MmuSegmentation, Measure, Emboss, + Svg, Simplify, Undefined };