mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 04:55:55 +08:00
Create text volume with feature per letter transformation.
This commit is contained in:
parent
2bfe762dfb
commit
35044e29c3
@ -163,6 +163,8 @@ static constexpr const char *BOLDNESS_ATTR = "boldness";
|
|||||||
static constexpr const char *SKEW_ATTR = "skew";
|
static constexpr const char *SKEW_ATTR = "skew";
|
||||||
static constexpr const char *DISTANCE_ATTR = "distance";
|
static constexpr const char *DISTANCE_ATTR = "distance";
|
||||||
static constexpr const char *ANGLE_ATTR = "angle";
|
static constexpr const char *ANGLE_ATTR = "angle";
|
||||||
|
static constexpr const char *PER_GLYPH_ATTR = "per_glyph";
|
||||||
|
static constexpr const char *ALIGN_ATTR = "align";
|
||||||
static constexpr const char *COLLECTION_NUMBER_ATTR = "collection";
|
static constexpr const char *COLLECTION_NUMBER_ATTR = "collection";
|
||||||
|
|
||||||
static constexpr const char *FONT_FAMILY_ATTR = "family";
|
static constexpr const char *FONT_FAMILY_ATTR = "family";
|
||||||
@ -3530,6 +3532,10 @@ void TextConfigurationSerialization::to_xml(std::stringstream &stream, const Tex
|
|||||||
stream << DISTANCE_ATTR << "=\"" << *fp.distance << "\" ";
|
stream << DISTANCE_ATTR << "=\"" << *fp.distance << "\" ";
|
||||||
if (fp.angle.has_value())
|
if (fp.angle.has_value())
|
||||||
stream << ANGLE_ATTR << "=\"" << *fp.angle << "\" ";
|
stream << ANGLE_ATTR << "=\"" << *fp.angle << "\" ";
|
||||||
|
if (fp.per_glyph)
|
||||||
|
stream << PER_GLYPH_ATTR << "=\"" << 1 << "\" ";
|
||||||
|
if (fp.align != FontProp().align) // differ to default value? back compatibility
|
||||||
|
stream << ALIGN_ATTR << "=\"" << static_cast<int>(fp.align) << "\" ";
|
||||||
if (fp.collection_number.has_value())
|
if (fp.collection_number.has_value())
|
||||||
stream << COLLECTION_NUMBER_ATTR << "=\"" << *fp.collection_number << "\" ";
|
stream << COLLECTION_NUMBER_ATTR << "=\"" << *fp.collection_number << "\" ";
|
||||||
// font descriptor
|
// font descriptor
|
||||||
@ -3609,6 +3615,11 @@ std::optional<TextConfiguration> TextConfigurationSerialization::read(const char
|
|||||||
float angle = get_attribute_value_float(attributes, num_attributes, ANGLE_ATTR);
|
float angle = get_attribute_value_float(attributes, num_attributes, ANGLE_ATTR);
|
||||||
if (std::fabs(angle) > std::numeric_limits<float>::epsilon())
|
if (std::fabs(angle) > std::numeric_limits<float>::epsilon())
|
||||||
fp.angle = angle;
|
fp.angle = angle;
|
||||||
|
int per_glyph = get_attribute_value_int(attributes, num_attributes, PER_GLYPH_ATTR);
|
||||||
|
if (per_glyph == 1) fp.per_glyph = true;
|
||||||
|
int align = get_attribute_value_int(attributes, num_attributes, ALIGN_ATTR);
|
||||||
|
fp.align = static_cast<FontProp::Align>(align);
|
||||||
|
|
||||||
int collection_number = get_attribute_value_int(attributes, num_attributes, COLLECTION_NUMBER_ATTR);
|
int collection_number = get_attribute_value_int(attributes, num_attributes, COLLECTION_NUMBER_ATTR);
|
||||||
if (collection_number > 0) fp.collection_number = static_cast<unsigned int>(collection_number);
|
if (collection_number > 0) fp.collection_number = static_cast<unsigned int>(collection_number);
|
||||||
|
|
||||||
|
@ -63,20 +63,23 @@ struct FontProp
|
|||||||
// Distiguish projection per glyph
|
// Distiguish projection per glyph
|
||||||
bool per_glyph;
|
bool per_glyph;
|
||||||
|
|
||||||
|
// Enumerate type of allowed text align
|
||||||
enum class Align {
|
enum class Align {
|
||||||
|
// NOTE: default value must be zero - 3mf store
|
||||||
|
first_line_center = 0, // use Y zero same as first letter
|
||||||
first_line_left, // it depends on position of zero for first letter (no shape move)
|
first_line_left, // it depends on position of zero for first letter (no shape move)
|
||||||
first_line_right, // use Y zero same as first letter
|
first_line_right, // use Y zero same as first letter
|
||||||
first_line_center, // use Y zero same as first letter
|
center_center,
|
||||||
center_left,
|
center_left,
|
||||||
center_right,
|
center_right,
|
||||||
center_center,
|
top_center,
|
||||||
top_left,
|
top_left,
|
||||||
top_right,
|
top_right,
|
||||||
top_center,
|
bottom_center,
|
||||||
bottom_left,
|
bottom_left,
|
||||||
bottom_right,
|
bottom_right
|
||||||
bottom_center
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// change pivot of text
|
// change pivot of text
|
||||||
// When not set, center is used and is not stored
|
// When not set, center is used and is not stored
|
||||||
Align align = Align::first_line_center;
|
Align align = Align::first_line_center;
|
||||||
@ -110,6 +113,8 @@ struct FontProp
|
|||||||
char_gap == other.char_gap &&
|
char_gap == other.char_gap &&
|
||||||
line_gap == other.line_gap &&
|
line_gap == other.line_gap &&
|
||||||
use_surface == other.use_surface &&
|
use_surface == other.use_surface &&
|
||||||
|
per_glyph == other.per_glyph &&
|
||||||
|
align == other.align &&
|
||||||
is_approx(emboss, other.emboss) &&
|
is_approx(emboss, other.emboss) &&
|
||||||
is_approx(size_in_mm, other.size_in_mm) &&
|
is_approx(size_in_mm, other.size_in_mm) &&
|
||||||
is_approx(boldness, other.boldness) &&
|
is_approx(boldness, other.boldness) &&
|
||||||
@ -121,7 +126,7 @@ struct FontProp
|
|||||||
// undo / redo stack recovery
|
// undo / redo stack recovery
|
||||||
template<class Archive> void save(Archive &ar) const
|
template<class Archive> void save(Archive &ar) const
|
||||||
{
|
{
|
||||||
ar(emboss, use_surface, size_in_mm);
|
ar(emboss, use_surface, size_in_mm, per_glyph, align);
|
||||||
cereal::save(ar, char_gap);
|
cereal::save(ar, char_gap);
|
||||||
cereal::save(ar, line_gap);
|
cereal::save(ar, line_gap);
|
||||||
cereal::save(ar, boldness);
|
cereal::save(ar, boldness);
|
||||||
@ -136,7 +141,7 @@ struct FontProp
|
|||||||
}
|
}
|
||||||
template<class Archive> void load(Archive &ar)
|
template<class Archive> void load(Archive &ar)
|
||||||
{
|
{
|
||||||
ar(emboss, use_surface, size_in_mm);
|
ar(emboss, use_surface, size_in_mm, per_glyph, align);
|
||||||
cereal::load(ar, char_gap);
|
cereal::load(ar, char_gap);
|
||||||
cereal::load(ar, line_gap);
|
cereal::load(ar, line_gap);
|
||||||
cereal::load(ar, boldness);
|
cereal::load(ar, boldness);
|
||||||
|
@ -146,9 +146,15 @@ namespace priv {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="text">Text to emboss</param>
|
/// <param name="text">Text to emboss</param>
|
||||||
/// <param name="style_manager">Keep actual selected style</param>
|
/// <param name="style_manager">Keep actual selected style</param>
|
||||||
|
/// <param name="text_lines">Needed when transform per glyph</param>
|
||||||
|
/// <param name="selection">Needed for transform per glyph</param>
|
||||||
/// <param name="cancel">Cancel for previous job</param>
|
/// <param name="cancel">Cancel for previous job</param>
|
||||||
/// <returns>Base data for emboss text</returns>
|
/// <returns>Base data for emboss text</returns>
|
||||||
static DataBase create_emboss_data_base(const std::string &text, StyleManager &style_manager, std::shared_ptr<std::atomic<bool>> &cancel);
|
static DataBase create_emboss_data_base(const std::string &text,
|
||||||
|
StyleManager &style_manager,
|
||||||
|
TextLinesModel &text_lines,
|
||||||
|
const Selection &selection,
|
||||||
|
std::shared_ptr<std::atomic<bool>> &cancel);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start job for add new volume to object with given transformation
|
/// Start job for add new volume to object with given transformation
|
||||||
@ -242,13 +248,17 @@ static bool apply_camera_dir(const Camera &camera, GLCanvas3D &canvas, bool keep
|
|||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /* const*/ StyleManager &style_manager, unsigned count_lines=0);
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mouse_pos)
|
void GLGizmoEmboss::create_volume(ModelVolumeType volume_type, const Vec2d& mouse_pos)
|
||||||
{
|
{
|
||||||
if (!init_create(volume_type))
|
if (!init_create(volume_type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const GLVolume *gl_volume = get_first_hovered_gl_volume(m_parent);
|
const GLVolume *gl_volume = get_first_hovered_gl_volume(m_parent);
|
||||||
DataBase emboss_data = priv::create_emboss_data_base(m_text, m_style_manager, m_job_cancel);
|
DataBase emboss_data = priv::create_emboss_data_base(m_text, m_style_manager, m_text_lines, m_parent.get_selection(), m_job_cancel);
|
||||||
bool is_simple_mode = wxGetApp().get_mode() == comSimple;
|
bool is_simple_mode = wxGetApp().get_mode() == comSimple;
|
||||||
if (gl_volume != nullptr && !is_simple_mode) {
|
if (gl_volume != nullptr && !is_simple_mode) {
|
||||||
// Try to cast ray into scene and find object for add volume
|
// Try to cast ray into scene and find object for add volume
|
||||||
@ -275,7 +285,7 @@ void GLGizmoEmboss::create_volume(ModelVolumeType volume_type)
|
|||||||
|
|
||||||
Size s = m_parent.get_canvas_size();
|
Size s = m_parent.get_canvas_size();
|
||||||
Vec2d screen_center(s.get_width() / 2., s.get_height() / 2.);
|
Vec2d screen_center(s.get_width() / 2., s.get_height() / 2.);
|
||||||
DataBase emboss_data = priv::create_emboss_data_base(m_text, m_style_manager, m_job_cancel);
|
DataBase emboss_data = priv::create_emboss_data_base(m_text, m_style_manager, m_text_lines, m_parent.get_selection(), m_job_cancel);
|
||||||
const ModelObjectPtrs &objects = selection.get_model()->objects;
|
const ModelObjectPtrs &objects = selection.get_model()->objects;
|
||||||
bool is_simple_mode = wxGetApp().get_mode() == comSimple;
|
bool is_simple_mode = wxGetApp().get_mode() == comSimple;
|
||||||
// No selected object so create new object
|
// No selected object so create new object
|
||||||
@ -559,7 +569,7 @@ void GLGizmoEmboss::volume_transformation_changing()
|
|||||||
}
|
}
|
||||||
const FontProp &prop = m_volume->text_configuration->style.prop;
|
const FontProp &prop = m_volume->text_configuration->style.prop;
|
||||||
if (prop.per_glyph)
|
if (prop.per_glyph)
|
||||||
init_text_lines(m_text_lines.get_lines().size());
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager, m_text_lines.get_lines().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::volume_transformation_changed()
|
void GLGizmoEmboss::volume_transformation_changed()
|
||||||
@ -571,7 +581,7 @@ void GLGizmoEmboss::volume_transformation_changed()
|
|||||||
|
|
||||||
const FontProp &prop = m_volume->text_configuration->style.prop;
|
const FontProp &prop = m_volume->text_configuration->style.prop;
|
||||||
if (prop.per_glyph)
|
if (prop.per_glyph)
|
||||||
init_text_lines(m_text_lines.get_lines().size());
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager, m_text_lines.get_lines().size());
|
||||||
|
|
||||||
// Update surface by new position
|
// Update surface by new position
|
||||||
if (prop.use_surface || prop.per_glyph)
|
if (prop.use_surface || prop.per_glyph)
|
||||||
@ -1047,11 +1057,13 @@ EmbossStyles GLGizmoEmboss::create_default_styles()
|
|||||||
return styles;
|
return styles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::init_text_lines(unsigned count_lines){
|
namespace {
|
||||||
assert(m_style_manager.is_active_font());
|
void init_text_lines(TextLinesModel &text_lines, const Selection& selection, /* const*/ StyleManager &style_manager, unsigned count_lines)
|
||||||
if (!m_style_manager.is_active_font())
|
{
|
||||||
|
assert(style_manager.is_active_font());
|
||||||
|
if (!style_manager.is_active_font())
|
||||||
return;
|
return;
|
||||||
const auto& ffc = m_style_manager.get_font_file_with_cache();
|
const auto &ffc = style_manager.get_font_file_with_cache();
|
||||||
assert(ffc.has_value());
|
assert(ffc.has_value());
|
||||||
if (!ffc.has_value())
|
if (!ffc.has_value())
|
||||||
return;
|
return;
|
||||||
@ -1060,14 +1072,12 @@ void GLGizmoEmboss::init_text_lines(unsigned count_lines){
|
|||||||
if (ff_ptr == nullptr)
|
if (ff_ptr == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_volume->is_the_only_one_part())
|
const FontProp &fp = style_manager.get_font_prop();
|
||||||
return;
|
|
||||||
|
|
||||||
const FontProp& fp = m_style_manager.get_font_prop();
|
|
||||||
const FontFile &ff = *ff_ptr;
|
const FontFile &ff = *ff_ptr;
|
||||||
|
|
||||||
double line_height = TextLinesModel::calc_line_height(ff, fp);
|
double line_height = TextLinesModel::calc_line_height(ff, fp);
|
||||||
m_text_lines.init(m_parent.get_selection(), line_height, count_lines);
|
text_lines.init(selection, line_height, count_lines);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoEmboss::set_volume_by_selection()
|
void GLGizmoEmboss::set_volume_by_selection()
|
||||||
@ -1209,7 +1219,7 @@ void GLGizmoEmboss::set_volume_by_selection()
|
|||||||
m_volume_id = volume->id();
|
m_volume_id = volume->id();
|
||||||
|
|
||||||
if (tc.style.prop.per_glyph)
|
if (tc.style.prop.per_glyph)
|
||||||
init_text_lines();
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager);
|
||||||
|
|
||||||
// Calculate current angle of up vector
|
// Calculate current angle of up vector
|
||||||
assert(m_style_manager.is_active_font());
|
assert(m_style_manager.is_active_font());
|
||||||
@ -1292,12 +1302,8 @@ bool GLGizmoEmboss::process()
|
|||||||
// exist loaded font file?
|
// exist loaded font file?
|
||||||
if (!m_style_manager.is_active_font()) return false;
|
if (!m_style_manager.is_active_font()) return false;
|
||||||
|
|
||||||
DataUpdate data{priv::create_emboss_data_base(m_text, m_style_manager, m_job_cancel), m_volume->id()};
|
DataUpdate data{priv::create_emboss_data_base(m_text, m_style_manager, m_text_lines, m_parent.get_selection(), m_job_cancel),
|
||||||
if (data.text_configuration.style.prop.per_glyph){
|
m_volume->id()};
|
||||||
if (!m_text_lines.is_init())
|
|
||||||
init_text_lines();
|
|
||||||
data.text_lines = m_text_lines.get_lines(); // copy
|
|
||||||
}
|
|
||||||
std::unique_ptr<Job> job = nullptr;
|
std::unique_ptr<Job> job = nullptr;
|
||||||
|
|
||||||
// check cutting from source mesh
|
// check cutting from source mesh
|
||||||
@ -1547,7 +1553,7 @@ void GLGizmoEmboss::draw_text_input()
|
|||||||
unsigned count_lines = get_count_lines(m_text);
|
unsigned count_lines = get_count_lines(m_text);
|
||||||
if (count_lines != m_text_lines.get_lines().size())
|
if (count_lines != m_text_lines.get_lines().size())
|
||||||
// Necesarry to initialize count by given number (differ from stored in volume at the moment)
|
// Necesarry to initialize count by given number (differ from stored in volume at the moment)
|
||||||
init_text_lines(count_lines);
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager, count_lines);
|
||||||
}
|
}
|
||||||
process();
|
process();
|
||||||
range_text = create_range_text_prep();
|
range_text = create_range_text_prep();
|
||||||
@ -3231,7 +3237,7 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
if (ImGui::Checkbox("##PerGlyph", per_glyph)) {
|
if (ImGui::Checkbox("##PerGlyph", per_glyph)) {
|
||||||
if (*per_glyph) {
|
if (*per_glyph) {
|
||||||
if (!m_text_lines.is_init())
|
if (!m_text_lines.is_init())
|
||||||
init_text_lines();
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager);
|
||||||
}
|
}
|
||||||
process();
|
process();
|
||||||
} else if (ImGui::IsItemHovered()) {
|
} else if (ImGui::IsItemHovered()) {
|
||||||
@ -3240,7 +3246,7 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
} else {
|
} else {
|
||||||
ImGui::SetTooltip("%s", _u8L("Set position and orientation of projection per Glyph.").c_str());
|
ImGui::SetTooltip("%s", _u8L("Set position and orientation of projection per Glyph.").c_str());
|
||||||
if (!m_text_lines.is_init())
|
if (!m_text_lines.is_init())
|
||||||
init_text_lines();
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager);
|
||||||
}
|
}
|
||||||
} else if (!*per_glyph && m_text_lines.is_init())
|
} else if (!*per_glyph && m_text_lines.is_init())
|
||||||
m_text_lines.reset();
|
m_text_lines.reset();
|
||||||
@ -3248,24 +3254,24 @@ void GLGizmoEmboss::draw_advanced()
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(100);
|
ImGui::SetNextItemWidth(100);
|
||||||
if (ImGui::SliderFloat("##base_line_y_offset", &m_text_lines.offset, -10.f, 10.f, "%f mm")) {
|
if (ImGui::SliderFloat("##base_line_y_offset", &m_text_lines.offset, -10.f, 10.f, "%f mm")) {
|
||||||
init_text_lines(m_text_lines.get_lines().size());
|
init_text_lines(m_text_lines, m_parent.get_selection(), m_style_manager, m_text_lines.get_lines().size());
|
||||||
process();
|
process();
|
||||||
} else if (ImGui::IsItemHovered())
|
} else if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("%s", _u8L("Move base line (up/down) for allign letters").c_str());
|
ImGui::SetTooltip("%s", _u8L("Move base line (up/down) for allign letters").c_str());
|
||||||
|
|
||||||
// order must match align enum
|
// order must match align enum
|
||||||
const char* align_names[] = {"first_line_left",
|
const char* align_names[] = { "first_line_center",
|
||||||
|
"first_line_left",
|
||||||
"first_line_right",
|
"first_line_right",
|
||||||
"first_line_center",
|
"center_center",
|
||||||
"center_left",
|
"center_left",
|
||||||
"center_right",
|
"center_right",
|
||||||
"center_center",
|
|
||||||
"top_left",
|
|
||||||
"top_right",
|
|
||||||
"top_center",
|
"top_center",
|
||||||
|
"top_left",
|
||||||
|
"top_right",
|
||||||
|
"bottom_center",
|
||||||
"bottom_left",
|
"bottom_left",
|
||||||
"bottom_right",
|
"bottom_right"};
|
||||||
"bottom_center"};
|
|
||||||
int selected_align = static_cast<int>(font_prop.align);
|
int selected_align = static_cast<int>(font_prop.align);
|
||||||
if (ImGui::Combo("align", &selected_align, align_names, IM_ARRAYSIZE(align_names))) {
|
if (ImGui::Combo("align", &selected_align, align_names, IM_ARRAYSIZE(align_names))) {
|
||||||
font_prop.align = static_cast<FontProp::Align>(selected_align);
|
font_prop.align = static_cast<FontProp::Align>(selected_align);
|
||||||
@ -3542,7 +3548,7 @@ bool priv::draw_button(const IconManager::VIcons &icons, IconType type, bool dis
|
|||||||
// priv namespace implementation
|
// priv namespace implementation
|
||||||
///////////////
|
///////////////
|
||||||
|
|
||||||
DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &style_manager, std::shared_ptr<std::atomic<bool>>& cancel)
|
DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &style_manager, TextLinesModel& text_lines, const Selection& selection, std::shared_ptr<std::atomic<bool>>& cancel)
|
||||||
{
|
{
|
||||||
// create volume_name
|
// create volume_name
|
||||||
std::string volume_name = text; // copy
|
std::string volume_name = text; // copy
|
||||||
@ -3565,6 +3571,12 @@ DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &st
|
|||||||
assert(es.path.compare(WxFontUtils::store_wxFont(style_manager.get_wx_font())) == 0);
|
assert(es.path.compare(WxFontUtils::store_wxFont(style_manager.get_wx_font())) == 0);
|
||||||
TextConfiguration tc{es, text};
|
TextConfiguration tc{es, text};
|
||||||
|
|
||||||
|
if (es.prop.per_glyph) {
|
||||||
|
if (!text_lines.is_init())
|
||||||
|
init_text_lines(text_lines, selection, style_manager);
|
||||||
|
} else
|
||||||
|
text_lines.reset();
|
||||||
|
|
||||||
// Cancel previous Job, when it is in process
|
// Cancel previous Job, when it is in process
|
||||||
// worker.cancel(); --> Use less in this case I want cancel only previous EmbossJob no other jobs
|
// worker.cancel(); --> Use less in this case I want cancel only previous EmbossJob no other jobs
|
||||||
// Cancel only EmbossUpdateJob no others
|
// Cancel only EmbossUpdateJob no others
|
||||||
@ -3572,7 +3584,7 @@ DataBase priv::create_emboss_data_base(const std::string &text, StyleManager &st
|
|||||||
cancel->store(true);
|
cancel->store(true);
|
||||||
// create new shared ptr to cancel new job
|
// create new shared ptr to cancel new job
|
||||||
cancel = std::make_shared<std::atomic<bool>>(false);
|
cancel = std::make_shared<std::atomic<bool>>(false);
|
||||||
return Slic3r::GUI::Emboss::DataBase{style_manager.get_font_file_with_cache(), tc, volume_name, cancel};
|
return Slic3r::GUI::Emboss::DataBase{style_manager.get_font_file_with_cache(), tc, volume_name, cancel, text_lines.get_lines()};
|
||||||
}
|
}
|
||||||
|
|
||||||
void priv::start_create_object_job(DataBase &emboss_data, const Vec2d &coor)
|
void priv::start_create_object_job(DataBase &emboss_data, const Vec2d &coor)
|
||||||
|
@ -317,7 +317,6 @@ private:
|
|||||||
|
|
||||||
// Keep information about curvature of text line around surface
|
// Keep information about curvature of text line around surface
|
||||||
TextLinesModel m_text_lines;
|
TextLinesModel m_text_lines;
|
||||||
void init_text_lines(unsigned count_lines = 0);
|
|
||||||
|
|
||||||
// Rotation gizmo
|
// Rotation gizmo
|
||||||
GLGizmoRotate m_rotate_gizmo;
|
GLGizmoRotate m_rotate_gizmo;
|
||||||
|
@ -253,6 +253,9 @@ GLModel::Geometry create_geometry(const TextLines &lines)
|
|||||||
|
|
||||||
void TextLinesModel::init(const Selection &selection, double line_height, unsigned count_lines)
|
void TextLinesModel::init(const Selection &selection, double line_height, unsigned count_lines)
|
||||||
{
|
{
|
||||||
|
m_model.reset();
|
||||||
|
m_lines.clear();
|
||||||
|
|
||||||
const GLVolume *gl_volume_ptr = selection.get_first_volume();
|
const GLVolume *gl_volume_ptr = selection.get_first_volume();
|
||||||
if (gl_volume_ptr == nullptr)
|
if (gl_volume_ptr == nullptr)
|
||||||
return;
|
return;
|
||||||
@ -267,6 +270,8 @@ void TextLinesModel::init(const Selection &selection, double line_height, unsign
|
|||||||
if (mv_ptr == nullptr)
|
if (mv_ptr == nullptr)
|
||||||
return;
|
return;
|
||||||
const ModelVolume &mv = *mv_ptr;
|
const ModelVolume &mv = *mv_ptr;
|
||||||
|
if (mv.is_the_only_one_part())
|
||||||
|
return;
|
||||||
|
|
||||||
// calculate count lines when not set
|
// calculate count lines when not set
|
||||||
if (count_lines == 0) {
|
if (count_lines == 0) {
|
||||||
@ -317,7 +322,6 @@ void TextLinesModel::init(const Selection &selection, double line_height, unsign
|
|||||||
for (size_t i = 0; i < count_lines; ++i)
|
for (size_t i = 0; i < count_lines; ++i)
|
||||||
m_lines[i].y = line_centers[i];
|
m_lines[i].y = line_centers[i];
|
||||||
|
|
||||||
m_model.reset();
|
|
||||||
//*
|
//*
|
||||||
GLModel::Geometry geometry = create_geometry(m_lines);
|
GLModel::Geometry geometry = create_geometry(m_lines);
|
||||||
if (geometry.vertices_count() == 0 || geometry.indices_count() == 0)
|
if (geometry.vertices_count() == 0 || geometry.indices_count() == 0)
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
void render(const Transform3d &text_world);
|
void render(const Transform3d &text_world);
|
||||||
|
|
||||||
bool is_init() const { return m_model.is_initialized(); }
|
bool is_init() const { return m_model.is_initialized(); }
|
||||||
void reset() { m_model.reset(); }
|
void reset() { m_model.reset(); m_lines.clear(); }
|
||||||
const Slic3r::Emboss::TextLines &get_lines() const { return m_lines; }
|
const Slic3r::Emboss::TextLines &get_lines() const { return m_lines; }
|
||||||
static double calc_line_height(const Slic3r::Emboss::FontFile& ff, const FontProp& fp);
|
static double calc_line_height(const Slic3r::Emboss::FontFile& ff, const FontProp& fp);
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user