Per letter emboss with align

This commit is contained in:
Filip Sykala - NTB T15p 2023-05-09 13:00:49 +02:00
parent 28b526167a
commit 43294950bd
4 changed files with 27 additions and 25 deletions

View File

@ -1870,19 +1870,19 @@ std::vector<double> Emboss::calculate_angles(int32_t distance, const PolygonPoin
return result; return result;
} }
PolygonPoints Emboss::sample_slice(const TextLine &slice, const BoundingBoxes &bbs, int32_t center_x, double scale) PolygonPoints Emboss::sample_slice(const TextLine &slice, const BoundingBoxes &bbs, double scale)
{ {
// find BB in center of line // find BB in center of line
size_t first_right_index = 0; size_t first_right_index = 0;
for (const BoundingBox &bb : bbs) for (const BoundingBox &bb : bbs)
if (bb.min.x() > center_x) { if (bb.min.x() > 0) {
break; break;
} else { } else {
++first_right_index; ++first_right_index;
} }
PolygonPoints samples(bbs.size()); PolygonPoints samples(bbs.size());
int32_t shapes_x_cursor = center_x; int32_t shapes_x_cursor = 0;
PolygonPoint cursor = slice.start; //copy PolygonPoint cursor = slice.start; //copy
@ -1908,7 +1908,7 @@ PolygonPoints Emboss::sample_slice(const TextLine &slice, const BoundingBoxes &b
samples[index] = create_sample(bbs[index], is_reverse); samples[index] = create_sample(bbs[index], is_reverse);
// calc transformation for letters on the Left side from center // calc transformation for letters on the Left side from center
shapes_x_cursor = center_x; shapes_x_cursor = 0;
cursor = slice.start; // copy cursor = slice.start; // copy
is_reverse = false; is_reverse = false;
for (size_t index_plus_one = first_right_index; index_plus_one > 0; --index_plus_one) { for (size_t index_plus_one = first_right_index; index_plus_one > 0; --index_plus_one) {

View File

@ -427,10 +427,9 @@ namespace Emboss
/// </summary> /// </summary>
/// <param name="slice">Polygon and start point</param> /// <param name="slice">Polygon and start point</param>
/// <param name="bbs">Bounding boxes of letter on one line</param> /// <param name="bbs">Bounding boxes of letter on one line</param>
/// <param name="center_x">Center x coor of bbs line</param>
/// <param name="scale">Scale for bbs</param> /// <param name="scale">Scale for bbs</param>
/// <returns>Sampled polygon by bounding boxes</returns> /// <returns>Sampled polygon by bounding boxes</returns>
PolygonPoints sample_slice(const TextLine &slice, const BoundingBoxes &bbs, int32_t center_x, double scale); PolygonPoints sample_slice(const TextLine &slice, const BoundingBoxes &bbs, double scale);
/// <summary> /// <summary>
/// Calculate angle for polygon point /// Calculate angle for polygon point

View File

@ -236,8 +236,9 @@ static bool draw_button(const IconManager::VIcons& icons, IconType type, bool di
/// </summary> /// </summary>
/// <param name="camera">Define view vector</param> /// <param name="camera">Define view vector</param>
/// <param name="canvas">Containe Selected Model to modify</param> /// <param name="canvas">Containe Selected Model to modify</param>
/// <param name="keep_up">Keep same up vector</param>
/// <returns>True when apply change otherwise false</returns> /// <returns>True when apply change otherwise false</returns>
static bool apply_camera_dir(const Camera &camera, GLCanvas3D &canvas); static bool apply_camera_dir(const Camera &camera, GLCanvas3D &canvas, bool keep_up);
} // namespace priv } // namespace priv
@ -3201,11 +3202,16 @@ void GLGizmoEmboss::draw_advanced()
} }
} }
if (exist_change) {
m_style_manager.clear_glyphs_cache();
process();
}
if (ImGui::Button(_u8L("Set text to face camera").c_str())) { if (ImGui::Button(_u8L("Set text to face camera").c_str())) {
assert(get_selected_volume(m_parent.get_selection()) == m_volume); assert(get_selected_volume(m_parent.get_selection()) == m_volume);
const Camera &cam = wxGetApp().plater()->get_camera(); const Camera &cam = wxGetApp().plater()->get_camera();
bool use_surface = m_style_manager.get_style().prop.use_surface; bool use_surface = m_style_manager.get_style().prop.use_surface;
if (priv::apply_camera_dir(cam, m_parent) && use_surface) if (priv::apply_camera_dir(cam, m_parent, m_keep_up) && use_surface)
process(); process();
} else if (ImGui::IsItemHovered()) { } else if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("%s", _u8L("Orient the text towards the camera.").c_str()); ImGui::SetTooltip("%s", _u8L("Orient the text towards the camera.").c_str());
@ -3218,7 +3224,7 @@ void GLGizmoEmboss::draw_advanced()
if (!m_text_lines.is_init()) if (!m_text_lines.is_init())
init_text_lines(); init_text_lines();
} }
exist_change = true; process();
} else if (ImGui::IsItemHovered()) { } else if (ImGui::IsItemHovered()) {
if (*per_glyph) { if (*per_glyph) {
ImGui::SetTooltip("%s", _u8L("Set global orientation for whole text.").c_str()); ImGui::SetTooltip("%s", _u8L("Set global orientation for whole text.").c_str());
@ -3234,6 +3240,7 @@ void GLGizmoEmboss::draw_advanced()
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(); init_text_lines();
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());
@ -3253,13 +3260,10 @@ void GLGizmoEmboss::draw_advanced()
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);
} // TODO: move with text in finalize to not change position
if (exist_change) {
m_style_manager.clear_glyphs_cache();
process(); process();
} }
#ifdef ALLOW_DEBUG_MODE #ifdef ALLOW_DEBUG_MODE
ImGui::Text("family = %s", (font_prop.family.has_value() ? ImGui::Text("family = %s", (font_prop.family.has_value() ?
font_prop.family->c_str() : font_prop.family->c_str() :
@ -3743,8 +3747,7 @@ void priv::change_window_position(std::optional<ImVec2>& output_window_offset, b
output_window_offset = ImVec2(-1, -1); // Cannot output_window_offset = ImVec2(-1, -1); // Cannot
} }
bool priv::apply_camera_dir(const Camera &camera, GLCanvas3D &canvas, bool keep_up) {
bool priv::apply_camera_dir(const Camera &camera, GLCanvas3D &canvas) {
const Vec3d &cam_dir = camera.get_dir_forward(); const Vec3d &cam_dir = camera.get_dir_forward();
Selection &sel = canvas.get_selection(); Selection &sel = canvas.get_selection();

View File

@ -457,11 +457,13 @@ template<typename Fnc> TriangleMesh create_mesh_per_glyph(DataBase &input, Fnc w
if (shapes.empty()) if (shapes.empty())
return {}; return {};
align_shape(prop.align, shapes);
const FontFile &ff = *font.font_file; const FontFile &ff = *font.font_file;
double shape_scale = get_shape_scale(prop, ff); double shape_scale = get_shape_scale(prop, ff);
BoundingBox extents; // whole text to find center // Precalculate bounding boxes of glyphs
// separate lines of text to vector // Separate lines of text to vector of Bounds
std::vector<BoundingBoxes> bbs(count_lines); std::vector<BoundingBoxes> bbs(count_lines);
size_t text_line_index = 0; size_t text_line_index = 0;
// s_i .. shape index // s_i .. shape index
@ -470,7 +472,6 @@ template<typename Fnc> TriangleMesh create_mesh_per_glyph(DataBase &input, Fnc w
BoundingBox bb; BoundingBox bb;
if (!shape.empty()) { if (!shape.empty()) {
bb = get_extents(shape); bb = get_extents(shape);
extents.merge(bb);
} }
BoundingBoxes &line_bbs = bbs[text_line_index]; BoundingBoxes &line_bbs = bbs[text_line_index];
line_bbs.push_back(bb); line_bbs.push_back(bb);
@ -487,14 +488,13 @@ template<typename Fnc> TriangleMesh create_mesh_per_glyph(DataBase &input, Fnc w
double em_2_mm = prop.size_in_mm / 2.; double em_2_mm = prop.size_in_mm / 2.;
int32_t em_2_polygon = static_cast<int32_t>(std::round(scale_(em_2_mm))); int32_t em_2_polygon = static_cast<int32_t>(std::round(scale_(em_2_mm)));
Point center = extents.center();
size_t s_i_offset = 0; // shape index offset(for next lines) size_t s_i_offset = 0; // shape index offset(for next lines)
indexed_triangle_set result; indexed_triangle_set result;
for (text_line_index = 0; text_line_index < input.text_lines.size(); ++text_line_index) { for (text_line_index = 0; text_line_index < input.text_lines.size(); ++text_line_index) {
const BoundingBoxes &line_bbs = bbs[text_line_index]; const BoundingBoxes &line_bbs = bbs[text_line_index];
const TextLine &line = input.text_lines[text_line_index]; const TextLine &line = input.text_lines[text_line_index];
// IMPROVE: do not precalculate samples do it inline - store result its // IMPROVE: do not precalculate samples do it inline - store result its
PolygonPoints samples = sample_slice(line, line_bbs, center.x(), shape_scale); PolygonPoints samples = sample_slice(line, line_bbs, shape_scale);
std::vector<double> angles = calculate_angles(em_2_polygon, samples, line.polygon); std::vector<double> angles = calculate_angles(em_2_polygon, samples, line.polygon);
for (size_t i = 0; i < line_bbs.size(); ++i) { for (size_t i = 0; i < line_bbs.size(); ++i) {