Add svg to context menu

This commit is contained in:
Filip Sykala - NTB T15p 2023-03-08 16:40:03 +01:00
parent a7fdddfd77
commit 24c791b29d
7 changed files with 108 additions and 44 deletions

View File

@ -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<size_t>(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;
}
}
}

View File

@ -14,6 +14,7 @@
#include "Selection.hpp"
#include "format.hpp"
#include "Gizmos/GLGizmoEmboss.hpp"
#include "Gizmos/GLGizmoSVG.hpp"
#include <boost/algorithm/string.hpp>
#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<GLGizmoSVG *>(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;

View File

@ -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);

View File

@ -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<float> 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<ProjectScale>(std::make_unique<ProjectZ>(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<ProjectScale>(
std::make_unique<ProjectZ>(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

View File

@ -38,12 +38,14 @@ public:
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
/// <param name="mouse_pos">Define position of new volume</param>
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
/// <summary>
/// Create new text without given position
/// </summary>
/// <param name="volume_type">Object part / Negative volume / Modifier</param>
void create_volume(const std::string &svg_file_path, ModelVolumeType volume_type);
void create_volume(ModelVolumeType volume_type); // first open file dialog
/// <summary>
/// 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)

View File

@ -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));

View File

@ -79,6 +79,7 @@ public:
MmuSegmentation,
Measure,
Emboss,
Svg,
Simplify,
Undefined
};