mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-13 07:31:49 +08:00
Add icons(refresh and burn) to svg emboss
Add NSVG image to shape
This commit is contained in:
parent
ed10fefba8
commit
d530831e35
4
resources/icons/burn.svg
Normal file
4
resources/icons/burn.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16px" height="16px">
|
||||
<path fill="#808080" d="M 10.324265,12.637091 C 9.7126185,11.801826 9.4455652,11.319769 9.3860031,10.943437 9.3387131,10.644653 9.2775165,10.67725 9.032793,11.131535 8.8565876,11.45863 8.806364,11.904627 8.9008009,12.303679 8.330577,11.894019 7.6015175,10.031363 7.7096999,9.1284851 5.381808,10.598103 4.7271155,13.939753 5,16 2.9751051,14.608227 1.2851951,13.046842 1.3078808,10.57598 1.3305665,8.1051179 3.8432395,6.4490194 3.8697024,4.1713523 3.8727624,3.3745518 3.8421277,3.3793755 4.5118024,4.0701844 5.3014406,5.073513 5.8791344,5.964439 5.6521467,7.0731381 6.1486239,6.623741 6.3341015,5.940722 6.5401623,5.4070849 6.8689362,3.4222537 6.7021829,1.5642078 6,0 c 2.5998224,0.67409817 4.550997,3.5888298 4.623306,5.6887828 l 9.3e-4,0.4921817 C 11.260843,5.1624272 11.966175,4.3725405 13,4 12.774748,6.4272659 14.752236,8.539235 14.683585,10.819702 14.614934,13.100169 13.178608,15.41894 11,16 11.750123,14.792953 10.874074,13.393198 10.324265,12.637091 Z" />
|
||||
<path fill="#ed6b21" d="M 9.032793,11.131535 C 8.8565876,11.45863 8.806364,11.904627 8.9008009,12.303679 8.2684185,12.02479 7.7175594,10.368983 7.6751289,9.4545414 7.7066738,9.2878597 7.7222018,9.1411316 7.7097002,9.1284851 8.5239771,6.6708553 5.893441,7.0819045 6.5401623,5.4070849 6.8689362,3.4222537 6.7021829,1.5642078 6,0 c 2.5998224,0.67409817 4.550997,3.5888298 4.623306,5.6887828 l 9.3e-4,0.4921817 c -0.04706,1.5271028 -0.04706,2.5643146 -1.591443,4.9505705 z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
4
resources/icons/refresh.svg
Normal file
4
resources/icons/refresh.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16px" height="16px">
|
||||
<path fill="#ed6b21" d="m 0.80996126,4.2067338 c 0,0 1.45662384,-2.2486082 3.76076774,-3.45466511 2.3041438,-1.2060569 5.1439072,-0.85800021 7.005512,0.31082271 1.861604,1.1704417 2.488671,2.1563326 2.488671,2.1563326 l 1.603592,-0.9146606 c 0,0 0.331496,-0.1651245 0.331496,0.2185472 v 5.7388883 c 0,0 0,0.5115624 -0.387017,0.3286302 C 15.288019,8.4368366 11.764034,6.4326776 10.655236,5.801319 10.046132,5.5293491 10.581752,5.309183 10.581752,5.309183 l 1.548071,-0.8855209 c 0,0 -0.883446,-1.1056871 -2.1751379,-1.6917175 C 8.5715456,2.0147859 7.2765874,1.9289859 5.6909576,2.5279672 4.6572773,2.9181146 3.4390694,3.9185752 2.5621557,5.3966019 Z" />
|
||||
<path fill="#808080" d="m 15.19004,11.792751 c 0,0 -1.456624,2.248608 -3.760768,3.454665 C 9.125128,16.453472 6.2853646,16.107035 4.4237602,14.936593 2.5621557,13.766151 1.935089,12.78026 1.935089,12.78026 l -1.60359274,0.913042 c 0,0 -0.3314962496,0.165125 -0.3314962496,-0.218547 V 7.7342477 c 0,0 0,-0.5115623 0.3870177796,-0.3286303 0.32496429,0.1537925 3.84894891,2.1579516 4.95774671,2.7893106 0.609104,0.271969 0.073485,0.492136 0.073485,0.492136 l -1.5480712,0.88552 c 0,0 0.8834456,1.105688 2.1751379,1.691718 1.3831395,0.720396 2.6780976,0.806196 4.2637278,0.207215 1.033681,-0.390147 2.251888,-1.390608 3.128802,-2.868635 z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -3,6 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <memory> // unique_ptr
|
||||
#include <cereal/cereal.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
@ -11,6 +12,7 @@
|
||||
#include "Point.hpp" // Transform3d
|
||||
#include "ExPolygon.hpp"
|
||||
#include "ExPolygonSerialize.hpp"
|
||||
#include "nanosvg/nanosvg.h" // NSVGimage
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
@ -83,19 +85,31 @@ struct EmbossShape
|
||||
// Stored_Transform3d * fix_3mf_tr = Transform3d_before_store_to_3mf
|
||||
std::optional<Slic3r::Transform3d> fix_3mf_tr;
|
||||
|
||||
// file(.svg) path to source of shape
|
||||
// When empty can't reload from disk
|
||||
std::string svg_file_path;
|
||||
|
||||
struct SvgFile {
|
||||
// File(.svg) path on local computer
|
||||
// When empty can't reload from disk
|
||||
std::string path;
|
||||
|
||||
// File path into .3mf(.zip)
|
||||
// When empty svg is not stored into .3mf file yet.
|
||||
// and will create dialog to delete private data on save.
|
||||
std::string path_in_3mf;
|
||||
|
||||
// Loaded svg file data.
|
||||
// !!! It is not serialized on undo/redo stack
|
||||
std::shared_ptr<NSVGimage> image;
|
||||
};
|
||||
SvgFile svg_file;
|
||||
|
||||
// undo / redo stack recovery
|
||||
template<class Archive> void save(Archive &ar) const
|
||||
{
|
||||
ar(shapes_with_ids, scale, projection, svg_file_path);
|
||||
ar(shapes_with_ids, scale, projection, svg_file.path, svg_file.path_in_3mf);
|
||||
cereal::save(ar, fix_3mf_tr);
|
||||
}
|
||||
template<class Archive> void load(Archive &ar)
|
||||
{
|
||||
ar(shapes_with_ids, scale, projection, svg_file_path);
|
||||
ar(shapes_with_ids, scale, projection, svg_file.path, svg_file.path_in_3mf);
|
||||
cereal::load(ar, fix_3mf_tr);
|
||||
}
|
||||
};
|
||||
|
@ -3691,7 +3691,7 @@ std::string to_string(const ExPolygonsWithIds &shapes)
|
||||
|
||||
void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume &volume) {
|
||||
stream << " <" << SHAPE_TAG << " ";
|
||||
stream << SVG_FILE_PATH_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(es.svg_file_path) << "\" ";
|
||||
stream << SVG_FILE_PATH_ATTR << "=\"" << xml_escape_double_quotes_attribute_value(es.svg_file.path) << "\" ";
|
||||
stream << SHAPE_SCALE_ATTR << "=\"" << es.scale << "\" ";
|
||||
|
||||
std::string expolygons_str = to_string(es.shapes_with_ids); // cereal serialize expolygons
|
||||
|
@ -23,10 +23,10 @@ Point::coord_type to_coor(float val, float scale) { return static_cast<Point::co
|
||||
} // namespace
|
||||
|
||||
namespace Slic3r {
|
||||
Polygons to_polygons(NSVGimage *image, float tessTol, int max_level, float scale, bool is_y_negative)
|
||||
Polygons to_polygons(const NSVGimage &image, float tessTol, int max_level, float scale, bool is_y_negative)
|
||||
{
|
||||
Polygons polygons;
|
||||
for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
|
||||
for (NSVGshape *shape = image.shapes; shape != NULL; shape = shape->next) {
|
||||
if (!(shape->flags & NSVG_FLAGS_VISIBLE))
|
||||
continue;
|
||||
if (shape->fill.type == NSVG_PAINT_NONE)
|
||||
@ -64,10 +64,16 @@ Polygons to_polygons(NSVGimage *image, float tessTol, int max_level, float scale
|
||||
return polygons;
|
||||
}
|
||||
|
||||
ExPolygons to_expolygons(NSVGimage *image, float tessTol, int max_level, float scale, bool is_y_negative){
|
||||
ExPolygons to_expolygons(const NSVGimage &image, float tessTol, int max_level, float scale, bool is_y_negative){
|
||||
return union_ex(to_polygons(image, tessTol, max_level, scale, is_y_negative));
|
||||
}
|
||||
|
||||
NSVGimage_ptr nsvgParseFromFile(const std::string &filename, const char *units, float dpi)
|
||||
{
|
||||
NSVGimage *image = ::nsvgParseFromFile(filename.c_str(), units, dpi);
|
||||
return {image, ::nsvgDelete};
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
namespace {
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef slic3r_NSVGUtils_hpp_
|
||||
#define slic3r_NSVGUtils_hpp_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Polygon.hpp"
|
||||
#include "ExPolygon.hpp"
|
||||
#include "nanosvg/nanosvg.h" // load SVG file
|
||||
@ -19,8 +21,11 @@ namespace Slic3r {
|
||||
/// NOTE: Every point coor from image(float) is multiplied by scale and rounded to integer</param>
|
||||
/// <param name="is_y_negative">Flag is y negative, when true than y coor is multiplied by -1</param>
|
||||
/// <returns>Polygons extracted from svg</returns>
|
||||
Polygons to_polygons(NSVGimage *image, float tessTol = 10., int max_level = 10, float scale = 1.f, bool is_y_negative = true);
|
||||
ExPolygons to_expolygons(NSVGimage *image, float tessTol = 10., int max_level = 10, float scale = 1.f, bool is_y_negative = true);
|
||||
Polygons to_polygons(const NSVGimage &image, float tessTol = 10., int max_level = 10, float scale = 1.f, bool is_y_negative = true);
|
||||
ExPolygons to_expolygons(const NSVGimage &image, float tessTol = 10., int max_level = 10, float scale = 1.f, bool is_y_negative = true);
|
||||
|
||||
using NSVGimage_ptr = std::unique_ptr<NSVGimage, void (*)(NSVGimage*)>;
|
||||
NSVGimage_ptr nsvgParseFromFile(const std::string& filename, const char *units = "mm", float dpi = 96.0f);
|
||||
|
||||
} // namespace Slic3r
|
||||
#endif // slic3r_NSVGUtils_hpp_
|
||||
|
@ -68,7 +68,7 @@ std::string choose_svg_file();
|
||||
/// Let user to choose file with (S)calable (V)ector (G)raphics - SVG.
|
||||
/// Than let select contour
|
||||
/// </summary>
|
||||
/// <param name="filepath">SVG file path</param>
|
||||
/// <param name="filepath">SVG file path, when empty promt user to select one</param>
|
||||
/// <returns>EmbossShape to create</returns>
|
||||
EmbossShape select_shape(std::string_view filepath = "");
|
||||
|
||||
@ -80,14 +80,6 @@ EmbossShape select_shape(std::string_view filepath = "");
|
||||
/// <returns>Base data for emboss SVG</returns>
|
||||
DataBasePtr create_emboss_data_base(std::shared_ptr<std::atomic<bool>> &cancel, std::string_view filepath = "");
|
||||
|
||||
/// <summary>
|
||||
/// Create symbol '?' as default shape
|
||||
/// without source file
|
||||
/// with size 2cm
|
||||
/// </summary>
|
||||
/// <returns>Default shape to emboss</returns>
|
||||
ExPolygons default_shape();
|
||||
|
||||
/// <summary>
|
||||
/// Separate file name from file path.
|
||||
/// String after last delimiter and before last point
|
||||
@ -115,6 +107,12 @@ CreateVolumeParams create_input(GLCanvas3D &canvas, RaycastManager &raycaster, M
|
||||
enum class IconType : unsigned {
|
||||
reset_value,
|
||||
reset_value_hover,
|
||||
refresh,
|
||||
refresh_hover,
|
||||
change_file,
|
||||
change_file_hover,
|
||||
bake,
|
||||
bake_hover,
|
||||
lock,
|
||||
lock_hover,
|
||||
unlock,
|
||||
@ -126,6 +124,8 @@ enum class IconType : unsigned {
|
||||
// automatic calc of icon's count
|
||||
_count
|
||||
};
|
||||
// Do not forgot add loading of file in funtion:
|
||||
// IconManager::Icons init_icons(
|
||||
|
||||
const IconManager::Icon &get_icon(const IconManager::Icons &icons, IconType type) {
|
||||
return *icons[static_cast<unsigned>(type)]; }
|
||||
@ -140,7 +140,7 @@ struct GuiCfg
|
||||
float main_toolbar_height;
|
||||
|
||||
// Define bigger size(width or height)
|
||||
unsigned texture_max_size_px = 64;
|
||||
unsigned texture_max_size_px = 256;
|
||||
|
||||
// Zero means it is calculated in init function
|
||||
ImVec2 minimal_window_size = ImVec2(0, 0);
|
||||
@ -385,6 +385,12 @@ IconManager::Icons init_icons(IconManager &mng, const GuiCfg &cfg)
|
||||
IconManager::InitTypes init_types{
|
||||
{"undo.svg", size, IconManager::RasterType::white_only_data}, // undo
|
||||
{"undo.svg", size, IconManager::RasterType::color}, // undo_hovered
|
||||
{"refresh.svg", size, IconManager::RasterType::white_only_data}, // refresh
|
||||
{"refresh.svg", size, IconManager::RasterType::color}, // refresh_hovered
|
||||
{"open.svg", size, IconManager::RasterType::white_only_data}, // changhe_file
|
||||
{"open.svg", size, IconManager::RasterType::color}, // changhe_file_hovered
|
||||
{"burn.svg", size, IconManager::RasterType::white_only_data}, // bake_file
|
||||
{"burn.svg", size, IconManager::RasterType::color}, // bake_hovered
|
||||
{"lock_closed.svg", size, IconManager::RasterType::white_only_data}, // lock
|
||||
{"lock_open_f.svg", size, IconManager::RasterType::white_only_data}, // lock_hovered
|
||||
{"lock_open.svg", size, IconManager::RasterType::white_only_data}, // unlock
|
||||
@ -554,7 +560,7 @@ bool init_texture(Texture &texture, const ModelVolume &mv, unsigned max_size_px)
|
||||
return false;
|
||||
|
||||
const EmbossShape &es = *mv.emboss_shape;
|
||||
const std::string &filepath = es.svg_file_path;
|
||||
const std::string &filepath = es.svg_file.path;
|
||||
if (filepath.empty())
|
||||
return false;
|
||||
|
||||
@ -566,7 +572,7 @@ bool init_texture(Texture &texture, const ModelVolume &mv, unsigned max_size_px)
|
||||
ScopeGuard sg_image([image]() { nsvgDelete(image); });
|
||||
|
||||
// NOTE: Can not use es.shape --> it is aligned and one need offset in svg
|
||||
ExPolygons shape = to_expolygons(image);
|
||||
ExPolygons shape = to_expolygons(*image);
|
||||
if (shape.empty())
|
||||
return false;
|
||||
|
||||
@ -793,14 +799,10 @@ bool GLGizmoSVG::draw_preview(){
|
||||
|
||||
if (m_filename_preview.empty()){
|
||||
// create filename preview
|
||||
m_filename_preview = get_file_name(m_volume->emboss_shape->svg_file_path);
|
||||
m_filename_preview = get_file_name(m_volume->emboss_shape->svg_file.path);
|
||||
m_filename_preview = ImGuiWrapper::trunc(m_filename_preview, m_gui_cfg->input_width);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
ScopeGuard sg_group([]() { ImGui::EndGroup(); });
|
||||
|
||||
// Remove space between filename and gray suffix ".svg"
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||
|
||||
@ -812,19 +814,19 @@ bool GLGizmoSVG::draw_preview(){
|
||||
|
||||
is_hovered |= ImGui::IsItemHovered();
|
||||
if (is_hovered) {
|
||||
std::string tooltip = GUI::format(_L("SVG file path is \"%1%\" "), m_volume->emboss_shape->svg_file_path);
|
||||
std::string tooltip = GUI::format(_L("SVG file path is \"%1%\" "), m_volume->emboss_shape->svg_file.path);
|
||||
ImGui::SetTooltip("%s", tooltip.c_str());
|
||||
}
|
||||
|
||||
// Re-Load button
|
||||
bool can_reload = !m_volume_shape.svg_file_path.empty();
|
||||
bool can_reload = !m_volume_shape.svg_file.path.empty();
|
||||
if (can_reload) {
|
||||
ImGui::SameLine();
|
||||
if (clickable(get_icon(m_icons, IconType::reset_value), get_icon(m_icons, IconType::reset_value_hover))) {
|
||||
if (!boost::filesystem::exists(m_volume_shape.svg_file_path)) {
|
||||
m_volume_shape.svg_file_path.clear();
|
||||
if (clickable(get_icon(m_icons, IconType::refresh), get_icon(m_icons, IconType::refresh_hover))) {
|
||||
if (!boost::filesystem::exists(m_volume_shape.svg_file.path)) {
|
||||
m_volume_shape.svg_file.path.clear();
|
||||
} else {
|
||||
m_volume_shape.shapes_with_ids = select_shape(m_volume_shape.svg_file_path).shapes_with_ids;
|
||||
m_volume_shape.shapes_with_ids = select_shape(m_volume_shape.svg_file.path).shapes_with_ids;
|
||||
init_texture(m_texture, *m_volume, m_gui_cfg->texture_max_size_px);
|
||||
process();
|
||||
}
|
||||
@ -832,19 +834,22 @@ bool GLGizmoSVG::draw_preview(){
|
||||
ImGui::SetTooltip("%s", _u8L("Re-load SVG file from disk.").c_str());
|
||||
}
|
||||
|
||||
if (ImGui::Button(_u8L("Change file").c_str())) {
|
||||
ImGui::SameLine();
|
||||
if (clickable(get_icon(m_icons, IconType::change_file), get_icon(m_icons, IconType::change_file_hover))) {
|
||||
m_volume_shape.shapes_with_ids = select_shape().shapes_with_ids;
|
||||
init_texture(m_texture, *m_volume, m_gui_cfg->texture_max_size_px);
|
||||
process();
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", _u8L("Change to another .svg file").c_str());
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_u8L("Bake").c_str())) {
|
||||
if (clickable(get_icon(m_icons, IconType::bake), get_icon(m_icons, IconType::bake_hover))) {
|
||||
m_volume->emboss_shape.reset();
|
||||
close();
|
||||
return false;
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("%s", _u8L("Remove connection to source file to take care about copyright").c_str());
|
||||
ImGui::SetTooltip("%s", _u8L("Bake to uneditable part and save copyright of svg").c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1221,7 +1226,7 @@ std::string get_file_name(const std::string &file_path)
|
||||
|
||||
std::string volume_name(const EmbossShape &shape)
|
||||
{
|
||||
std::string file_name = get_file_name(shape.svg_file_path);
|
||||
std::string file_name = get_file_name(shape.svg_file.path);
|
||||
if (!file_name.empty())
|
||||
return file_name;
|
||||
return "SVG shape";
|
||||
@ -1244,7 +1249,7 @@ GuiCfg create_gui_configuration() {
|
||||
|
||||
float space = line_height_with_spacing - line_height;
|
||||
|
||||
cfg.icon_width = std::floor(line_height/8)*8;
|
||||
cfg.icon_width = std::max(std::round(line_height/8)*8, 8.f);
|
||||
|
||||
GuiCfg::Translations &tr = cfg.translations;
|
||||
|
||||
@ -1271,7 +1276,7 @@ GuiCfg create_gui_configuration() {
|
||||
ImVec2 letter_m_size = ImGui::CalcTextSize("M");
|
||||
const float count_letter_M_in_input = 12.f;
|
||||
cfg.input_width = letter_m_size.x * count_letter_M_in_input;
|
||||
|
||||
cfg.texture_max_size_px = std::round((cfg.input_width + cfg.input_offset + cfg.icon_width +space)/8) * 8;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
@ -1299,8 +1304,19 @@ std::string choose_svg_file()
|
||||
if (input_files.size() != 1)
|
||||
BOOST_LOG_TRIVIAL(warning) << "SVG file dialog result contain multiple files but only first is used.";
|
||||
|
||||
auto &input_file = input_files.front();
|
||||
std::string path = std::string(input_file.c_str());
|
||||
auto &input_file = input_files.front();
|
||||
std::string path = std::string(input_file.c_str());
|
||||
|
||||
if (!boost::filesystem::exists(path)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "SVG file dialog return invalid path.";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!boost::algorithm::iends_with(path, ".svg")) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "SVG file dialog return path without '.svg' tail";
|
||||
return {};
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -1309,32 +1325,6 @@ void translate(ExPolygons &expolys, const Point &p) {
|
||||
expoly.translate(p);
|
||||
}
|
||||
|
||||
NSVGimage *parse_from_file(const char *filepath){
|
||||
const char *unit_mm{"mm"};
|
||||
// common used DPI is 96 or 72
|
||||
float dpi = 96.0f;
|
||||
return nsvgParseFromFile(filepath, unit_mm, dpi);
|
||||
}
|
||||
|
||||
ExPolygons default_shape()
|
||||
{
|
||||
std::string file = Slic3r::resources_dir() + "/icons/question.svg";
|
||||
assert(boost::filesystem::exists(file));
|
||||
NSVGimage *image = parse_from_file(file.c_str());
|
||||
assert(image != nullptr);
|
||||
|
||||
// tesselation tolerance
|
||||
float tol = 1e-2f;
|
||||
int max_level = 10;
|
||||
float scale = static_cast<float>(2. / DEFAULT_SCALE);
|
||||
bool is_y_negative = true;
|
||||
ExPolygons shape = to_expolygons(image, tol, max_level, scale, is_y_negative);
|
||||
assert(!shape.empty());
|
||||
|
||||
nsvgDelete(image);
|
||||
return shape;
|
||||
}
|
||||
|
||||
EmbossShape select_shape(std::string_view filepath)
|
||||
{
|
||||
EmbossShape shape;
|
||||
@ -1342,32 +1332,42 @@ EmbossShape select_shape(std::string_view filepath)
|
||||
shape.projection.use_surface = false;
|
||||
|
||||
if (filepath.empty()) {
|
||||
shape.svg_file_path = choose_svg_file();
|
||||
if (shape.svg_file_path.empty())
|
||||
return {};
|
||||
// When empty open file dialog
|
||||
shape.svg_file.path = choose_svg_file();
|
||||
if (shape.svg_file.path.empty())
|
||||
return {}; // file was not selected
|
||||
} else {
|
||||
shape.svg_file_path = filepath; // copy
|
||||
shape.svg_file.path = filepath; // copy
|
||||
}
|
||||
|
||||
if (!boost::filesystem::exists(shape.svg_file.path)) {
|
||||
show_error(nullptr, GUI::format(_u8L("File(%1%) does NOT exists."), shape.svg_file.path));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!boost::filesystem::exists(shape.svg_file_path) ||
|
||||
!boost::algorithm::iends_with(shape.svg_file_path, ".svg"))
|
||||
if (!boost::algorithm::iends_with(shape.svg_file.path, ".svg")){
|
||||
show_error(nullptr, GUI::format(_u8L("File has to end with \".svg\" but you select: %1%"), shape.svg_file.path));
|
||||
return {};
|
||||
}
|
||||
|
||||
NSVGimage *image = parse_from_file(shape.svg_file_path.c_str());
|
||||
if (image == nullptr) return {};
|
||||
ScopeGuard sg([image]() { nsvgDelete(image); });
|
||||
shape.svg_file.image = nsvgParseFromFile(shape.svg_file.path);
|
||||
if (shape.svg_file.image.get() == nullptr) {
|
||||
show_error(nullptr, GUI::format(_u8L("Nano SVG parser can't load from file(%1%)."), shape.svg_file.path));
|
||||
return {};
|
||||
}
|
||||
|
||||
shape.scale = DEFAULT_SCALE; // loaded in mm
|
||||
|
||||
constexpr float tesselation_tolerance = 1e-2f;
|
||||
int max_level = 10;
|
||||
float scale = static_cast<float>(1 / shape.scale);
|
||||
bool is_y_negative = true;
|
||||
ExPolygons expoly = to_expolygons(image, tesselation_tolerance, max_level, scale, is_y_negative);
|
||||
ExPolygons expoly = to_expolygons(*shape.svg_file.image, tesselation_tolerance, max_level, scale, is_y_negative);
|
||||
|
||||
// Must contain some shapes !!!
|
||||
if (expoly.empty())
|
||||
expoly = default_shape();
|
||||
if (expoly.empty()) {
|
||||
show_error(nullptr, GUI::format(_u8L("SVG file(%1%) do NOT contain path to be able embossed."), shape.svg_file.path));
|
||||
return {};
|
||||
}
|
||||
|
||||
// SVG is used as centered
|
||||
// Do not disturb user by settings of pivot position
|
||||
|
@ -244,7 +244,7 @@ void scale(Polygons &polygons, double multiplicator) {
|
||||
Polygons load_polygons(const std::string &svg_file) {
|
||||
std::string file_path = TEST_DATA_DIR PATH_SEPARATOR + svg_file;
|
||||
NSVGimage *image = nsvgParseFromFile(file_path.c_str(), "px", 96.0f);
|
||||
Polygons polygons = to_polygons(image);
|
||||
Polygons polygons = to_polygons(*image);
|
||||
nsvgDelete(image);
|
||||
return polygons;
|
||||
}
|
||||
@ -289,7 +289,7 @@ TEST_CASE("Heal of points close to line", "[Emboss]")
|
||||
std::string file_name = "points_close_to_line.svg";
|
||||
std::string file_path = TEST_DATA_DIR PATH_SEPARATOR + file_name;
|
||||
NSVGimage *image = nsvgParseFromFile(file_path.c_str(), "px", 96.0f);
|
||||
Polygons polygons = to_polygons(image);
|
||||
Polygons polygons = to_polygons(*image);
|
||||
nsvgDelete(image);
|
||||
REQUIRE(polygons.size() == 1);
|
||||
Polygon polygon = polygons.front();
|
||||
@ -536,7 +536,7 @@ TEST_CASE("UndoRedo EmbossShape serialization", "[Emboss]")
|
||||
emboss.projection.depth = 5.;
|
||||
emboss.projection.use_surface = true;
|
||||
emboss.fix_3mf_tr = Transform3d::Identity();
|
||||
emboss.svg_file_path = "Everything starts somewhere, though many physicists disagree.\
|
||||
emboss.svg_file.path = "Everything starts somewhere, though many physicists disagree.\
|
||||
But people have always been dimly aware of the problem with the start of things.\
|
||||
They wonder how the snowplough driver gets to work,\
|
||||
or how the makers of dictionaries look up the spelling of words.";
|
||||
|
Loading…
x
Reference in New Issue
Block a user