OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::Emboss Namespace Reference

class with only static function add ability to engraved OR raised text OR polygons onto model surface More...

Classes

struct  Glyph
struct  FontFile
 keep information from file about font (store file data itself) More...
struct  FontFileWithCache
 Add caching for shape of glyphs. More...
class  IProject3d
 Project spatial point. More...
class  IProjection
 Project 2d point into space Could be plane, sphere, cylindric, ... More...
class  ProjectZ
class  ProjectScale
class  ProjectTransform
class  OrthoProject3d
class  OrthoProject
struct  TextLine
 Define polygon for draw letters. More...

Typedefs

using Glyphs = std::map<int, Glyph>
using TextLines = std::vector<TextLine>

Functions

EmbossStyles get_font_list ()
 Collect fonts registred inside OS.
std::optional< std::wstring > get_font_path (const std::wstring &font_face_name)
 OS dependent function to get location of font by its name descriptor.
std::unique_ptr< FontFile > create_font_file (const char *file_path)
 Load font file into buffer.
std::unique_ptr< FontFile > create_font_file (std::unique_ptr< std::vector< unsigned char > > data)
std::optional< Glyph > letter2glyph (const FontFile &font, unsigned int font_index, int letter, float flatness)
 convert letter into polygons
HealedExPolygons text2shapes (FontFileWithCache &font, const char *text, const FontProp &font_prop, const std::function< bool()> &was_canceled=[]() {return false;})
 Convert text into polygons.
ExPolygonsWithIds text2vshapes (FontFileWithCache &font, const std::wstring &text, const FontProp &font_prop, const std::function< bool()> &was_canceled=[]() {return false;})
unsigned get_count_lines (const std::wstring &ws)
 Sum of character '
'.
unsigned get_count_lines (const std::string &text)
unsigned get_count_lines (const ExPolygonsWithIds &shape)
HealedExPolygons heal_polygons (const Polygons &shape, bool is_non_zero=true, unsigned max_iteration=10)
 Fix duplicit points and self intersections in polygons. Also try to reduce amount of points and remove useless polygon parts.
bool heal_expolygons (ExPolygons &shape, unsigned max_iteration=10)
 NOTE: call Slic3r::union_ex before this call.
bool divide_segments_for_close_point (ExPolygons &expolygons, double distance)
 Divide line segments in place near to point (which could lead to self intersection due to preccision) Remove same neighbors Note: Possible part of heal shape.
void apply_transformation (const std::optional< float > &angle, const std::optional< float > &distance, Transform3d &transformation)
 Use data from font property to modify transformation.
bool is_italic (const FontFile &font, unsigned int font_index)
 Read information from naming table of font file search for italic (or oblique), bold italic (or bold oblique).
std::string create_range_text (const std::string &text, const FontFile &font, unsigned int font_index, bool *exist_unknown=nullptr)
 Create unique character set from string with filtered from text with only character from font.
double get_text_shape_scale (const FontProp &fp, const FontFile &ff)
 Calculate scale for glyph shape convert from shape points to mm.
const FontFile::Info & get_font_info (const FontFile &font, const FontProp &prop)
 getter of font info by collection defined in prop
int get_line_height (const FontFile &font, const FontProp &prop)
 Read from font file and properties height of line with spacing.
double get_align_y_offset_in_mm (FontProp::VerticalAlign align, unsigned count_lines, const FontFile &ff, const FontProp &fp)
 Calculate Vertical align.
indexed_triangle_set polygons2model (const ExPolygons &shape2d, const IProjection &projection)
 Create triangle model for text.
Vec3d suggest_up (const Vec3d normal, double up_limit=0.9)
 Suggest wanted up vector of embossed text by emboss direction.
std::optional< float > calc_up (const Transform3d &tr, double up_limit=0.9)
 By transformation calculate angle between suggested and actual up vector.
Transform3d create_transformation_onto_surface (const Vec3d &position, const Vec3d &normal, double up_limit=0.9)
 Create transformation for emboss text object to lay on surface point.
PolygonPoints sample_slice (const TextLine &slice, const BoundingBoxes &bbs, double scale)
 Sample slice polygon by bounding boxes centers slice start point has shape_center_x coor.
double calculate_angle (int32_t distance, PolygonPoint polygon_point, const Polygon &polygon)
 Calculate angle for polygon point.
std::vector< double > calculate_angles (int32_t distance, const PolygonPoints &polygon_points, const Polygon &polygon)

Variables

static const float UNION_DELTA = 50.0f
static const unsigned UNION_MAX_ITERATIN = 10
const unsigned ENTER_UNICODE = static_cast<unsigned>('\n')

Detailed Description

class with only static function add ability to engraved OR raised text OR polygons onto model surface


Class Documentation

◆ Slic3r::Emboss::Glyph

struct Slic3r::Emboss::Glyph
Collaboration diagram for Slic3r::Emboss::Glyph:
Class Members
int advance_width =0
int left_side_bearing =0
ExPolygons shape

◆ Slic3r::Emboss::TextLine

struct Slic3r::Emboss::TextLine

Define polygon for draw letters.

Collaboration diagram for Slic3r::Emboss::TextLine:
Class Members
Polygon polygon
PolygonPoint start
float y

Typedef Documentation

◆ Glyphs

using Slic3r::Emboss::Glyphs = std::map<int, Glyph>

◆ TextLines

using Slic3r::Emboss::TextLines = std::vector<TextLine>

Function Documentation

◆ apply_transformation()

void Slic3r::Emboss::apply_transformation ( const std::optional< float > & angle,
const std::optional< float > & distance,
Transform3d & transformation )

Use data from font property to modify transformation.

Parameters
angleZ-rotation as angle to Y axis
distanceZ-move as surface distance
transformationIn / Out transformation to modify by property
1480 {
1481 if (angle.has_value()) {
1482 double angle_z = *angle;
1483 transformation *= Eigen::AngleAxisd(angle_z, Vec3d::UnitZ());
1484 }
1485 if (distance.has_value()) {
1486 Vec3d translate = Vec3d::UnitZ() * (*distance);
1487 transformation.translate(translate);
1488 }
1489}
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
void translate(ExPolygonsWithIds &e, const Point &p)
Definition Emboss.cpp:1368
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138

References Slic3r::angle(), and Slic3r::translate().

Referenced by anonymous_namespace{SurfaceDrag.cpp}::get_volume_transformation(), anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::process(), and anonymous_namespace{EmbossJob.cpp}::start_create_volume_on_surface_job().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calc_up()

std::optional< float > Slic3r::Emboss::calc_up ( const Transform3d & tr,
double up_limit = 0.9 )

By transformation calculate angle between suggested and actual up vector.

Parameters
trTransformation of embossed volume in world
up_limitIs compared with normal.z to suggest up direction
Returns
Rotation of suggested up-vector[in rad] in the range [-Pi, Pi], When rotation is not zero
1769{
1770 auto tr_linear = tr.linear().eval();
1771 // z base of transformation ( tr * UnitZ )
1772 Vec3d normal = tr_linear.col(2);
1773 // scaled matrix has base with different size
1774 normal.normalize();
1775 Vec3d suggested = suggest_up(normal, up_limit);
1776 assert(is_approx(suggested.squaredNorm(), 1.));
1777
1778 Vec3d up = tr_linear.col(1); // tr * UnitY()
1779 up.normalize();
1780 Matrix3d m;
1781 m.row(0) = up;
1782 m.row(1) = suggested;
1783 m.row(2) = normal;
1784 double det = m.determinant();
1785 double dot = suggested.dot(up);
1786 double res = -atan2(det, dot);
1787 if (is_approx(res, 0.))
1788 return {};
1789 return res;
1790}
Vec3d suggest_up(const Vec3d normal, double up_limit=0.9)
Suggest wanted up vector of embossed text by emboss direction.
Definition Emboss.cpp:1749
constexpr bool is_approx(Number value, Number test_value, Number precision=EPSILON)
Definition libslic3r.h:320
Point normal(Point pt, double scale)
Definition TreeSupport.cpp:112
T dot(const boost::geometry::model::d2::point_xy< T > &v1, const boost::geometry::model::d2::point_xy< T > &v2)
Definition ExtrusionSimulator.cpp:154
Eigen::Matrix< double, 3, 3, Eigen::DontAlign > Matrix3d
Definition Point.hpp:86

References Slic3r::dot(), Slic3r::is_approx(), Slic3r::normal(), and suggest_up().

Referenced by Slic3r::GUI::calc_angle(), Slic3r::GUI::face_selected_volume_to_camera(), and anonymous_namespace{SurfaceDrag.cpp}::start_dragging().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ calculate_angle()

double Slic3r::Emboss::calculate_angle ( int32_t distance,
PolygonPoint polygon_point,
const Polygon & polygon )

Calculate angle for polygon point.

Parameters
distanceDistance for found normal in point
polygon_pointSelect point on polygon
polygonPolygon know neighbor of point
Returns
angle(atan2) of normal in polygon point
1964{
1965 PolygonPoint polygon_point2 = polygon_point; // copy
1966 point_in_distance(distance, polygon_point, polygon);
1967 point_in_reverse_distance(distance, polygon_point2, polygon);
1968
1969 Point surface_dir = polygon_point2.point - polygon_point.point;
1970 Point norm(-surface_dir.y(), surface_dir.x());
1971 Vec2d norm_d = norm.cast<double>();
1972 //norm_d.normalize();
1973 return std::atan2(norm_d.y(), norm_d.x());
1974}
Definition Point.hpp:199
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67
Point point
Definition Polygon.hpp:308
Define point laying on polygon keep index of polygon line and point coordinate.
Definition Polygon.hpp:302

References Slic3r::PolygonPoint::point.

Referenced by calculate_angles().

Here is the caller graph for this function:

◆ calculate_angles()

std::vector< double > Slic3r::Emboss::calculate_angles ( int32_t distance,
const PolygonPoints & polygon_points,
const Polygon & polygon )
1977{
1978 std::vector<double> result;
1979 result.reserve(polygon_points.size());
1980 for(const PolygonPoint& pp: polygon_points)
1981 result.emplace_back(calculate_angle(distance, pp, polygon));
1982 return result;
1983}
double calculate_angle(int32_t distance, PolygonPoint polygon_point, const Polygon &polygon)
Calculate angle for polygon point.
Definition Emboss.cpp:1963

References calculate_angle().

Referenced by anonymous_namespace{EmbossJob.cpp}::create_mesh_per_glyph(), and anonymous_namespace{EmbossJob.cpp}::cut_per_glyph_surface().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_font_file() [1/2]

std::unique_ptr< FontFile > Slic3r::Emboss::create_font_file ( const char * file_path)

Load font file into buffer.

Parameters
file_pathLocation of .ttf or .ttc font file
Returns
Font object when loaded.
1165{
1166 FILE *file = std::fopen(file_path, "rb");
1167 if (file == nullptr) {
1168 assert(false);
1169 BOOST_LOG_TRIVIAL(error) << "Couldn't open " << file_path << " for reading.";
1170 return nullptr;
1171 }
1172 ScopeGuard sg([&file]() { std::fclose(file); });
1173
1174 // find size of file
1175 if (fseek(file, 0L, SEEK_END) != 0) {
1176 assert(false);
1177 BOOST_LOG_TRIVIAL(error) << "Couldn't fseek file " << file_path << " for size measure.";
1178 return nullptr;
1179 }
1180 size_t size = ftell(file);
1181 if (size == 0) {
1182 assert(false);
1183 BOOST_LOG_TRIVIAL(error) << "Size of font file is zero. Can't read.";
1184 return nullptr;
1185 }
1186 rewind(file);
1187 auto buffer = std::make_unique<std::vector<unsigned char>>(size);
1188 size_t count_loaded_bytes = fread((void *) &buffer->front(), 1, size, file);
1189 if (count_loaded_bytes != size) {
1190 assert(false);
1191 BOOST_LOG_TRIVIAL(error) << "Different loaded(from file) data size.";
1192 return nullptr;
1193 }
1194 return create_font_file(std::move(buffer));
1195}
#define L(s)
Definition ExtrusionEntity.cpp:25
Definition Utils.hpp:533
std::unique_ptr< FontFile > create_font_file(const char *file_path)
Load font file into buffer.
Definition Emboss.cpp:1164

References create_font_file(), and L.

Referenced by create_font_file(), Slic3r::GUI::WxFontUtils::create_font_file(), Slic3r::GUI::Emboss::StyleManager::load_style(), and Slic3r::text_to_regions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_font_file() [2/2]

std::unique_ptr< FontFile > Slic3r::Emboss::create_font_file ( std::unique_ptr< std::vector< unsigned char > > data)
1134{
1135 int collection_size = stbtt_GetNumberOfFonts(data->data());
1136 // at least one font must be inside collection
1137 if (collection_size < 1) {
1138 assert(false);
1139 // There is no font collection inside font data
1140 return nullptr;
1141 }
1142
1143 unsigned int c_size = static_cast<unsigned int>(collection_size);
1144 std::vector<FontFile::Info> infos;
1145 infos.reserve(c_size);
1146 for (unsigned int i = 0; i < c_size; ++i) {
1147 auto font_info = load_font_info(data->data(), i);
1148 if (!font_info.has_value()) return nullptr;
1149
1150 const stbtt_fontinfo *info = &(*font_info);
1151 // load information about line gap
1152 int ascent, descent, linegap;
1153 stbtt_GetFontVMetrics(info, &ascent, &descent, &linegap);
1154
1155 float pixels = 1000.; // value is irelevant
1156 float em_pixels = stbtt_ScaleForMappingEmToPixels(info, pixels);
1157 int units_per_em = static_cast<int>(std::round(pixels / em_pixels));
1158
1159 infos.emplace_back(FontFile::Info{ascent, descent, linegap, units_per_em});
1160 }
1161 return std::make_unique<FontFile>(std::move(data), std::move(infos));
1162}
Definition Emboss.hpp:79

References anonymous_namespace{Emboss.cpp}::load_font_info().

Here is the call graph for this function:

◆ create_range_text()

std::string Slic3r::Emboss::create_range_text ( const std::string & text,
const FontFile & font,
unsigned int font_index,
bool * exist_unknown = nullptr )

Create unique character set from string with filtered from text with only character from font.

Parameters
textSource vector of glyphs
fontFont descriptor
font_indexDefine font in collection
exist_unknownTrue when text contain glyph unknown in font
Returns
Unique set of character from text contained in font
1533{
1534 if (!is_valid(font, font_index)) return {};
1535
1536 std::wstring ws = boost::nowide::widen(text);
1537
1538 // need remove symbols not contained in font
1539 std::sort(ws.begin(), ws.end());
1540
1541 auto font_info_opt = load_font_info(font.data->data(), 0);
1542 if (!font_info_opt.has_value()) return {};
1543 const stbtt_fontinfo *font_info = &(*font_info_opt);
1544
1545 if (exist_unknown != nullptr) *exist_unknown = false;
1546 int prev_unicode = -1;
1547 ws.erase(std::remove_if(ws.begin(), ws.end(),
1548 [&prev_unicode, font_info, exist_unknown](wchar_t wc) -> bool {
1549 int unicode = static_cast<int>(wc);
1550
1551 // skip white spaces
1552 if (unicode == '\n' ||
1553 unicode == '\r' ||
1554 unicode == '\t') return true;
1555
1556 // is duplicit?
1557 if (prev_unicode == unicode) return true;
1558 prev_unicode = unicode;
1559
1560 // can find in font?
1561 bool is_unknown = !stbtt_FindGlyphIndex(font_info, unicode);
1562 if (is_unknown && exist_unknown != nullptr)
1563 *exist_unknown = true;
1564 return is_unknown;
1565 }), ws.end());
1566
1567 return boost::nowide::narrow(ws);
1568}
std::unique_ptr< std::vector< unsigned char > > data
Definition Emboss.hpp:76

References Slic3r::Emboss::FontFile::data, anonymous_namespace{Emboss.cpp}::is_valid(), and anonymous_namespace{Emboss.cpp}::load_font_info().

Referenced by anonymous_namespace{GLGizmoEmboss.cpp}::can_write(), and Slic3r::GUI::GLGizmoEmboss::draw_text_input().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_transformation_onto_surface()

Transform3d Slic3r::Emboss::create_transformation_onto_surface ( const Vec3d & position,
const Vec3d & normal,
double up_limit = 0.9 )

Create transformation for emboss text object to lay on surface point.

Parameters
positionPosition of surface point
normalNormal of surface point
up_limitIs compared with normal.z to suggest up direction
Returns
Transformation onto surface point
1795{
1796 // is normalized ?
1797 assert(is_approx(normal.squaredNorm(), 1.));
1798
1799 // up and emboss direction for generated model
1800 Vec3d up_dir = Vec3d::UnitY();
1801 Vec3d emboss_dir = Vec3d::UnitZ();
1802
1803 // after cast from float it needs to be normalized again
1804 Vec3d wanted_up_dir = suggest_up(normal, up_limit);
1805
1806 // perpendicular to emboss vector of text and normal
1807 Vec3d axis_view;
1808 double angle_view;
1809 if (normal == -Vec3d::UnitZ()) {
1810 // text_emboss_dir has opposit direction to wanted_emboss_dir
1811 axis_view = Vec3d::UnitY();
1812 angle_view = M_PI;
1813 } else {
1814 axis_view = emboss_dir.cross(normal);
1815 angle_view = std::acos(emboss_dir.dot(normal)); // in rad
1816 axis_view.normalize();
1817 }
1818
1819 Eigen::AngleAxis view_rot(angle_view, axis_view);
1820 Vec3d wanterd_up_rotated = view_rot.matrix().inverse() * wanted_up_dir;
1821 wanterd_up_rotated.normalize();
1822 double angle_up = std::acos(up_dir.dot(wanterd_up_rotated));
1823
1824 Vec3d text_view = up_dir.cross(wanterd_up_rotated);
1825 Vec3d diff_view = emboss_dir - text_view;
1826 if (std::fabs(diff_view.x()) > 1. ||
1827 std::fabs(diff_view.y()) > 1. ||
1828 std::fabs(diff_view.z()) > 1.) // oposit direction
1829 angle_up *= -1.;
1830
1831 Eigen::AngleAxis up_rot(angle_up, emboss_dir);
1832
1833 Transform3d transform = Transform3d::Identity();
1834 transform.translate(position);
1835 transform.rotate(view_rot);
1836 transform.rotate(up_rot);
1837 return transform;
1838}
#define M_PI
Definition ExtrusionSimulator.cpp:31
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
Linef3 transform(const Linef3 &line, const Transform3d &t)
Definition Line.cpp:15

References Slic3r::is_approx(), M_PI, Slic3r::normal(), suggest_up(), and Slic3r::transform().

Referenced by anonymous_namespace{EmbossJob.cpp}::start_create_volume_on_surface_job().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ divide_segments_for_close_point()

bool Slic3r::Emboss::divide_segments_for_close_point ( ExPolygons & expolygons,
double distance )

Divide line segments in place near to point (which could lead to self intersection due to preccision) Remove same neighbors Note: Possible part of heal shape.

Parameters
expolygonsExpolygon to edit
distance(epsilon)Euclidean distance from point to line which divide line
Returns
True when some division was made otherwise false
328{
329 if (expolygons.empty()) return false;
330 if (distance < 0.) return false;
331
332 // ExPolygons can't contain same neigbours
333 remove_same_neighbor(expolygons);
334
335 // IMPROVE: use int(insted of double) lines and tree
336 const ExPolygonsIndices ids(expolygons);
337 const std::vector<Linef> lines = Slic3r::to_linesf(expolygons, ids.get_count());
339 using Div = std::pair<Point, size_t>;
340 std::vector<Div> divs;
341 size_t point_index = 0;
342 auto check_points = [&divs, &point_index, &lines, &tree, &distance, &ids, &expolygons](const Points &pts) {
343 for (const Point &p : pts) {
344 Vec2d p_d = p.cast<double>();
345 std::vector<size_t> close_lines = AABBTreeLines::all_lines_in_radius(lines, tree, p_d, distance);
346 for (size_t index : close_lines) {
347 // skip point neighbour lines indices
348 if (index == point_index) continue;
349 if (&p != &pts.front()) {
350 if (index == point_index - 1) continue;
351 } else if (index == (pts.size()-1)) continue;
352
353 // do not doubled side point of segment
354 const ExPolygonsIndex id = ids.cvt(index);
355 const ExPolygon &expoly = expolygons[id.expolygons_index];
356 const Polygon &poly = id.is_contour() ? expoly.contour : expoly.holes[id.hole_index()];
357 const Points &poly_pts = poly.points;
358 const Point &line_a = poly_pts[id.point_index];
359 const Point &line_b = (!ids.is_last_point(id)) ? poly_pts[id.point_index + 1] : poly_pts.front();
360 assert(line_a == lines[index].a.cast<coord_t>());
361 assert(line_b == lines[index].b.cast<coord_t>());
362 if (p == line_a || p == line_b) continue;
363
364 divs.emplace_back(p, index);
365 }
366 ++point_index;
367 }
368 };
369 for (const ExPolygon &expoly : expolygons) {
370 check_points(expoly.contour.points);
371 for (const Polygon &hole : expoly.holes)
372 check_points(hole.points);
373 }
374
375 // check if exist division
376 if (divs.empty()) return false;
377
378 // sort from biggest index to zero
379 // to be able add points and not interupt indices
380 std::sort(divs.begin(), divs.end(),
381 [](const Div &d1, const Div &d2) { return d1.second > d2.second; });
382
383 auto it = divs.begin();
384 // divide close line
385 while (it != divs.end()) {
386 // colect division of a line segmen
387 size_t index = it->second;
388 auto it2 = it+1;
389 while (it2 != divs.end() && it2->second == index) ++it2;
390
391 ExPolygonsIndex id = ids.cvt(index);
392 ExPolygon &expoly = expolygons[id.expolygons_index];
393 Polygon &poly = id.is_contour() ? expoly.contour : expoly.holes[id.hole_index()];
394 Points &pts = poly.points;
395 size_t count = it2 - it;
396
397 // add points into polygon to divide in place of near point
398 if (count == 1) {
399 pts.insert(pts.begin() + id.point_index + 1, it->first);
400 ++it;
401 } else {
402 // collect points to add into polygon
403 Points points;
404 points.reserve(count);
405 for (; it < it2; ++it)
406 points.push_back(it->first);
407
408 // need sort by line direction
409 const Linef &line = lines[index];
410 Vec2d dir = line.b - line.a;
411 // select mayorit direction
412 int axis = (abs(dir.x()) > abs(dir.y())) ? 0 : 1;
413 using Fnc = std::function<bool(const Point &, const Point &)>;
414 Fnc fnc = (dir[axis] < 0) ? Fnc([axis](const Point &p1, const Point &p2) { return p1[axis] > p2[axis]; }) :
415 Fnc([axis](const Point &p1, const Point &p2) { return p1[axis] < p2[axis]; }) ;
416 std::sort(points.begin(), points.end(), fnc);
417
418 // use only unique points
419 points.erase(std::unique(points.begin(), points.end()), points.end());
420
421 // divide line by adding points into polygon
422 pts.insert(pts.begin() + id.point_index + 1,
423 points.begin(), points.end());
424 }
425 assert(it == it2);
426 }
427 return true;
428}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246
Definition AABBTreeIndirect.hpp:45
Definition ExPolygon.hpp:23
Polygon contour
Definition ExPolygon.hpp:42
Polygons holes
Definition ExPolygon.hpp:43
Keep conversion from ExPolygonsIndex to Index and vice versa ExPolygonsIndex .. contour(or hole) poin...
Definition ExPolygonsIndex.hpp:40
Vec2d b
Definition Line.hpp:265
Vec2d a
Definition Line.hpp:264
Points points
Definition MultiPoint.hpp:22
Definition Polygon.hpp:31
int64_t coord_t
Definition libslic3r.h:48
std::vector< size_t > all_lines_in_radius(const std::vector< LineType > &lines, const TreeType &tree, const VectorType &point, typename VectorType::Scalar max_distance_squared)
Definition AABBTreeLines.hpp:229
AABBTreeIndirect::Tree< LineType::Dim, typename LineType::Scalar > build_aabb_tree_over_indexed_lines(const std::vector< LineType > &lines)
Definition AABBTreeLines.hpp:172
void poly(std::vector< std::pair< Vec2d, Vec2d > > &out, std::initializer_list< Vec2d > p)
Definition DesignSketchTool.cpp:7751
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
bool remove_same_neighbor(ExPolygons &expolygons)
Definition ExPolygon.cpp:496
Linesf to_linesf(const ExPolygons &src, uint32_t count_lines=0)
Definition ExPolygon.hpp:154
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:73
Slic3r::Polygon Polygon
Definition Emboss.cpp:101
Index into ExPolygons Identify expolygon, its contour (or hole) and point.
Definition ExPolygonsIndex.hpp:14

References Slic3r::Linef::a, Slic3r::AABBTreeLines::all_lines_in_radius(), Slic3r::Linef::b, Slic3r::AABBTreeLines::build_aabb_tree_over_indexed_lines(), Slic3r::ExPolygon::contour, count, Slic3r::ExPolygonsIndices::cvt(), Slic3r::ExPolygonsIndices::get_count(), Slic3r::ExPolygon::holes, Slic3r::ExPolygonsIndices::is_last_point(), Slic3r::MultiPoint::points, Slic3r::remove_same_neighbor(), and Slic3r::to_linesf().

Here is the call graph for this function:

◆ get_align_y_offset_in_mm()

double Slic3r::Emboss::get_align_y_offset_in_mm ( FontProp::VerticalAlign align,
unsigned count_lines,
const FontFile & ff,
const FontProp & fp )

Calculate Vertical align.

Parameters
alignTop | Center | Bottom
count_lines
Returns
Return align Y offset in mm
2115 {
2116 float offset_in_font_point = get_align_y_offset(align, count_lines, ff, fp);
2117 double scale = get_text_shape_scale(fp, ff);
2118 return scale * offset_in_font_point;
2119}
int scale(const int val)
Definition WipeTowerDialog.cpp:58
double get_text_shape_scale(const FontProp &fp, const FontFile &ff)
Calculate scale for glyph shape convert from shape points to mm.
Definition Emboss.cpp:1570

References get_text_shape_scale(), and scale().

Referenced by Slic3r::GUI::TextLinesModel::init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_count_lines() [1/3]

unsigned Slic3r::Emboss::get_count_lines ( const ExPolygonsWithIds & shape)
1470 {
1471 if (shapes.empty())
1472 return 0; // no glyphs
1473 unsigned result = 1; // one line is minimum
1474 for (const ExPolygonsWithId &shape_id : shapes)
1475 if (shape_id.id == ENTER_UNICODE)
1476 ++result;
1477 return result;
1478}
const unsigned ENTER_UNICODE
Definition Emboss.hpp:166
Definition EmbossShape.hpp:47

References ENTER_UNICODE.

◆ get_count_lines() [2/3]

unsigned Slic3r::Emboss::get_count_lines ( const std::string & text)
1465{
1466 std::wstring ws = boost::nowide::widen(text.c_str());
1467 return get_count_lines(ws);
1468}
unsigned get_count_lines(const std::wstring &ws)
Sum of character ' '.
Definition Emboss.cpp:1437

References get_count_lines().

Here is the call graph for this function:

◆ get_count_lines() [3/3]

unsigned Slic3r::Emboss::get_count_lines ( const std::wstring & ws)

Sum of character '
'.

1438{
1439 if (ws.empty())
1440 return 0;
1441
1442 unsigned count = 1;
1443 for (wchar_t wc : ws)
1444 if (wc == '\n')
1445 ++count;
1446 return count;
1447
1448 // unsigned prev_count = 0;
1449 // for (wchar_t wc : ws)
1450 // if (wc == '\n')
1451 // ++prev_count;
1452 // else
1453 // break;
1454 //
1455 // unsigned post_count = 0;
1456 // for (wchar_t wc : boost::adaptors::reverse(ws))
1457 // if (wc == '\n')
1458 // ++post_count;
1459 // else
1460 // break;
1461 //return count - prev_count - post_count;
1462}

References count.

Referenced by anonymous_namespace{Emboss.cpp}::align_shape(), anonymous_namespace{EmbossJob.cpp}::create_line_bounds(), anonymous_namespace{EmbossJob.cpp}::create_mesh_per_glyph(), anonymous_namespace{EmbossJob.cpp}::cut_per_glyph_surface(), Slic3r::GUI::GLGizmoEmboss::draw_advanced(), Slic3r::GUI::GLGizmoEmboss::draw_text_input(), get_count_lines(), anonymous_namespace{GLGizmoEmboss.cpp}::init_text_lines(), and Slic3r::GUI::GLGizmoEmboss::process().

Here is the caller graph for this function:

◆ get_font_info()

const FontFile::Info & Slic3r::Emboss::get_font_info ( const FontFile & font,
const FontProp & prop )

getter of font info by collection defined in prop

Parameters
fontContain infos about all fonts(collections) in file
propIndex of collection
Returns
Ascent, descent, line gap
1274{
1275 unsigned int font_index = prop.collection_number.value_or(0);
1276 assert(is_valid(font, font_index));
1277 return font.infos[font_index];
1278}
std::vector< Info > infos
Definition Emboss.hpp:87
std::optional< unsigned int > collection_number
Definition TextConfiguration.hpp:43

References Slic3r::FontProp::collection_number, Slic3r::Emboss::FontFile::infos, and anonymous_namespace{Emboss.cpp}::is_valid().

Referenced by Slic3r::GUI::Emboss::StyleManager::create_imgui_font(), Slic3r::GUI::GLGizmoEmboss::draw_advanced(), anonymous_namespace{Emboss.cpp}::get_align_y_offset(), Slic3r::GUI::Emboss::StyleManager::get_imgui_font_size(), get_line_height(), and get_text_shape_scale().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_font_list()

EmbossStyles Slic3r::Emboss::get_font_list ( )

Collect fonts registred inside OS.

Returns
OS registred TTF font files(full path) with names
1121 {
1122 // not implemented
1123 return {};
1124}

◆ get_font_path()

std::optional< std::wstring > Slic3r::Emboss::get_font_path ( const std::wstring & font_face_name)

OS dependent function to get location of font by its name descriptor.

Parameters
font_face_nameUnique identificator for font
Returns
File path to font when found
1126 {
1127 // not implemented
1128 return {};
1129}

◆ get_line_height()

int Slic3r::Emboss::get_line_height ( const FontFile & font,
const FontProp & prop )

Read from font file and properties height of line with spacing.

Parameters
fontInfos for collections
propCollection index + Additional line gap
Returns
Line height with spacing in scaled font points (same as ExPolygons)
1280 {
1281 const FontFile::Info &info = get_font_info(font, prop);
1282 int line_height = info.ascent - info.descent + info.linegap;
1283 line_height += prop.line_gap.value_or(0);
1284 return static_cast<int>(line_height / SHAPE_SCALE);
1285}
static constexpr double SHAPE_SCALE
Definition Emboss.cpp:53
const FontFile::Info & get_font_info(const FontFile &font, const FontProp &prop)
getter of font info by collection defined in prop
Definition Emboss.cpp:1273
int linegap
Definition Emboss.hpp:81
int ascent
Definition Emboss.hpp:81
int descent
Definition Emboss.hpp:81
std::optional< int > line_gap
Definition TextConfiguration.hpp:29

References Slic3r::Emboss::FontFile::Info::ascent, Slic3r::Emboss::FontFile::Info::descent, get_font_info(), Slic3r::FontProp::line_gap, Slic3r::Emboss::FontFile::Info::linegap, and SHAPE_SCALE.

Referenced by Slic3r::GUI::TextLinesModel::calc_line_height_in_mm(), anonymous_namespace{Emboss.cpp}::get_align_y_offset(), and anonymous_namespace{Emboss.cpp}::letter2shapes().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_text_shape_scale()

double Slic3r::Emboss::get_text_shape_scale ( const FontProp & fp,
const FontFile & ff )

Calculate scale for glyph shape convert from shape points to mm.

Parameters
fpProperty of font
ffFont data
Returns
Conversion to mm
1571{
1572 const FontFile::Info &info = get_font_info(ff, fp);
1573 double scale = fp.size_in_mm / (double) info.unit_per_em;
1574 // Shape is scaled for store point coordinate as integer
1575 return scale * SHAPE_SCALE;
1576}
int unit_per_em
Definition Emboss.hpp:84
float size_in_mm
Definition TextConfiguration.hpp:63

References get_font_info(), scale(), SHAPE_SCALE, Slic3r::FontProp::size_in_mm, and Slic3r::Emboss::FontFile::Info::unit_per_em.

Referenced by anonymous_namespace{GLGizmoEmboss.cpp}::TextDataBase::TextDataBase(), Slic3r::GUI::TextLinesModel::calc_line_height_in_mm(), get_align_y_offset_in_mm(), and Slic3r::text_to_regions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ heal_expolygons()

bool Slic3r::Emboss::heal_expolygons ( ExPolygons & shape,
unsigned max_iteration = 10 )

NOTE: call Slic3r::union_ex before this call.

Heal (read: Fix) issues in expolygons:

  • self intersections
  • duplicit points
  • points close to line segments
Parameters
shapeIn/Out shape to heal
max_iterationHeal could create another issue, After healing it is checked again until shape is good or maximal count of iteration
Returns
True when shapes is good otherwise False
537{
538 return ::heal_dupl_inter(shape, max_iteration);
539}

Referenced by anonymous_namespace{Emboss.cpp}::union_with_delta().

Here is the caller graph for this function:

◆ heal_polygons()

HealedExPolygons Slic3r::Emboss::heal_polygons ( const Polygons & shape,
bool is_non_zero = true,
unsigned max_iteration = 10 )

Fix duplicit points and self intersections in polygons. Also try to reduce amount of points and remove useless polygon parts.

Parameters
is_non_zeroFill type pftNonZero for overlapping otherwise
max_iterationLook at heal_expolygon()::max_iteration
Returns
Healed shapes with flag is fully healed

References Slic3r::angle().

Referenced by anonymous_namespace{NSVGUtils.cpp}::fill_to_expolygons(), anonymous_namespace{Emboss.cpp}::get_glyph(), and anonymous_namespace{NSVGUtils.cpp}::stroke_to_expolygons().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_italic()

bool Slic3r::Emboss::is_italic ( const FontFile & font,
unsigned int font_index )

Read information from naming table of font file search for italic (or oblique), bold italic (or bold oblique).

Parameters
fontSelector of font
font_indexIndex of font in collection
Returns
True when the font description contains italic/obligue otherwise False
1492{
1493 if (font_index >= font.infos.size()) return false;
1494 fontinfo_opt font_info_opt = load_font_info(font.data->data(), font_index);
1495
1496 if (!font_info_opt.has_value()) return false;
1497 stbtt_fontinfo *info = &(*font_info_opt);
1498
1499 // https://docs.microsoft.com/cs-cz/typography/opentype/spec/name
1500 // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
1501 // 2 ==> Style / Subfamily name
1502 int name_id = 2;
1503 int length;
1504 const char* value = stbtt_GetFontNameString(info, &length,
1505 STBTT_PLATFORM_ID_MICROSOFT,
1506 STBTT_MS_EID_UNICODE_BMP,
1507 STBTT_MS_LANG_ENGLISH,
1508 name_id);
1509
1510 // value is big endian utf-16 i need extract only normal chars
1511 std::string value_str;
1512 value_str.reserve(length / 2);
1513 for (int i = 1; i < length; i += 2)
1514 value_str.push_back(value[i]);
1515
1516 // lower case
1517 std::transform(value_str.begin(), value_str.end(), value_str.begin(),
1518 [](unsigned char c) { return std::tolower(c); });
1519
1520 const std::vector<std::string> italics({"italic", "oblique"});
1521 for (const std::string &it : italics) {
1522 if (value_str.find(it) != std::string::npos) {
1523 return true;
1524 }
1525 }
1526 return false;
1527}
std::optional< stbtt_fontinfo > fontinfo_opt
Definition Emboss.cpp:58
double length(const Points &pts)
Definition MultiPoint.hpp:181

References Slic3r::Emboss::FontFile::data, Slic3r::Emboss::FontFile::infos, Slic3r::length(), and anonymous_namespace{Emboss.cpp}::load_font_info().

Referenced by Slic3r::GUI::Emboss::StyleManager::is_font_changed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ letter2glyph()

std::optional< Glyph > Slic3r::Emboss::letter2glyph ( const FontFile & font,
unsigned int font_index,
int letter,
float flatness )

convert letter into polygons

Parameters
fontDefine fonts
font_indexIndex of font in collection
letterOne character defined by unicode codepoint
flatnessPrecision of lettter outline curve in conversion to lines
Returns
inner polygon cw(outer ccw)
1266{
1267 if (!is_valid(font, font_index)) return {};
1268 auto font_info_opt = load_font_info(font.data->data(), font_index);
1269 if (!font_info_opt.has_value()) return {};
1270 return get_glyph(*font_info_opt, letter, flatness);
1271}

References Slic3r::Emboss::FontFile::data, anonymous_namespace{Emboss.cpp}::get_glyph(), anonymous_namespace{Emboss.cpp}::is_valid(), and anonymous_namespace{Emboss.cpp}::load_font_info().

Here is the call graph for this function:

◆ polygons2model()

indexed_triangle_set Slic3r::Emboss::polygons2model ( const ExPolygons & shape2d,
const IProjection & projection )

Create triangle model for text.

Parameters
shape2dtext or image
projectionDefine transformation from 2d to 3d(orientation, position, scale, ...)
Returns
Projected shape into space
1723{
1724 Points points = to_points(shape2d);
1725 Points duplicits = collect_duplicates(points);
1726 return (duplicits.empty()) ?
1727 polygons2model_unique(shape2d, projection, points) :
1728 polygons2model_duplicit(shape2d, projection, points, duplicits);
1729}
Points collect_duplicates(Points pts)
Definition Point.cpp:147
Points to_points(const ExPolygons &src)
Definition ExPolygon.hpp:222

References Slic3r::collect_duplicates(), anonymous_namespace{Emboss.cpp}::polygons2model_duplicit(), anonymous_namespace{Emboss.cpp}::polygons2model_unique(), and Slic3r::to_points().

Referenced by anonymous_namespace{EmbossJob.cpp}::create_mesh_per_glyph(), and anonymous_namespace{EmbossJob.cpp}::try_create_mesh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sample_slice()

PolygonPoints Slic3r::Emboss::sample_slice ( const TextLine & slice,
const BoundingBoxes & bbs,
double scale )

Sample slice polygon by bounding boxes centers slice start point has shape_center_x coor.

Parameters
slicePolygon and start point[Slic3r scaled millimeters]
bbsBounding boxes of letter on one line[in font scales]
scaleScale for bbs (after multiply bb is in millimeters)
Returns
Sampled polygon by bounding boxes
1986{
1987 // find BB in center of line
1988 size_t first_right_index = 0;
1989 for (const BoundingBox &bb : bbs)
1990 if (!bb.defined) // white char do not have bb
1991 continue;
1992 else if (bb.min.x() < 0)
1993 ++first_right_index;
1994 else
1995 break;
1996
1997 PolygonPoints samples(bbs.size());
1998 int32_t shapes_x_cursor = 0;
1999
2000 PolygonPoint cursor = slice.start; //copy
2001
2002 auto create_sample = [&] //polygon_cursor, &polygon_line_index, &line_bbs, &shapes_x_cursor, &shape_scale, &em_2_polygon, &line, &offsets]
2003 (const BoundingBox &bb, bool is_reverse) {
2004 if (!bb.defined)
2005 return cursor;
2006 Point letter_center = bb.center();
2007 int32_t shape_distance = shapes_x_cursor - letter_center.x();
2008 shapes_x_cursor = letter_center.x();
2009 double distance_mm = shape_distance * scale;
2010 int32_t distance_polygon = static_cast<int32_t>(std::round(scale_(distance_mm)));
2011 if (is_reverse)
2012 point_in_distance(distance_polygon, cursor, slice.polygon);
2013 else
2014 point_in_reverse_distance(distance_polygon, cursor, slice.polygon);
2015 return cursor;
2016 };
2017
2018 // calc transformation for letters on the Right side from center
2019 bool is_reverse = true;
2020 for (size_t index = first_right_index; index < bbs.size(); ++index)
2021 samples[index] = create_sample(bbs[index], is_reverse);
2022
2023 // calc transformation for letters on the Left side from center
2024 if (first_right_index < bbs.size()) {
2025 shapes_x_cursor = bbs[first_right_index].center().x();
2026 cursor = samples[first_right_index];
2027 }else{
2028 // only left side exists
2029 shapes_x_cursor = 0;
2030 cursor = slice.start; // copy
2031 }
2032 is_reverse = false;
2033 for (size_t index_plus_one = first_right_index; index_plus_one > 0; --index_plus_one) {
2034 size_t index = index_plus_one - 1;
2035 samples[index] = create_sample(bbs[index], is_reverse);
2036 }
2037 return samples;
2038}
bool defined
Definition BoundingBox.hpp:22
PointType center() const
Definition BoundingBox.cpp:228
Definition BoundingBox.hpp:212
#define scale_(val)
Definition libslic3r.h:106
PolygonPoint start
Definition Emboss.hpp:443
Polygon polygon
Definition Emboss.hpp:440
std::vector< PolygonPoint > PolygonPoints
Definition Polygon.hpp:310

References Slic3r::BoundingBoxBase< PointType, APointsType >::center(), Slic3r::BoundingBoxBase< PointType, APointsType >::defined, Slic3r::Emboss::TextLine::polygon, scale(), scale_, and Slic3r::Emboss::TextLine::start.

Referenced by anonymous_namespace{EmbossJob.cpp}::create_mesh_per_glyph(), and anonymous_namespace{EmbossJob.cpp}::cut_per_glyph_surface().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ suggest_up()

Vec3d Slic3r::Emboss::suggest_up ( const Vec3d normal,
double up_limit = 0.9 )

Suggest wanted up vector of embossed text by emboss direction.

Parameters
normalNormalized vector of emboss direction in world
up_limitIs compared with normal.z to suggest up direction
Returns
Wanted up vector
1750{
1751 // Normal must be 1
1752 assert(is_approx(normal.squaredNorm(), 1.));
1753
1754 // wanted up direction of result
1755 Vec3d wanted_up_side =
1756 (std::fabs(normal.z()) > up_limit)?
1757 Vec3d::UnitY() : Vec3d::UnitZ();
1758
1759 // create perpendicular unit vector to surface triangle normal vector
1760 // lay on surface of triangle and define up vector for text
1761 Vec3d wanted_up_dir = normal.cross(wanted_up_side).cross(normal);
1762 // normal3d is NOT perpendicular to normal_up_dir
1763 wanted_up_dir.normalize();
1764
1765 return wanted_up_dir;
1766}

References Slic3r::is_approx(), and Slic3r::normal().

Referenced by calc_up(), create_transformation_onto_surface(), and anonymous_namespace{SurfaceDrag.cpp}::get_volume_transformation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ text2shapes()

HealedExPolygons Slic3r::Emboss::text2shapes ( FontFileWithCache & font,
const char * text,
const FontProp & font_prop,
const std::function< bool()> & was_canceled = []() {return false;} )

Convert text into polygons.

Parameters
fontDefine fonts + cache, which could extend
textCharacters to convert
font_propUser defined property of the font
was_canceledWay to interupt processing
Returns
Inner polygon cw(outer ccw)
1389{
1390 std::wstring text_w = boost::nowide::widen(text);
1391 ExPolygonsWithIds vshapes = text2vshapes(font_with_cache, text_w, font_prop, was_canceled);
1392
1393 float delta = static_cast<float>(1. / SHAPE_SCALE);
1394 return ::union_with_delta(vshapes, delta, MAX_HEAL_ITERATION_OF_TEXT);
1395}
static unsigned MAX_HEAL_ITERATION_OF_TEXT
Definition Emboss.cpp:54
ExPolygonsWithIds text2vshapes(FontFileWithCache &font, const std::wstring &text, const FontProp &font_prop, const std::function< bool()> &was_canceled=[]() {return false;})
Definition Emboss.cpp:1409
std::vector< ExPolygonsWithId > ExPolygonsWithIds
Definition EmbossShape.hpp:60

References MAX_HEAL_ITERATION_OF_TEXT, SHAPE_SCALE, and text2vshapes().

Referenced by Slic3r::GUI::CreateFontImageJob::process(), and Slic3r::text_to_regions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ text2vshapes()

ExPolygonsWithIds Slic3r::Emboss::text2vshapes ( FontFileWithCache & font,
const std::wstring & text,
const FontProp & font_prop,
const std::function< bool()> & was_canceled = []() {return false;} )
1409 {
1410 assert(font_with_cache.has_value());
1411 const FontFile &font = *font_with_cache.font_file;
1412 unsigned int font_index = font_prop.collection_number.value_or(0);
1413 if (!is_valid(font, font_index))
1414 return {};
1415
1416 unsigned counter = 0;
1417 Point cursor(0, 0);
1418
1419 fontinfo_opt font_info_cache;
1420 ExPolygonsWithIds result;
1421 result.reserve(text.size());
1422 for (wchar_t letter : text) {
1423 if (++counter == CANCEL_CHECK) {
1424 counter = 0;
1425 if (was_canceled())
1426 return {};
1427 }
1428 unsigned id = static_cast<unsigned>(letter);
1429 result.push_back({id, letter2shapes(letter, cursor, font_with_cache, font_prop, font_info_cache)});
1430 }
1431
1432 align_shape(result, text, font_prop, font);
1433 return result;
1434}
ExPolygons letter2shapes(wchar_t letter, Point &cursor, FontFileWithCache &font_with_cache, const FontProp &font_prop, fontinfo_opt &font_info_cache)
Definition Emboss.cpp:1288
void align_shape(ExPolygonsWithIds &shapes, const std::wstring &text, const FontProp &prop, const FontFile &font)
Align shape against pivot.
Definition Emboss.cpp:2070
std::shared_ptr< const FontFile > font_file
Definition Emboss.hpp:116
keep information from file about font (store file data itself)
Definition Emboss.hpp:71

References anonymous_namespace{Emboss.cpp}::align_shape(), anonymous_namespace{Emboss.cpp}::CANCEL_CHECK, Slic3r::FontProp::collection_number, Slic3r::Emboss::FontFileWithCache::font_file, Slic3r::Emboss::FontFileWithCache::has_value(), anonymous_namespace{Emboss.cpp}::is_valid(), and anonymous_namespace{Emboss.cpp}::letter2shapes().

Referenced by anonymous_namespace{GLGizmoEmboss.cpp}::TextDataBase::create_shape(), and text2shapes().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ ENTER_UNICODE

const unsigned Slic3r::Emboss::ENTER_UNICODE = static_cast<unsigned>('\n')

◆ UNION_DELTA

const float Slic3r::Emboss::UNION_DELTA = 50.0f
static

◆ UNION_MAX_ITERATIN

const unsigned Slic3r::Emboss::UNION_MAX_ITERATIN = 10
static