Fix copy of text
Fix store/load of volume type Fix grayed out of Menu item Change short curt from q to t
This commit is contained in:
parent
a725b3f62b
commit
7f5c6b0513
@ -135,6 +135,7 @@ add_library(libslic3r STATIC
|
||||
Model.hpp
|
||||
ModelArrange.hpp
|
||||
ModelArrange.cpp
|
||||
ModelVolumeType.hpp
|
||||
MultiMaterialSegmentation.cpp
|
||||
MultiMaterialSegmentation.hpp
|
||||
CustomGCode.cpp
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "Arrange.hpp"
|
||||
#include "CustomGCode.hpp"
|
||||
#include "enum_bitmask.hpp"
|
||||
#include "ModelVolumeType.hpp"
|
||||
#include "TextConfiguration.hpp"
|
||||
|
||||
#include <map>
|
||||
@ -220,16 +221,6 @@ private:
|
||||
friend class ModelObject;
|
||||
};
|
||||
|
||||
// Declared outside of ModelVolume, so it could be forward declared.
|
||||
enum class ModelVolumeType : int {
|
||||
INVALID = -1,
|
||||
MODEL_PART = 0,
|
||||
NEGATIVE_VOLUME,
|
||||
PARAMETER_MODIFIER,
|
||||
SUPPORT_BLOCKER,
|
||||
SUPPORT_ENFORCER,
|
||||
};
|
||||
|
||||
enum class ModelObjectCutAttribute : int { KeepUpper, KeepLower, FlipLower };
|
||||
using ModelObjectCutAttributes = enum_bitmask<ModelObjectCutAttribute>;
|
||||
ENABLE_ENUM_BITMASK_OPERATORS(ModelObjectCutAttribute);
|
||||
@ -801,7 +792,8 @@ private:
|
||||
ObjectBase(other),
|
||||
name(other.name), source(other.source), m_mesh(other.m_mesh), m_convex_hull(other.m_convex_hull),
|
||||
config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation),
|
||||
supported_facets(other.supported_facets), seam_facets(other.seam_facets), mmu_segmentation_facets(other.mmu_segmentation_facets)
|
||||
supported_facets(other.supported_facets), seam_facets(other.seam_facets),
|
||||
mmu_segmentation_facets(other.mmu_segmentation_facets), text_configuration(other.text_configuration)
|
||||
{
|
||||
assert(this->id().valid());
|
||||
assert(this->config.id().valid());
|
||||
@ -821,7 +813,9 @@ private:
|
||||
}
|
||||
// Providing a new mesh, therefore this volume will get a new unique ID assigned.
|
||||
ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) :
|
||||
name(other.name), source(other.source), m_mesh(new TriangleMesh(std::move(mesh))), config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation)
|
||||
name(other.name), source(other.source), m_mesh(new TriangleMesh(std::move(mesh))),
|
||||
config(other.config), m_type(other.m_type), object(object), m_transformation(other.m_transformation),
|
||||
text_configuration(other.text_configuration)
|
||||
{
|
||||
assert(this->id().valid());
|
||||
assert(this->config.id().valid());
|
||||
|
16
src/libslic3r/ModelVolumeType.hpp
Normal file
16
src/libslic3r/ModelVolumeType.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef slic3r_ModelVolumeType_hpp_
|
||||
#define slic3r_ModelVolumeType_hpp_
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
enum class ModelVolumeType : int {
|
||||
INVALID = -1,
|
||||
MODEL_PART = 0,
|
||||
NEGATIVE_VOLUME,
|
||||
PARAMETER_MODIFIER,
|
||||
SUPPORT_BLOCKER,
|
||||
SUPPORT_ENFORCER,
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
#endif /* slic3r_ModelVolumeType_hpp_ */
|
@ -56,9 +56,9 @@ struct TextConfiguration
|
||||
// user modification of font
|
||||
FontProp font_prop;
|
||||
|
||||
std::string text;
|
||||
std::string text = "None";
|
||||
|
||||
TextConfiguration() = default;
|
||||
TextConfiguration() = default; // optional needs empty constructor
|
||||
TextConfiguration(const FontItem & font_item,
|
||||
const FontProp & font_prop,
|
||||
const std::string &text)
|
||||
|
@ -2859,6 +2859,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
if (!m_initialized || !_set_current())
|
||||
return;
|
||||
|
||||
|
||||
#if ENABLE_RETINA_GL
|
||||
const float scale = m_retina_helper->get_scale_factor();
|
||||
evt.SetX(evt.GetX() * scale);
|
||||
@ -3281,6 +3282,18 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||
}
|
||||
|
||||
mouse_up_cleanup();
|
||||
} else if (evt.LeftDClick()) {
|
||||
// open text editation
|
||||
int vol_id = get_first_hover_volume_idx();
|
||||
const auto & cid = m_volumes.volumes[vol_id]->composite_id;
|
||||
const ModelObject *obj = m_model->objects[cid.object_id];
|
||||
const ModelVolume *mv = obj->volumes[cid.volume_id];
|
||||
if (mv->text_configuration.has_value()) {
|
||||
// select volume and open emboss gizmo
|
||||
deselect_all();
|
||||
m_selection.add(vol_id);
|
||||
m_gizmos.open_gizmo(GLGizmosManager::EType::Emboss);
|
||||
}
|
||||
}
|
||||
else if (evt.Moving()) {
|
||||
m_mouse.position = pos.cast<double>();
|
||||
|
@ -469,12 +469,9 @@ wxMenu* MenuFactory::append_submenu_add_generic(wxMenu* menu, ModelVolumeType ty
|
||||
|
||||
auto add_text = [type](wxCommandEvent &) {
|
||||
GLGizmosManager &mng = plater()->canvas3D()->get_gizmos_manager();
|
||||
if (mng.open_gizmo(GLGizmosManager::Emboss)) {
|
||||
GLGizmoBase * base = mng.get_current();
|
||||
GLGizmoEmboss *emboss = dynamic_cast<GLGizmoEmboss *>(base);
|
||||
if (emboss == nullptr) {
|
||||
int j = 42;
|
||||
} else
|
||||
if (mng.get_current_type() == GLGizmosManager::Emboss ||
|
||||
mng.open_gizmo(GLGizmosManager::Emboss)) {
|
||||
GLGizmoEmboss *emboss = dynamic_cast<GLGizmoEmboss *>(mng.get_current());
|
||||
emboss->set_volume_type(type);
|
||||
}
|
||||
};
|
||||
@ -898,6 +895,26 @@ void MenuFactory::append_menu_items_mirror(wxMenu* menu)
|
||||
[]() { return plater()->can_mirror(); }, m_parent);
|
||||
}
|
||||
|
||||
void MenuFactory::append_menu_item_edit_text(wxMenu *menu) {
|
||||
wxString name = _L("Edit text");
|
||||
wxString description = _L("Ability to change text, font, size, ...");
|
||||
std::string icon = "";
|
||||
append_menu_item(
|
||||
menu, wxID_ANY, name, description,
|
||||
[](wxCommandEvent &) {
|
||||
plater()->canvas3D()->get_gizmos_manager().open_gizmo(GLGizmosManager::Emboss);
|
||||
},
|
||||
icon, nullptr,
|
||||
[]() {
|
||||
const auto& sel = plater()->get_selection();
|
||||
if (sel.volumes_count() != 1) return false;
|
||||
auto cid = sel.get_volume(*sel.get_volume_idxs().begin());
|
||||
const ModelVolume *vol = plater()->canvas3D()->get_model()
|
||||
->objects[cid->object_idx()]->volumes[cid->volume_idx()];
|
||||
return vol->text_configuration.has_value();
|
||||
}, m_parent);
|
||||
}
|
||||
|
||||
MenuFactory::MenuFactory()
|
||||
{
|
||||
for (int i = 0; i < mtCount; i++) {
|
||||
@ -980,6 +997,7 @@ void MenuFactory::create_part_menu()
|
||||
#ifdef __WXOSX__
|
||||
append_menu_items_osx(menu);
|
||||
#endif // __WXOSX__
|
||||
append_menu_item_edit_text(menu);
|
||||
append_menu_item_delete(menu);
|
||||
append_menu_item_reload_from_disk(menu);
|
||||
append_menu_item_replace_with_stl(menu);
|
||||
|
@ -103,6 +103,7 @@ private:
|
||||
void append_menu_item_merge_to_multipart_object(wxMenu *menu);
|
||||
// void append_menu_item_merge_to_single_object(wxMenu *menu);
|
||||
void append_menu_items_mirror(wxMenu *menu);
|
||||
void append_menu_item_edit_text(wxMenu *menu);
|
||||
void append_menu_items_instance_manipulation(wxMenu *menu);
|
||||
void update_menu_items_instance_manipulation(MenuType type);
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ GLGizmoEmboss::~GLGizmoEmboss() {}
|
||||
bool GLGizmoEmboss::on_init()
|
||||
{
|
||||
//m_grabbers.emplace_back();
|
||||
m_shortcut_key = WXK_CONTROL_Q;
|
||||
m_shortcut_key = WXK_CONTROL_T;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -92,95 +92,9 @@ void GLGizmoEmboss::on_render_input_window(float x, float y, float bottom_limit)
|
||||
int flag = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoCollapse;
|
||||
m_imgui->begin(on_get_name(), flag);
|
||||
draw_window();
|
||||
|
||||
if (!m_font.has_value()) {
|
||||
ImGui::Text("Warning: No font is selected. Select correct one.");
|
||||
}
|
||||
|
||||
draw_font_list();
|
||||
|
||||
if (ImGui::Button(_L("choose font").c_str())) {
|
||||
choose_font_by_dialog();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_L("use system font").c_str())) {
|
||||
wxSystemSettings ss;
|
||||
wxFont f = ss.GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
size_t font_index = m_font_list.size();
|
||||
FontItem fi = WxFontUtils::get_font_item(f);
|
||||
m_font_list.emplace_back(fi);
|
||||
bool loaded = load_font(font_index);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
draw_add_button();
|
||||
|
||||
if (ImGui::Button("add svg")) {
|
||||
std::string filePath =
|
||||
"C:/Users/filip/Downloads/fontawesome-free-5.15.4-web/"
|
||||
"fontawesome-free-5.15.4-web/svgs/solid/bicycle.svg";
|
||||
filePath = "C:/Users/filip/Downloads/circle.svg";
|
||||
NSVGimage *image = nsvgParseFromFile(filePath.c_str(), "mm", 96.0f);
|
||||
ExPolygons polys = NSVGUtils::to_ExPolygons(image);
|
||||
|
||||
for (auto &poly : polys) poly.scale(1e5);
|
||||
SVG svg("converted.svg", BoundingBox(polys.front().contour.points));
|
||||
svg.draw(polys);
|
||||
|
||||
nsvgDelete(image);
|
||||
}
|
||||
|
||||
if (ImGui::InputFloat("Size[in mm]", &m_font_prop.size_in_mm)) {
|
||||
if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10;
|
||||
process();
|
||||
}
|
||||
if (ImGui::InputFloat("Emboss[in mm]", &m_font_prop.emboss)) process();
|
||||
if (ImGui::InputFloat("Flatness", &m_font_prop.flatness)) {
|
||||
if (m_font.has_value()) m_font->cache.clear();
|
||||
process();
|
||||
}
|
||||
if (ImGui::InputInt("CharGap[in font points]", &m_font_prop.char_gap)) process();
|
||||
if (ImGui::InputInt("LineGap[in font points]", &m_font_prop.line_gap)) process();
|
||||
|
||||
//ImGui::InputFloat3("Origin", m_orientation.origin.data());
|
||||
//if (ImGui::InputFloat3("Normal", m_normal.data())) m_normal.normalize();
|
||||
//if (ImGui::InputFloat3("Up", m_up.data())) m_up.normalize();
|
||||
|
||||
ImVec2 input_size(-FLT_MIN, ImGui::GetTextLineHeight() * 6);
|
||||
ImGuiInputTextFlags flags =
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_AllowTabInput
|
||||
| ImGuiInputTextFlags_::ImGuiInputTextFlags_AutoSelectAll
|
||||
//| ImGuiInputTextFlags_::ImGuiInputTextFlags_CallbackResize
|
||||
//|ImGuiInputTextFlags_::ImGuiInputTextFlags_CtrlEnterForNewLine
|
||||
;
|
||||
|
||||
|
||||
if (ImGui::InputTextMultiline("##Text", m_text.get(), m_text_size, input_size, flags)) {
|
||||
process();
|
||||
}
|
||||
|
||||
// change text size
|
||||
int max_text_size = static_cast<int>(m_text_size);
|
||||
if (ImGui::InputInt("max text size", &max_text_size, 8, 64)) {
|
||||
set_max_text_size(static_cast<size_t>(max_text_size));
|
||||
}
|
||||
|
||||
// draw 2d triangle in IMGUI
|
||||
ImVec2 t0(25, 25);
|
||||
ImVec2 t1(150, 5);
|
||||
ImVec2 t2(10, 100);
|
||||
ImU32 c = ImGui::ColorConvertFloat4ToU32(ImVec4(.0, .8, .2, 1.));
|
||||
ImGui::GetOverlayDrawList()->AddTriangleFilled(t0, t1, t2, c);
|
||||
|
||||
// create text volume when reselect volumes
|
||||
m_imgui->disabled_begin(!m_font.has_value());
|
||||
if (m_volume == nullptr) {
|
||||
if (ImGui::Button("Generate preview")) process();
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
|
||||
m_imgui->end();
|
||||
m_imgui->end(); //
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::on_set_state()
|
||||
@ -211,7 +125,7 @@ void GLGizmoEmboss::on_set_state()
|
||||
}
|
||||
|
||||
// Try set selected volume
|
||||
if (!set_volume()) {
|
||||
if (!load_configuration(get_selected_volume())) {
|
||||
// No volume with text selected, create new one
|
||||
set_default_configuration();
|
||||
process();
|
||||
@ -314,6 +228,7 @@ bool GLGizmoEmboss::gizmo_event(SLAGizmoEventType action,
|
||||
void GLGizmoEmboss::set_default_configuration() {
|
||||
set_text(_u8L("Embossed text"));
|
||||
m_font_prop = FontProp();
|
||||
m_volume_type = ModelVolumeType::MODEL_PART;
|
||||
// may be set default font?
|
||||
}
|
||||
|
||||
@ -328,10 +243,9 @@ void GLGizmoEmboss::check_selection()
|
||||
if (m_volume != nullptr)
|
||||
ImGui::ClearActiveID();
|
||||
|
||||
// is selected volume embossed?
|
||||
if (vol!= nullptr && vol->text_configuration.has_value()) {
|
||||
m_volume = vol;
|
||||
load_configuration(*vol->text_configuration);
|
||||
// is select embossed volume?
|
||||
if (load_configuration(vol)) {
|
||||
// successfull load volume for editing
|
||||
return;
|
||||
}
|
||||
|
||||
@ -441,7 +355,7 @@ bool GLGizmoEmboss::process() {
|
||||
return items.front();
|
||||
});
|
||||
|
||||
if (m_volume_type == ModelVolumeType::MODEL_PART)
|
||||
if (m_volume->type() == ModelVolumeType::MODEL_PART)
|
||||
// update printable state on canvas
|
||||
m_parent.update_instance_printable_state_for_object((size_t) object_idx);
|
||||
|
||||
@ -490,6 +404,89 @@ void GLGizmoEmboss::draw_add_button() {
|
||||
}
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::draw_window()
|
||||
{
|
||||
if (!m_font.has_value()) {
|
||||
ImGui::Text("Warning: No font is selected. Select correct one.");
|
||||
}
|
||||
|
||||
draw_font_list();
|
||||
|
||||
if (ImGui::Button(_L("choose font").c_str())) { choose_font_by_dialog(); }
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_L("use system font").c_str())) {
|
||||
wxSystemSettings ss;
|
||||
wxFont f = ss.GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
size_t font_index = m_font_list.size();
|
||||
FontItem fi = WxFontUtils::get_font_item(f);
|
||||
m_font_list.emplace_back(fi);
|
||||
bool loaded = load_font(font_index);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
draw_add_button();
|
||||
|
||||
if (ImGui::Button("add svg")) {
|
||||
std::string filePath =
|
||||
"C:/Users/filip/Downloads/fontawesome-free-5.15.4-web/"
|
||||
"fontawesome-free-5.15.4-web/svgs/solid/bicycle.svg";
|
||||
filePath = "C:/Users/filip/Downloads/circle.svg";
|
||||
NSVGimage *image = nsvgParseFromFile(filePath.c_str(), "mm", 96.0f);
|
||||
ExPolygons polys = NSVGUtils::to_ExPolygons(image);
|
||||
|
||||
for (auto &poly : polys) poly.scale(1e5);
|
||||
SVG svg("converted.svg", BoundingBox(polys.front().contour.points));
|
||||
svg.draw(polys);
|
||||
|
||||
nsvgDelete(image);
|
||||
}
|
||||
|
||||
if (ImGui::InputFloat("Size[in mm]", &m_font_prop.size_in_mm)) {
|
||||
if (m_font_prop.size_in_mm < 0.1) m_font_prop.size_in_mm = 10;
|
||||
process();
|
||||
}
|
||||
if (ImGui::InputFloat("Emboss[in mm]", &m_font_prop.emboss)) process();
|
||||
if (ImGui::InputFloat("Flatness", &m_font_prop.flatness)) {
|
||||
if (m_font.has_value()) m_font->cache.clear();
|
||||
process();
|
||||
}
|
||||
if (ImGui::InputInt("CharGap[in font points]", &m_font_prop.char_gap))
|
||||
process();
|
||||
if (ImGui::InputInt("LineGap[in font points]", &m_font_prop.line_gap))
|
||||
process();
|
||||
|
||||
// ImGui::InputFloat3("Origin", m_orientation.origin.data());
|
||||
// if (ImGui::InputFloat3("Normal", m_normal.data())) m_normal.normalize();
|
||||
// if (ImGui::InputFloat3("Up", m_up.data())) m_up.normalize();
|
||||
|
||||
ImVec2 input_size(-FLT_MIN, ImGui::GetTextLineHeight() * 6);
|
||||
ImGuiInputTextFlags flags =
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_AllowTabInput |
|
||||
ImGuiInputTextFlags_::ImGuiInputTextFlags_AutoSelectAll
|
||||
//| ImGuiInputTextFlags_::ImGuiInputTextFlags_CallbackResize
|
||||
//|ImGuiInputTextFlags_::ImGuiInputTextFlags_CtrlEnterForNewLine
|
||||
;
|
||||
|
||||
if (ImGui::InputTextMultiline("##Text", m_text.get(), m_text_size,
|
||||
input_size, flags)) {
|
||||
process();
|
||||
}
|
||||
|
||||
// change text size
|
||||
int max_text_size = static_cast<int>(m_text_size);
|
||||
if (ImGui::InputInt("max text size", &max_text_size, 8, 64)) {
|
||||
set_max_text_size(static_cast<size_t>(max_text_size));
|
||||
}
|
||||
|
||||
// Option to create text volume when reselect volumes
|
||||
m_imgui->disabled_begin(!m_font.has_value());
|
||||
if (m_volume == nullptr) {
|
||||
if (ImGui::Button("Generate preview")) process();
|
||||
}
|
||||
m_imgui->disabled_end();
|
||||
}
|
||||
|
||||
void GLGizmoEmboss::draw_font_list()
|
||||
{
|
||||
auto ¤t = m_font_list[m_font_selected];
|
||||
@ -623,28 +620,16 @@ void GLGizmoEmboss::add_fonts(const FontList &font_list) {
|
||||
sort_fonts();
|
||||
}
|
||||
|
||||
bool GLGizmoEmboss::set_volume()
|
||||
{
|
||||
ModelVolume *vol = get_selected_volume();
|
||||
// Is selected only one volume
|
||||
if (vol == nullptr) return false;
|
||||
|
||||
// Is volume created by Emboss?
|
||||
if (!vol->text_configuration.has_value()) return false;
|
||||
|
||||
// set selected volume
|
||||
m_volume = vol;
|
||||
load_configuration(*vol->text_configuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
TextConfiguration GLGizmoEmboss::create_configuration() {
|
||||
std::string text((const char *) m_text.get());
|
||||
return TextConfiguration(m_font_list[m_font_selected], m_font_prop, text);
|
||||
}
|
||||
|
||||
bool GLGizmoEmboss::load_configuration(const TextConfiguration &configuration)
|
||||
bool GLGizmoEmboss::load_configuration(ModelVolume *volume)
|
||||
{
|
||||
if (volume == nullptr) return false;
|
||||
if (!volume->text_configuration.has_value()) return false;
|
||||
const TextConfiguration &configuration = *volume->text_configuration;
|
||||
size_t index = m_font_list.size();
|
||||
for (const auto &font_item : m_font_list) {
|
||||
if (font_item.type == configuration.font_item.type &&
|
||||
@ -670,6 +655,8 @@ bool GLGizmoEmboss::load_configuration(const TextConfiguration &configuration)
|
||||
|
||||
m_font_prop = configuration.font_prop;
|
||||
set_text(configuration.text);
|
||||
m_volume_type = volume->type(); // not neccesary
|
||||
m_volume = volume;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ private:
|
||||
// create volume from text - main functionality
|
||||
bool process();
|
||||
void close();
|
||||
void draw_window();
|
||||
void draw_font_list();
|
||||
void draw_add_button();
|
||||
bool load_font();
|
||||
@ -59,11 +60,9 @@ private:
|
||||
void sort_fonts();
|
||||
void add_fonts(const FontList &font_list);
|
||||
|
||||
bool set_volume();
|
||||
|
||||
// Create object described how to make a Volume
|
||||
TextConfiguration create_configuration();
|
||||
bool load_configuration(const TextConfiguration& configuration);
|
||||
bool load_configuration(ModelVolume *volume);
|
||||
|
||||
std::string create_volume_name();
|
||||
|
||||
@ -99,6 +98,8 @@ private:
|
||||
|
||||
// actual volume
|
||||
ModelVolume *m_volume;
|
||||
|
||||
// Only for new created volume
|
||||
ModelVolumeType m_volume_type;
|
||||
|
||||
bool m_is_initialized;
|
||||
|
@ -154,6 +154,7 @@ void KBShortcutsDialog::fill_shortcuts()
|
||||
{ "L", L("Gizmo FDM paint-on supports") },
|
||||
{ "P", L("Gizmo FDM paint-on seam") },
|
||||
{ "N", L("Gizmo Multi Material painting") },
|
||||
{ "T", L("Gizmo Emboss Text / edit text")},
|
||||
{ "Esc", L("Unselect gizmo or clear selection") },
|
||||
{ "K", L("Change camera type (perspective, orthographic)") },
|
||||
{ "B", L("Zoom to Bed") },
|
||||
|
Loading…
Reference in New Issue
Block a user