OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
anonymous_namespace{EmbossJob.cpp} Namespace Reference

private namespace implementation More...

Classes

struct  DataCreateVolume
 Hold neccessary data to create ModelVolume in job Volume is created on the surface of existing volume in object. NOTE: EmbossDataBase::font_file doesn't have to be valid !!! More...
class  CreateVolumeJob
 Create new TextVolume on the surface of ModelObject Should not be stopped NOTE: EmbossDataBase::font_file doesn't have to be valid !!! More...
struct  DataCreateObject
 Hold neccessary data to create ModelObject in job Object is placed on bed under screen coor OR to center of scene when it is out of bed shape. More...
class  CreateObjectJob
 Create new TextObject on the platter Should not be stopped. More...
struct  CreateSurfaceVolumeData
 Hold neccessary data to create(cut) volume from surface object in job. More...
class  CreateSurfaceVolumeJob
 Cut surface from object and create cutted volume Should not be stopped. More...
class  JobException

Functions

bool check (const DataBase &input, bool check_fontfile=true, bool use_surface=false)
 Assert check of inputs data.
bool check (GLGizmosManager::EType gizmo)
bool check (const CreateVolumeParams &input)
bool check (const DataCreateVolume &input, bool is_main_thread=false)
bool check (const DataCreateObject &input)
bool check (const DataUpdate &input, bool is_main_thread=false, bool use_surface=false)
bool check (const CreateSurfaceVolumeData &input, bool is_main_thread=false)
bool check (const UpdateSurfaceVolumeData &input, bool is_main_thread=false)
template<typename Fnc>
static ExPolygons create_shape (DataBase &input, Fnc was_canceled)
template<typename Fnc>
TriangleMesh try_create_mesh (DataBase &input, const Fnc &was_canceled)
 Try to create mesh from text.
template<typename Fnc>
TriangleMesh create_mesh (DataBase &input, const Fnc &was_canceled, Job::Ctl &ctl)
TriangleMesh create_default_mesh ()
 Create default mesh for embossed text.
void update_volume (TriangleMesh &&mesh, const DataUpdate &data, const Transform3d *tr=nullptr)
 Must be called on main thread.
void update_name_in_list (const ObjectList &object_list, const ModelVolume &volume)
 Update name in right panel.
void create_volume (TriangleMesh &&mesh, const ObjectID &object_id, const ModelVolumeType type, const std::optional< Transform3d > &trmat, const DataBase &data, GLGizmosManager::EType gizmo)
 Add new volume to object.
OrthoProject create_projection_for_cut (Transform3d tr, double shape_scale, const std::pair< float, float > &z_range)
 Create projection for cut surface from mesh.
OrthoProject3d create_emboss_projection (bool is_outside, float emboss, Transform3d tr, SurfaceCut &cut)
 Create tranformation for emboss Cutted surface.
template<typename Fnc>
TriangleMesh cut_surface (DataBase &input1, const SurfaceVolumeData &input2, const Fnc &was_canceled)
 Cut surface into triangle mesh.
SurfaceVolumeData::ModelSources create_sources (const ModelVolumePtrs &volumes, std::optional< size_t > text_volume_id={})
 Copied triangles from object to be able create mesh for cut surface from.
void create_message (const std::string &message)
bool process (std::exception_ptr &eptr)
bool finalize (bool canceled, std::exception_ptr &eptr, const DataBase &input)
auto was_canceled (const Job::Ctl &ctl, const DataBase &base)
bool is_valid (ModelVolumeType volume_type)
 Check if volume type is possible use for new text volume.
bool start_create_volume_job (Worker &worker, const ModelObject &object, const std::optional< Transform3d > &volume_tr, DataBasePtr data, ModelVolumeType volume_type, GLGizmosManager::EType gizmo)
 Start job for add new volume to object with given transformation.
const GLVolume * find_closest (const Selection &selection, const Vec2d &screen_center, const Camera &camera, const ModelObjectPtrs &objects, Vec2d *closest_center)
 Find volume in selected objects with closest convex hull to screen center.
bool start_create_object_job (const CreateVolumeParams &input, DataBasePtr emboss_data, const Vec2d &coor)
 Start job for add object with text into scene.
bool start_create_volume_on_surface_job (CreateVolumeParams &input, DataBasePtr data, const Vec2d &screen_coor, bool try_no_coor)
 Start job to create volume on the surface of object.
template<typename Fnc>
ExPolygons create_shape (DataBase &input, Fnc was_canceled)
std::vector< BoundingBoxes > create_line_bounds (const ExPolygonsWithIds &shapes, size_t count_lines=0)
template<typename Fnc>
TriangleMesh create_mesh_per_glyph (DataBase &input, Fnc was_canceled)
indexed_triangle_set cut_surface_to_its (const ExPolygons &shapes, const Transform3d &tr, const SurfaceVolumeData::ModelSources &sources, DataBase &input, std::function< bool()> was_canceled)
TriangleMesh cut_per_glyph_surface (DataBase &input1, const SurfaceVolumeData &input2, std::function< bool()> was_canceled)

Variables

constexpr float SAFE_SURFACE_OFFSET = 0.015f
constexpr float safe_extension = 1.0f

Detailed Description

private namespace implementation


Class Documentation

◆ anonymous_namespace{EmbossJob.cpp}::DataCreateVolume

struct anonymous_namespace{EmbossJob.cpp}::DataCreateVolume

Hold neccessary data to create ModelVolume in job Volume is created on the surface of existing volume in object. NOTE: EmbossDataBase::font_file doesn't have to be valid !!!

Collaboration diagram for anonymous_namespace{EmbossJob.cpp}::DataCreateVolume:
Class Members
DataBasePtr base
EType gizmo
ObjectID object_id
optional< Transform3d > trmat
ModelVolumeType volume_type

◆ anonymous_namespace{EmbossJob.cpp}::DataCreateObject

struct anonymous_namespace{EmbossJob.cpp}::DataCreateObject

Hold neccessary data to create ModelObject in job Object is placed on bed under screen coor OR to center of scene when it is out of bed shape.

Collaboration diagram for anonymous_namespace{EmbossJob.cpp}::DataCreateObject:
Class Members
optional< float > angle = {}
DataBasePtr base
vector< Vec2d > bed_shape
Camera camera
EType gizmo
Vec2d screen_coor

Function Documentation

◆ check() [1/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const CreateSurfaceVolumeData & input,
bool is_main_thread = false )
802{
803 bool use_surface = true;
804 assert(input.base != nullptr);
805 bool res = input.base != nullptr;
806 res &= check(*input.base, is_main_thread, use_surface);
807 assert(!input.sources.empty());
808 res &= !input.sources.empty();
809 res &= check(input.gizmo);
810 assert(input.base->shape.projection.use_surface);
811 res &= input.base->shape.projection.use_surface;
812 return res;
813}
EmbossShape shape
Definition EmbossJob.hpp:86
bool check(const DataBase &input, bool check_fontfile=true, bool use_surface=false)
Assert check of inputs data.
Definition EmbossJob.cpp:719
bool use_surface
Definition EmbossShape.hpp:27
EmbossProjection projection
Definition EmbossShape.hpp:80
ModelSources sources
Definition EmbossJob.hpp:172
GLGizmosManager::EType gizmo
Definition EmbossJob.cpp:169
DataBasePtr base
Definition EmbossJob.cpp:160

References anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeData::base, check(), anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeData::gizmo, Slic3r::EmbossShape::projection, Slic3r::GUI::Emboss::DataBase::shape, Slic3r::GUI::Emboss::SurfaceVolumeData::sources, and Slic3r::EmbossProjection::use_surface.

Here is the call graph for this function:

◆ check() [2/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const CreateVolumeParams & input)
749{
750 bool res = is_valid(input.volume_type);
751 auto gizmo_type = static_cast<GLGizmosManager::EType>(input.gizmo);
752 res &= ::check(gizmo_type);
753 return res;
754}
EType
Definition GLGizmosManager.hpp:86
unsigned char gizmo
Definition EmbossJob.hpp:225
ModelVolumeType volume_type
Definition EmbossJob.hpp:219
bool is_valid(ModelVolumeType volume_type)
Check if volume type is possible use for new text volume.
Definition EmbossJob.cpp:1450

References check(), Slic3r::GUI::Emboss::CreateVolumeParams::gizmo, is_valid(), and Slic3r::GUI::Emboss::CreateVolumeParams::volume_type.

Here is the call graph for this function:

◆ check() [3/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const DataBase & input,
bool check_fontfile = true,
bool use_surface = false )

Assert check of inputs data.

720{
721 bool res = true;
722 // if (check_fontfile) {
723 // assert(input.font_file.has_value());
724 // res &= input.font_file.has_value();
725 // }
726 // assert(!input.text_configuration.fix_3mf_tr.has_value());
727 // res &= !input.text_configuration.fix_3mf_tr.has_value();
728 // assert(!input.text_configuration.text.empty());
729 // res &= !input.text_configuration.text.empty();
730 assert(!input.volume_name.empty());
731 res &= !input.volume_name.empty();
732 //const FontProp& prop = input.text_configuration.style.prop;
733 //assert(prop.per_glyph == !input.text_lines.empty());
734 //res &= prop.per_glyph == !input.text_lines.empty();
735 //if (prop.per_glyph) {
736 // assert(get_count_lines(input.text_configuration.text) == input.text_lines.size());
737 // res &= get_count_lines(input.text_configuration.text) == input.text_lines.size();
738 //}
739 return res;
740}
std::string volume_name
Definition EmbossJob.hpp:79

References check(), and Slic3r::GUI::Emboss::DataBase::volume_name.

Referenced by anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::CreateObjectJob(), anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeJob::CreateSurfaceVolumeJob(), anonymous_namespace{EmbossJob.cpp}::CreateVolumeJob::CreateVolumeJob(), check(), check(), check(), check(), check(), check(), check(), check(), anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::process(), anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeJob::process(), and anonymous_namespace{EmbossJob.cpp}::CreateVolumeJob::process().

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

◆ check() [4/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const DataCreateObject & input)
769{
770 bool check_fontfile = false;
771 assert(input.base != nullptr);
772 bool res = input.base != nullptr;
773 res &= check(*input.base, check_fontfile);
774 assert(input.screen_coor.x() >= 0.);
775 res &= input.screen_coor.x() >= 0.;
776 assert(input.screen_coor.y() >= 0.);
777 res &= input.screen_coor.y() >= 0.;
778 assert(input.bed_shape.size() >= 3); // at least triangle
779 res &= input.bed_shape.size() >= 3;
780 res &= check(input.gizmo);
781 assert(!input.base->shape.projection.use_surface);
782 res &= !input.base->shape.projection.use_surface;
783 return res;
784}
DataBasePtr base
Definition EmbossJob.cpp:120
GLGizmosManager::EType gizmo
Definition EmbossJob.cpp:132
std::vector< Vec2d > bed_shape
Definition EmbossJob.cpp:129
Vec2d screen_coor
Definition EmbossJob.cpp:123

References anonymous_namespace{EmbossJob.cpp}::DataCreateObject::base, anonymous_namespace{EmbossJob.cpp}::DataCreateObject::bed_shape, check(), anonymous_namespace{EmbossJob.cpp}::DataCreateObject::gizmo, Slic3r::EmbossShape::projection, anonymous_namespace{EmbossJob.cpp}::DataCreateObject::screen_coor, Slic3r::GUI::Emboss::DataBase::shape, and Slic3r::EmbossProjection::use_surface.

Here is the call graph for this function:

◆ check() [5/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const DataCreateVolume & input,
bool is_main_thread = false )
757{
758 bool check_fontfile = false;
759 assert(input.base != nullptr);
760 bool res = input.base != nullptr;
761 res &= check(*input.base, check_fontfile);
762 res &= is_valid(input.volume_type);
763 res &= check(input.gizmo);
764 assert(!input.base->shape.projection.use_surface);
765 res &= !input.base->shape.projection.use_surface;
766 return res;
767}
ModelVolumeType volume_type
Definition EmbossJob.cpp:81
GLGizmosManager::EType gizmo
Definition EmbossJob.cpp:90
DataBasePtr base
Definition EmbossJob.cpp:78

References anonymous_namespace{EmbossJob.cpp}::DataCreateVolume::base, check(), anonymous_namespace{EmbossJob.cpp}::DataCreateVolume::gizmo, is_valid(), Slic3r::EmbossShape::projection, Slic3r::GUI::Emboss::DataBase::shape, Slic3r::EmbossProjection::use_surface, and anonymous_namespace{EmbossJob.cpp}::DataCreateVolume::volume_type.

Here is the call graph for this function:

◆ check() [6/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const DataUpdate & input,
bool is_main_thread = false,
bool use_surface = false )
786{
787 bool check_fontfile = true;
788 assert(input.base != nullptr);
789 bool res = input.base != nullptr;
790 res &= check(*input.base, check_fontfile, use_surface);
791 if (is_main_thread)
792 assert(get_model_volume(input.volume_id, wxGetApp().model().objects) != nullptr);
793 assert(input.base->cancel != nullptr);
794 res &= input.base->cancel != nullptr;
795 if (is_main_thread)
796 assert(!input.base->cancel->load());
797 assert(!input.base->shape.projection.use_surface);
798 res &= !input.base->shape.projection.use_surface;
799 return res;
800}
std::shared_ptr< std::atomic< bool > > cancel
Definition EmbossJob.hpp:83
static ModelVolume * get_model_volume(const Selection &selection, Model &model)
Definition GLGizmoBrimEars.cpp:66
DataBasePtr base
Definition EmbossJob.hpp:113
ObjectID volume_id
Definition EmbossJob.hpp:116

References Slic3r::GUI::Emboss::DataUpdate::base, Slic3r::GUI::Emboss::DataBase::cancel, check(), Slic3r::GUI::get_model_volume(), Slic3r::EmbossShape::projection, Slic3r::GUI::Emboss::DataBase::shape, Slic3r::EmbossProjection::use_surface, and Slic3r::GUI::Emboss::DataUpdate::volume_id.

Here is the call graph for this function:

◆ check() [7/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( const UpdateSurfaceVolumeData & input,
bool is_main_thread = false )
815{
816 bool use_surface = true;
817 assert(input.base != nullptr);
818 bool res = input.base != nullptr;
819 res &= check(*input.base, is_main_thread, use_surface);
820 assert(!input.sources.empty());
821 res &= !input.sources.empty();
822 assert(input.base->shape.projection.use_surface);
823 res &= input.base->shape.projection.use_surface;
824 return res;
825}

References Slic3r::GUI::Emboss::DataUpdate::base, check(), Slic3r::EmbossShape::projection, Slic3r::GUI::Emboss::DataBase::shape, Slic3r::GUI::Emboss::SurfaceVolumeData::sources, and Slic3r::EmbossProjection::use_surface.

Here is the call graph for this function:

◆ check() [8/8]

bool anonymous_namespace{EmbossJob.cpp}::check ( GLGizmosManager::EType gizmo)
743{
744 assert(gizmo == GLGizmosManager::Emboss || gizmo == GLGizmosManager::Svg);
745 return gizmo == GLGizmosManager::Emboss || gizmo == GLGizmosManager::Svg;
746}
@ Emboss
Definition GLGizmosManager.hpp:99
@ Svg
Definition GLGizmosManager.hpp:100

References check(), Slic3r::GUI::GLGizmosManager::Emboss, and Slic3r::GUI::GLGizmosManager::Svg.

Here is the call graph for this function:

◆ create_default_mesh()

TriangleMesh anonymous_namespace{EmbossJob.cpp}::create_default_mesh ( )

Create default mesh for embossed text.

Returns
Not empty model(index trinagle set - its)
1007{
1008 // When cant load any font use default object loaded from file
1009 std::string path = Slic3r::resources_dir() + "/data/embossed_text.obj";
1010 TriangleMesh triangle_mesh;
1011 std::string message;
1012 ObjInfo obj_info;
1013 if (!load_obj(path.c_str(), &triangle_mesh, obj_info, message)) {
1014 // when can't load mesh use cube
1015 return TriangleMesh(its_make_cube(36., 4., 2.5));
1016 }
1017 return triangle_mesh;
1018}
Definition TriangleMesh.hpp:94
bool load_obj(const char *path, TriangleMesh *meshptr, ObjInfo &obj_info, std::string &message, ObjParser::MtlData *out_mtl)
Definition OBJ.cpp:38
const std::string & resources_dir()
Definition utils.cpp:296
indexed_triangle_set its_make_cube(double xd, double yd, double zd)
Definition TriangleMesh.cpp:902
Definition OBJ.hpp:19

References create_default_mesh(), Slic3r::its_make_cube(), Slic3r::load_obj(), and Slic3r::resources_dir().

Referenced by create_default_mesh(), and create_mesh().

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

◆ create_emboss_projection()

OrthoProject3d anonymous_namespace{EmbossJob.cpp}::create_emboss_projection ( bool is_outside,
float emboss,
Transform3d tr,
SurfaceCut & cut )

Create tranformation for emboss Cutted surface.

Parameters
is_outsideTrue .. raise, False .. engrave
embossDepth of embossing
trText voliume transformation inside object
cutCutted surface from model
Returns
Projection
1219{
1220 float
1221 front_move = (is_outside) ? emboss : SAFE_SURFACE_OFFSET,
1222 back_move = -((is_outside) ? SAFE_SURFACE_OFFSET : emboss);
1223 its_transform(cut, tr.pretranslate(Vec3d(0., 0., front_move)));
1224 Vec3d from_front_to_back(0., 0., back_move - front_move);
1225 return OrthoProject3d(from_front_to_back);
1226}
Definition Emboss.hpp:411
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition Point.hpp:68
constexpr float SAFE_SURFACE_OFFSET
Definition EmbossJob.cpp:94

References create_emboss_projection(), and SAFE_SURFACE_OFFSET.

Referenced by create_emboss_projection(), and cut_surface_to_its().

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

◆ create_line_bounds()

std::vector< BoundingBoxes > anonymous_namespace{EmbossJob.cpp}::create_line_bounds ( const ExPolygonsWithIds & shapes,
size_t count_lines = 0 )
842{
843 if (count_lines == 0)
844 count_lines = get_count_lines(shapes);
845 assert(count_lines == get_count_lines(shapes));
846
847 std::vector<BoundingBoxes> result(count_lines);
848 size_t text_line_index = 0;
849 // s_i .. shape index
850 for (const ExPolygonsWithId &shape_id: shapes) {
851 const ExPolygons &shape = shape_id.expoly;
852 BoundingBox bb;
853 if (!shape.empty()) {
854 bb = get_extents(shape);
855 }
856 BoundingBoxes &line_bbs = result[text_line_index];
857 line_bbs.push_back(bb);
858 if (shape_id.id == ENTER_UNICODE) {
859 // skip enters on beginig and tail
860 ++text_line_index;
861 }
862 }
863 return result;
864}
Definition BoundingBox.hpp:212
unsigned get_count_lines(const std::wstring &ws)
Sum of character ' '.
Definition Emboss.cpp:1437
const unsigned ENTER_UNICODE
Definition Emboss.hpp:166
std::vector< ExPolygon > ExPolygons
Definition ExPolygon.hpp:20
BoundingBox get_extents(const ExPolygonsWithIds &e)
Definition Emboss.cpp:1374
std::vector< BoundingBox > BoundingBoxes
Definition BoundingBox.hpp:235
Definition EmbossShape.hpp:47

References create_line_bounds(), Slic3r::Emboss::ENTER_UNICODE, Slic3r::Emboss::get_count_lines(), and Slic3r::get_extents().

Referenced by create_line_bounds(), create_mesh_per_glyph(), and cut_per_glyph_surface().

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

◆ create_mesh()

template<typename Fnc>
TriangleMesh anonymous_namespace{EmbossJob.cpp}::create_mesh ( DataBase & input,
const Fnc & was_canceled,
Job::Ctl & ctl )
985{
986 // It is neccessary to create some shape
987 // Emboss text window is opened by creation new emboss text object
989 if (was_canceled())
990 return {};
991
992 if (result.its.empty()) {
993 result = create_default_mesh();
994 if (was_canceled())
995 return {};
996 // only info
997 ctl.call_on_main_thread([]() {
998 create_message(_u8L("It is used default volume for embossed text, try to change text or font to fix it."));
999 });
1000 }
1001
1002 assert(!result.its.empty());
1003 return result;
1004}
virtual std::future< void > call_on_main_thread(std::function< void()> fn)=0
indexed_triangle_set its
Definition TriangleMesh.hpp:164
auto was_canceled(const Job::Ctl &ctl, const DataBase &base)
Definition EmbossJob.cpp:292
void create_message(const std::string &message)
Definition EmbossJob.cpp:1613
TriangleMesh create_default_mesh()
Create default mesh for embossed text.
Definition EmbossJob.cpp:1006
TriangleMesh try_create_mesh(DataBase &input, const Fnc &was_canceled)
Try to create mesh from text.
Definition EmbossJob.cpp:958
#define _u8L(s)
Definition I18N.hpp:11

References _u8L, Slic3r::GUI::Job::Ctl::call_on_main_thread(), create_default_mesh(), create_message(), Slic3r::TriangleMesh::its, try_create_mesh(), and was_canceled().

Referenced by anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::process(), and anonymous_namespace{EmbossJob.cpp}::CreateVolumeJob::process().

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

◆ create_mesh_per_glyph()

template<typename Fnc>
TriangleMesh anonymous_namespace{EmbossJob.cpp}::create_mesh_per_glyph ( DataBase & input,
Fnc was_canceled )
867{
868 // method use square of coord stored into int64_t
869 // static_assert(std::is_same<Point::coord_type, int32_t>());
870 const EmbossShape &shape = input.create_shape();
871 if (shape.shapes_with_ids.empty())
872 return {};
873
874 // Precalculate bounding boxes of glyphs
875 // Separate lines of text to vector of Bounds
876 assert(get_count_lines(shape.shapes_with_ids) == input.text_lines.size());
877 size_t count_lines = input.text_lines.size();
878 std::vector<BoundingBoxes> bbs = create_line_bounds(shape.shapes_with_ids, count_lines);
879
880 double depth = shape.projection.depth / shape.scale;
881 auto scale_tr = Eigen::Scaling(shape.scale);
882
883 // half of font em size for direction of letter emboss
884 // double em_2_mm = prop.size_in_mm / 2.; // TODO: fix it
885 double em_2_mm = 5.;
886 coord_t em_2_polygon = static_cast<coord_t>(std::round(scale_(em_2_mm)));
887
888 size_t s_i_offset = 0; // shape index offset(for next lines)
889 indexed_triangle_set result;
890 for (size_t text_line_index = 0; text_line_index < input.text_lines.size(); ++text_line_index) {
891 const BoundingBoxes &line_bbs = bbs[text_line_index];
892 const TextLine &line = input.text_lines[text_line_index];
893 PolygonPoints samples = sample_slice(line, line_bbs, shape.scale);
894 std::vector<double> angles = calculate_angles(em_2_polygon, samples, line.polygon);
895
896 for (size_t i = 0; i < line_bbs.size(); ++i) {
897 const BoundingBox &letter_bb = line_bbs[i];
898 if (!letter_bb.defined)
899 continue;
900
901 Vec2d to_zero_vec = letter_bb.center().cast<double>() * shape.scale; // [in mm]
902 float surface_offset = input.is_outside ? -SAFE_SURFACE_OFFSET : (-shape.projection.depth + SAFE_SURFACE_OFFSET);
903
904 if (input.from_surface.has_value())
905 surface_offset += *input.from_surface;
906
907 Eigen::Translation<double, 3> to_zero(-to_zero_vec.x(), 0., static_cast<double>(surface_offset));
908
909 const double &angle = angles[i];
910 Eigen::AngleAxisd rotate(angle + M_PI_2, Vec3d::UnitY());
911
912 const PolygonPoint &sample = samples[i];
913 Vec2d offset_vec = unscale(sample.point); // [in mm]
914 Eigen::Translation<double, 3> offset_tr(offset_vec.x(), 0., -offset_vec.y());
915 Transform3d tr = offset_tr * rotate * to_zero * scale_tr;
916
917 const ExPolygons &letter_shape = shape.shapes_with_ids[s_i_offset + i].expoly;
918 assert(get_extents(letter_shape) == letter_bb);
919 auto projectZ = std::make_unique<ProjectZ>(depth);
920 ProjectTransform project(std::move(projectZ), tr);
921 indexed_triangle_set glyph_its = polygons2model(letter_shape, project);
922 its_merge(result, std::move(glyph_its));
923
924 if (((s_i_offset + i) % 15) && was_canceled())
925 return {};
926 }
927 s_i_offset += line_bbs.size();
928
929#ifdef STORE_SAMPLING
930 { // Debug store polygon
931 //std::string stl_filepath = "C:/data/temp/line" + std::to_string(text_line_index) + "_model.stl";
932 //bool suc = its_write_stl_ascii(stl_filepath.c_str(), "label", result);
933
934 BoundingBox bbox = get_extents(line.polygon);
935 std::string file_path = "C:/data/temp/line" + std::to_string(text_line_index) + "_letter_position.svg";
936 SVG svg(file_path, bbox);
937 svg.draw(line.polygon);
938 int32_t radius = bbox.size().x() / 300;
939 for (size_t i = 0; i < samples.size(); i++) {
940 const PolygonPoint &pp = samples[i];
941 const Point& p = pp.point;
942 svg.draw(p, "green", radius);
943 std::string label = std::string(" ")+tc.text[i];
944 svg.draw_text(p, label.c_str(), "black");
945
946 double a = angles[i];
947 double length = 3.0 * radius;
948 Point n(length * std::cos(a), length * std::sin(a));
949 svg.draw(Slic3r::Line(p - n, p + n), "Lime");
950 }
951 }
952#endif // STORE_SAMPLING
953 }
954 return TriangleMesh(std::move(result));
955}
PointType size() const
Definition BoundingBox.cpp:178
bool defined
Definition BoundingBox.hpp:22
PointType center() const
Definition BoundingBox.cpp:228
Definition Emboss.hpp:381
virtual EmbossShape & create_shape()
Create shape e.g. Text extract glyphs from font Not 'const' function because it could modify shape.
Definition EmbossJob.hpp:56
std::optional< float > from_surface
Definition EmbossJob.hpp:76
Slic3r::Emboss::TextLines text_lines
Definition EmbossJob.hpp:71
bool is_outside
Definition EmbossJob.hpp:67
#define scale_(val)
Definition libslic3r.h:106
int64_t coord_t
Definition libslic3r.h:48
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.
Definition Emboss.cpp:1985
Polygon polygon
Definition Emboss.hpp:440
indexed_triangle_set polygons2model(const ExPolygons &shape2d, const IProjection &projection)
Create triangle model for text.
Definition Emboss.cpp:1721
std::vector< double > calculate_angles(int32_t distance, const PolygonPoints &polygon_points, const Polygon &polygon)
Definition Emboss.cpp:1976
Define polygon for draw letters.
Definition Emboss.hpp:438
Kernel::Point_3 Point
Definition MeshRepair.cpp:81
double length(const Points &pts)
Definition MultiPoint.hpp:181
Eigen::Transform< double, 3, Eigen::Affine, Eigen::DontAlign > Transform3d
Definition Point.hpp:96
void its_merge(indexed_triangle_set &A, const indexed_triangle_set &B)
Definition TriangleMesh.cpp:1448
double angle(const Eigen::MatrixBase< Derived > &v1, const Eigen::MatrixBase< Derived2 > &v2)
Definition Point.hpp:138
T unscale(Q v)
Definition libslic3r.h:138
std::vector< PolygonPoint > PolygonPoints
Definition Polygon.hpp:310
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
std::vector< BoundingBoxes > create_line_bounds(const ExPolygonsWithIds &shapes, size_t count_lines=0)
Definition EmbossJob.cpp:841
double depth
Definition EmbossShape.hpp:23
Contain plane shape information to be able emboss it and edit it.
Definition EmbossShape.hpp:66
double scale
Definition EmbossShape.hpp:77
ExPolygonsWithIds shapes_with_ids
Definition EmbossShape.hpp:68

References Slic3r::angle(), Slic3r::Emboss::calculate_angles(), Slic3r::BoundingBoxBase< PointType, APointsType >::center(), create_line_bounds(), create_mesh_per_glyph(), Slic3r::GUI::Emboss::DataBase::create_shape(), Slic3r::BoundingBoxBase< PointType, APointsType >::defined, Slic3r::EmbossProjection::depth, Slic3r::SVG::draw(), Slic3r::SVG::draw_text(), Slic3r::GUI::Emboss::DataBase::from_surface, Slic3r::Emboss::get_count_lines(), Slic3r::get_extents(), Slic3r::GUI::Emboss::DataBase::is_outside, Slic3r::its_merge(), Slic3r::length(), Slic3r::PolygonPoint::point, Slic3r::Emboss::TextLine::polygon, Slic3r::Emboss::polygons2model(), Slic3r::EmbossShape::projection, SAFE_SURFACE_OFFSET, Slic3r::Emboss::sample_slice(), Slic3r::EmbossShape::scale, scale_, Slic3r::EmbossShape::shapes_with_ids, Slic3r::BoundingBoxBase< PointType, APointsType >::size(), Slic3r::GUI::Emboss::DataBase::text_lines, Slic3r::unscale(), and was_canceled().

Referenced by create_mesh_per_glyph(), and try_create_mesh().

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

◆ create_message()

void anonymous_namespace{EmbossJob.cpp}::create_message ( const std::string & message)
1613 {
1614 show_error(nullptr, message.c_str());
1615}
void show_error(wxWindow *parent, const wxString &message, bool has_code_excerpts)
Definition GUI.cpp:296

References create_message(), and Slic3r::GUI::show_error().

Referenced by create_mesh(), create_message(), create_volume(), anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::finalize(), anonymous_namespace{EmbossJob.cpp}::CreateVolumeJob::finalize(), process(), and update_volume().

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

◆ create_projection_for_cut()

OrthoProject anonymous_namespace{EmbossJob.cpp}::create_projection_for_cut ( Transform3d tr,
double shape_scale,
const std::pair< float, float > & z_range )

Create projection for cut surface from mesh.

Parameters
trVolume transformation in object
shape_scaleConvert shape to millimeters
z_rangeBounding box 3d of model volume for projection ranges
Returns
Orthogonal cut_projection
1197{
1198 double min_z = z_range.first - safe_extension;
1199 double max_z = z_range.second + safe_extension;
1200 assert(min_z < max_z);
1201 // range between min and max value
1202 double projection_size = max_z - min_z;
1203 Matrix3d transformation_for_vector = tr.linear();
1204 // Projection must be negative value.
1205 // System of text coordinate
1206 // X .. from left to right
1207 // Y .. from bottom to top
1208 // Z .. from text to eye
1209 Vec3d untransformed_direction(0., 0., projection_size);
1210 Vec3d project_direction = transformation_for_vector * untransformed_direction;
1211
1212 // Projection is in direction from far plane
1213 tr.translate(Vec3d(0., 0., min_z));
1214 tr.scale(shape_scale);
1215 return OrthoProject(tr, project_direction);
1216}
Definition Emboss.hpp:419
Eigen::Matrix< double, 3, 3, Eigen::DontAlign > Matrix3d
Definition Point.hpp:86
constexpr float safe_extension
Definition EmbossJob.cpp:202

References create_projection_for_cut(), and safe_extension.

Referenced by create_projection_for_cut(), and cut_surface_to_its().

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

◆ create_shape() [1/2]

template<typename Fnc>
ExPolygons anonymous_namespace{EmbossJob.cpp}::create_shape ( DataBase & input,
Fnc was_canceled )
828 {
829 EmbossShape &es = input.create_shape();
830 // TODO: improve to use real size of volume
831 // ... need world matrix for volume
832 // ... printer resolution will be fine too
834}
static const float UNION_DELTA
Definition Emboss.hpp:31
static const unsigned UNION_MAX_ITERATIN
Definition Emboss.hpp:32
ExPolygons union_with_delta(EmbossShape &shape, float delta, unsigned max_heal_iteration)
Definition Emboss.cpp:1356

References create_shape(), Slic3r::GUI::Emboss::DataBase::create_shape(), Slic3r::Emboss::UNION_DELTA, Slic3r::Emboss::UNION_MAX_ITERATIN, Slic3r::union_with_delta(), and was_canceled().

Referenced by create_shape(), cut_surface(), and try_create_mesh().

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

◆ create_shape() [2/2]

template<typename Fnc>
ExPolygons anonymous_namespace{EmbossJob.cpp}::create_shape ( DataBase & input,
Fnc was_canceled )
static
828 {
829 EmbossShape &es = input.create_shape();
830 // TODO: improve to use real size of volume
831 // ... need world matrix for volume
832 // ... printer resolution will be fine too
834}

References create_shape(), Slic3r::GUI::Emboss::DataBase::create_shape(), Slic3r::Emboss::UNION_DELTA, Slic3r::Emboss::UNION_MAX_ITERATIN, Slic3r::union_with_delta(), and was_canceled().

Referenced by create_shape(), cut_surface(), and try_create_mesh().

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

◆ create_sources()

SurfaceVolumeData::ModelSources anonymous_namespace{EmbossJob.cpp}::create_sources ( const ModelVolumePtrs & volumes,
std::optional< size_t > text_volume_id = {} )

Copied triangles from object to be able create mesh for cut surface from.

Parameters
volumesSource object volumes for cut surface from
text_volume_idSource volume id
Returns
Source data for cut surface from
1408{
1410 result.reserve(volumes.size() - 1);
1411 for (const ModelVolume *v : volumes) {
1412 if (text_volume_id.has_value() && v->id().id == *text_volume_id)
1413 continue;
1414 // skip modifiers and negative volumes, ...
1415 if (!v->is_model_part())
1416 continue;
1417 const TriangleMesh &tm = v->mesh();
1418 if (tm.empty())
1419 continue;
1420 if (tm.its.empty())
1421 continue;
1422 result.push_back({v->get_mesh_shared_ptr(), v->get_matrix()});
1423 }
1424 return result;
1425}
Definition Model.hpp:832
bool empty() const
Definition TriangleMesh.hpp:146
std::vector< ModelSource > ModelSources
Definition EmbossJob.hpp:171

References create_sources(), Slic3r::TriangleMesh::empty(), and Slic3r::TriangleMesh::its.

Referenced by create_sources(), and start_create_volume_job().

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

◆ create_volume()

void anonymous_namespace{EmbossJob.cpp}::create_volume ( TriangleMesh && mesh,
const ObjectID & object_id,
const ModelVolumeType type,
const std::optional< Transform3d > & trmat,
const DataBase & data,
GLGizmosManager::EType gizmo )

Add new volume to object.

Parameters
meshtriangles of new volume
object_idObject where to add volume
typeType of new volume
trmatTransformation of volume inside of object
dataText configuration and New VolumeName
gizmoGizmo to open
1098{
1099 GUI_App &app = wxGetApp();
1100 Plater *plater = app.plater();
1101 ObjectList *obj_list = app.obj_list();
1102 GLCanvas3D *canvas = plater->get_view3D_canvas3D();
1103 ModelObjectPtrs &objects = plater->model().objects;
1104
1105 ModelObject *obj = nullptr;
1106 size_t object_idx = 0;
1107 for (; object_idx < objects.size(); ++object_idx) {
1108 ModelObject *o = objects[object_idx];
1109 if (o->id() == object_id) {
1110 obj = o;
1111 break;
1112 }
1113 }
1114
1115 // Parent object for text volume was propably removed.
1116 // Assumption: User know what he does, so text volume is no more needed.
1117 if (obj == nullptr)
1118 return create_message(_u8L("Bad object to create volume."));
1119
1120 if (mesh.its.empty())
1121 return create_message(_u8L("Can't create empty volume."));
1122
1123 plater->take_snapshot(_u8L("Add Emboss text Volume"));
1124
1125 BoundingBoxf3 instance_bb;
1126 if (!trmat.has_value()) {
1127 // used for align to instance
1128 size_t instance_index = 0; // must exist
1129 instance_bb = obj->instance_bounding_box(instance_index);
1130 }
1131
1132 // NOTE: be carefull add volume also center mesh !!!
1133 // So first add simple shape(convex hull is also calculated)
1134 ModelVolume *volume = obj->add_volume(make_cube(1., 1., 1.), type);
1135
1136 // TODO: Refactor to create better way to not set cube at begining
1137 // Revert mesh centering by set mesh after add cube
1138 volume->set_mesh(std::move(mesh));
1139 volume->calculate_convex_hull();
1140
1141 // set a default extruder value, since user can't add it manually
1142 volume->config.set_key_value("extruder", new ConfigOptionInt(0));
1143
1144 // do not allow model reload from disk
1145 volume->source.is_from_builtin_objects = true;
1146
1147 volume->name = data.volume_name; // copy
1148
1149 if (trmat.has_value()) {
1150 volume->set_transformation(*trmat);
1151 } else {
1152 assert(!data.shape.projection.use_surface);
1153 // Create transformation for volume near from object(defined by glVolume)
1154 // Transformation is inspired add generic volumes in ObjectList::load_generic_subobject
1155 Vec3d volume_size = volume->mesh().bounding_box().size();
1156 // Translate the new modifier to be pickable: move to the left front corner of the instance's bounding box, lift to print bed.
1157 Vec3d offset_tr(0, // center of instance - Can't suggest width of text before it will be created
1158 -instance_bb.size().y() / 2 - volume_size.y() / 2, // under
1159 volume_size.z() / 2 - instance_bb.size().z() / 2); // lay on bed
1160 // use same instance as for calculation of instance_bounding_box
1161 Transform3d tr = obj->instances.front()->get_transformation().get_matrix_no_offset().inverse();
1162 Transform3d volume_trmat = tr * Eigen::Translation3d(offset_tr);
1163 volume->set_transformation(volume_trmat);
1164 }
1165
1166 data.write(*volume);
1167
1168 // update printable state on canvas
1169 if (type == ModelVolumeType::MODEL_PART) {
1170 volume->get_object()->ensure_on_bed();
1172 }
1173
1174 // update volume name in object list
1175 // updata selection after new volume added
1176 // change name of volume in right panel
1177 // select only actual volume
1178 // when new volume is created change selection to this volume
1179 auto add_to_selection = [volume](const ModelVolume *vol) { return vol == volume; };
1180 wxDataViewItemArray sel = obj_list->reorder_volumes_and_get_selection(object_idx, add_to_selection);
1181 if (!sel.IsEmpty())
1182 obj_list->select_item(sel.front());
1183
1185
1186 // Now is valid text volume selected open emboss gizmo
1187 GLGizmosManager &manager = canvas->get_gizmos_manager();
1188 if (manager.get_current_type() != gizmo)
1189 manager.open_gizmo(gizmo);
1190
1191 // update model and redraw scene
1192 //canvas->reload_scene(true);
1193 plater->update();
1194}
PointType size() const
Definition BoundingBox.cpp:187
virtual void write(ModelVolume &volume) const
Write data how to reconstruct shape to volume.
Definition EmbossJob.cpp:302
Definition GLCanvas3D.hpp:239
void update_instance_printable_state_for_object(size_t obj_idx)
Definition GLCanvas3D.cpp:2142
const GLGizmosManager & get_gizmos_manager() const
Definition GLCanvas3D.hpp:1031
bool open_gizmo(EType type)
Definition GLGizmosManager.cpp:458
EType get_current_type() const
Definition GLGizmosManager.hpp:299
Definition GUI_App.hpp:255
ObjectList * obj_list()
Definition GUI_App.cpp:9699
Plater * plater()
Definition GUI_App.cpp:9709
Definition GUI_ObjectList.hpp:97
void selection_changed()
Definition GUI_ObjectList.cpp:1267
wxDataViewItemArray reorder_volumes_and_get_selection(int obj_idx, std::function< bool(const ModelVolume *)> add_to_selection=nullptr)
Definition GUI_ObjectList.cpp:6986
void select_item(const wxDataViewItem &item)
Definition GUI_ObjectList.cpp:5269
Definition Plater.hpp:337
void take_snapshot(const std::string &snapshot_name)
Definition Plater.cpp:21281
void update(bool conside_update_flag=false, bool force_background_processing_update=false)
Definition Plater.cpp:19092
bool set_key_value(const std::string &opt_key, ConfigOption *opt)
Definition PrintConfig.hpp:2635
Definition Model.hpp:382
void ensure_on_bed(bool allow_negative_z=false)
Definition Model.cpp:1896
ModelInstancePtrs instances
Definition Model.hpp:390
ModelVolume * add_volume(const TriangleMesh &mesh, bool modify_to_center_geometry=true)
Definition Model.cpp:1389
BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate=false) const
Definition Model.cpp:1778
void calculate_convex_hull()
Definition Model.cpp:2811
const TriangleMesh & mesh() const
Definition Model.hpp:892
ModelObject * get_object() const
Definition Model.hpp:1022
ModelConfigObject config
Definition Model.hpp:904
void set_mesh(const TriangleMesh &mesh)
Definition Model.hpp:894
std::string name
Definition Model.hpp:834
void set_transformation(const Geometry::Transformation &transformation)
Definition Model.hpp:1108
Source source
Definition Model.hpp:853
ObjectID id() const
Definition ObjectID.hpp:69
BoundingBoxf3 bounding_box() const
Definition TriangleMesh.cpp:447
static ObjectList * obj_list()
Definition GUI_Factories.cpp:405
static Plater * plater()
Definition GUI_Factories.cpp:400
TriangleMesh make_cube(double x, double y, double z)
Definition TriangleMesh.hpp:378
std::vector< ModelObject * > ModelObjectPtrs
Definition CutUtils.hpp:13
bool is_from_builtin_objects
Definition Model.hpp:845

References _u8L, Slic3r::ModelObject::add_volume(), Slic3r::TriangleMesh::bounding_box(), Slic3r::ModelVolume::calculate_convex_hull(), Slic3r::ModelVolume::config, create_message(), create_volume(), Slic3r::ModelObject::ensure_on_bed(), Slic3r::GUI::GLGizmosManager::get_current_type(), Slic3r::GUI::GLCanvas3D::get_gizmos_manager(), Slic3r::ModelVolume::get_object(), Slic3r::ObjectBase::id(), Slic3r::ModelObject::instance_bounding_box(), Slic3r::ModelObject::instances, Slic3r::ModelVolume::Source::is_from_builtin_objects, Slic3r::make_cube(), Slic3r::ModelVolume::mesh(), Slic3r::MODEL_PART, Slic3r::ModelVolume::name, Slic3r::GUI::GUI_App::obj_list(), Slic3r::GUI::obj_list(), Slic3r::GUI::GLGizmosManager::open_gizmo(), Slic3r::GUI::GUI_App::plater(), Slic3r::GUI::plater(), Slic3r::EmbossShape::projection, Slic3r::ModelConfig::set_key_value(), Slic3r::ModelVolume::set_mesh(), Slic3r::ModelVolume::set_transformation(), Slic3r::GUI::Emboss::DataBase::shape, Slic3r::BoundingBox3Base< PointType >::size(), Slic3r::ModelVolume::source, Slic3r::GUI::GLCanvas3D::update_instance_printable_state_for_object(), Slic3r::EmbossProjection::use_surface, Slic3r::GUI::Emboss::DataBase::volume_name, and Slic3r::GUI::Emboss::DataBase::write().

Referenced by create_volume(), anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeJob::finalize(), and anonymous_namespace{EmbossJob.cpp}::CreateVolumeJob::finalize().

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

◆ cut_per_glyph_surface()

TriangleMesh anonymous_namespace{EmbossJob.cpp}::cut_per_glyph_surface ( DataBase & input1,
const SurfaceVolumeData & input2,
std::function< bool()> was_canceled )
1323{
1324 // Precalculate bounding boxes of glyphs
1325 // Separate lines of text to vector of Bounds
1326 const EmbossShape &es = input1.create_shape();
1327 if (was_canceled()) return {};
1328 if (es.shapes_with_ids.empty())
1329 throw JobException(_u8L("Font doesn't have any shape for given text.").c_str());
1330
1331 assert(get_count_lines(es.shapes_with_ids) == input1.text_lines.size());
1332 size_t count_lines = input1.text_lines.size();
1333 std::vector<BoundingBoxes> bbs = create_line_bounds(es.shapes_with_ids, count_lines);
1334
1335 // half of font em size for direction of letter emboss
1336 double em_2_mm = 5.; // TODO: fix it
1337 int32_t em_2_polygon = static_cast<int32_t>(std::round(scale_(em_2_mm)));
1338
1339 size_t s_i_offset = 0; // shape index offset(for next lines)
1340 indexed_triangle_set result;
1341 for (size_t text_line_index = 0; text_line_index < input1.text_lines.size(); ++text_line_index) {
1342 const BoundingBoxes &line_bbs = bbs[text_line_index];
1343 const TextLine &line = input1.text_lines[text_line_index];
1344 PolygonPoints samples = sample_slice(line, line_bbs, es.scale);
1345 std::vector<double> angles = calculate_angles(em_2_polygon, samples, line.polygon);
1346
1347 for (size_t i = 0; i < line_bbs.size(); ++i) {
1348 const BoundingBox &glyph_bb = line_bbs[i];
1349 if (!glyph_bb.defined)
1350 continue;
1351
1352 const double &angle = angles[i];
1353 auto rotate = Eigen::AngleAxisd(angle + M_PI_2, Vec3d::UnitY());
1354
1355 const PolygonPoint &sample = samples[i];
1356 Vec2d offset_vec = unscale(sample.point); // [in mm]
1357 auto offset_tr = Eigen::Translation<double, 3>(offset_vec.x(), 0., -offset_vec.y());
1358
1359 ExPolygons glyph_shape = es.shapes_with_ids[s_i_offset + i].expoly;
1360 assert(get_extents(glyph_shape) == glyph_bb);
1361
1362 Point offset(-glyph_bb.center().x(), 0);
1363 for (ExPolygon& s: glyph_shape)
1364 s.translate(offset);
1365
1366 Transform3d modify = offset_tr * rotate;
1367 Transform3d tr = input2.transform * modify;
1368 indexed_triangle_set glyph_its = cut_surface_to_its(glyph_shape, tr, input2.sources, input1, was_canceled);
1369 // move letter in volume on the right position
1370 its_transform(glyph_its, modify);
1371
1372 // Improve: union instead of merge
1373 its_merge(result, std::move(glyph_its));
1374
1375 if (((s_i_offset + i) % 15) && was_canceled())
1376 return {};
1377 }
1378 s_i_offset += line_bbs.size();
1379 }
1380
1381 if (was_canceled()) return {};
1382 if (result.empty())
1383 throw JobException(_u8L("There is no valid surface for text projection.").c_str());
1384 return TriangleMesh(std::move(result));
1385}
Definition ExPolygon.hpp:23
Definition Point.hpp:199
Slic3r::Polygons offset(const Slic3r::Polygon &polygon, const float delta, JoinType joinType, double miterLimit)
Definition ClipperUtils.cpp:582
indexed_triangle_set cut_surface_to_its(const ExPolygons &shapes, const Transform3d &tr, const SurfaceVolumeData::ModelSources &sources, DataBase &input, std::function< bool()> was_canceled)
Definition EmbossJob.cpp:1228
Transform3d transform
Definition EmbossJob.hpp:162

References _u8L, Slic3r::angle(), Slic3r::Emboss::calculate_angles(), Slic3r::BoundingBoxBase< PointType, APointsType >::center(), create_line_bounds(), Slic3r::GUI::Emboss::DataBase::create_shape(), cut_per_glyph_surface(), cut_surface_to_its(), Slic3r::BoundingBoxBase< PointType, APointsType >::defined, Slic3r::Emboss::get_count_lines(), Slic3r::get_extents(), Slic3r::its_merge(), Slic3r::offset(), Slic3r::PolygonPoint::point, Slic3r::Emboss::TextLine::polygon, Slic3r::Emboss::sample_slice(), Slic3r::EmbossShape::scale, scale_, Slic3r::EmbossShape::shapes_with_ids, Slic3r::GUI::Emboss::SurfaceVolumeData::sources, Slic3r::GUI::Emboss::DataBase::text_lines, Slic3r::GUI::Emboss::SurfaceVolumeData::transform, Slic3r::unscale(), and was_canceled().

Referenced by cut_per_glyph_surface(), and cut_surface().

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

◆ cut_surface()

template<typename Fnc>
TriangleMesh anonymous_namespace{EmbossJob.cpp}::cut_surface ( DataBase & input1,
const SurfaceVolumeData & input2,
const Fnc & was_canceled )

Cut surface into triangle mesh.

Parameters
base(can't be const - cache of font)
input2SurfaceVolume data
was_canceledCheck to interupt execution
Returns
Extruded object from cuted surace
1390{
1391 if (!input1.text_lines.empty())
1392 return cut_per_glyph_surface(input1, input2, was_canceled);
1393
1394 ExPolygons shapes = create_shape(input1, was_canceled);
1395 if (was_canceled()) return {};
1396 if (shapes.empty())
1397 throw JobException(_u8L("Font doesn't have any shape for given text.").c_str());
1398
1399 indexed_triangle_set its = cut_surface_to_its(shapes, input2.transform, input2.sources, input1, was_canceled);
1400 if (was_canceled()) return {};
1401 if (its.empty())
1402 throw JobException(_u8L("There is no valid surface for text projection.").c_str());
1403
1404 return TriangleMesh(std::move(its));
1405}
TriangleMesh cut_per_glyph_surface(DataBase &input1, const SurfaceVolumeData &input2, std::function< bool()> was_canceled)
Definition EmbossJob.cpp:1322
static ExPolygons create_shape(DataBase &input, Fnc was_canceled)
Definition EmbossJob.cpp:828

References _u8L, create_shape(), cut_per_glyph_surface(), cut_surface_to_its(), Slic3r::GUI::Emboss::SurfaceVolumeData::sources, Slic3r::GUI::Emboss::DataBase::text_lines, Slic3r::GUI::Emboss::SurfaceVolumeData::transform, and was_canceled().

Referenced by anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeJob::process().

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

◆ cut_surface_to_its()

indexed_triangle_set anonymous_namespace{EmbossJob.cpp}::cut_surface_to_its ( const ExPolygons & shapes,
const Transform3d & tr,
const SurfaceVolumeData::ModelSources & sources,
DataBase & input,
std::function< bool()> was_canceled )
1228 {
1229 assert(!sources.empty());
1230 BoundingBox bb = get_extents(shapes);
1231 double shape_scale = input.shape.scale;
1232
1233 const SurfaceVolumeData::ModelSource *biggest = &sources.front();
1234
1235 size_t biggest_count = 0;
1236 // convert index from (s)ources to (i)ndexed (t)riangle (s)ets
1237 std::vector<size_t> s_to_itss(sources.size(), std::numeric_limits<size_t>::max());
1238 std::vector<indexed_triangle_set> itss;
1239 itss.reserve(sources.size());
1240 for (const SurfaceVolumeData::ModelSource &s : sources) {
1241 Transform3d mesh_tr_inv = s.tr.inverse();
1242 Transform3d cut_projection_tr = mesh_tr_inv * tr;
1243 std::pair<float, float> z_range{0., 1.};
1244 OrthoProject cut_projection = create_projection_for_cut(cut_projection_tr, shape_scale, z_range);
1245 // copy only part of source model
1246 indexed_triangle_set its = its_cut_AoI(s.mesh->its, bb, cut_projection);
1247 if (its.indices.empty())
1248 continue;
1249 if (biggest_count < its.vertices.size()) {
1250 biggest_count = its.vertices.size();
1251 biggest = &s;
1252 }
1253 size_t source_index = &s - &sources.front();
1254 size_t its_index = itss.size();
1255 s_to_itss[source_index] = its_index;
1256 itss.emplace_back(std::move(its));
1257 }
1258 if (itss.empty())
1259 return {};
1260
1261 Transform3d tr_inv = biggest->tr.inverse();
1262 Transform3d cut_projection_tr = tr_inv * tr;
1263
1264 size_t itss_index = s_to_itss[biggest - &sources.front()];
1265 BoundingBoxf3 mesh_bb = bounding_box(itss[itss_index]);
1266 for (const SurfaceVolumeData::ModelSource &s : sources) {
1267 itss_index = s_to_itss[&s - &sources.front()];
1268 if (itss_index == std::numeric_limits<size_t>::max())
1269 continue;
1270 if (&s == biggest)
1271 continue;
1272
1273 Transform3d tr = s.tr * tr_inv;
1274 bool fix_reflected = true;
1275 indexed_triangle_set &its = itss[itss_index];
1276 its_transform(its, tr, fix_reflected);
1277 BoundingBoxf3 its_bb = bounding_box(its);
1278 mesh_bb.merge(its_bb);
1279 }
1280
1281 // tr_inv = transformation of mesh inverted
1282 Transform3d emboss_tr = cut_projection_tr.inverse();
1283 BoundingBoxf3 mesh_bb_tr = mesh_bb.transformed(emboss_tr);
1284 std::pair<float, float> z_range{mesh_bb_tr.min.z(), mesh_bb_tr.max.z()};
1285 OrthoProject cut_projection = create_projection_for_cut(cut_projection_tr, shape_scale, z_range);
1286 float projection_ratio = (-z_range.first + safe_extension) /
1287 (z_range.second - z_range.first + 2 * safe_extension);
1288
1289 ExPolygons shapes_data; // is used only when text is reflected to reverse polygon points order
1290 const ExPolygons *shapes_ptr = &shapes;
1291 bool is_text_reflected = Slic3r::has_reflection(tr);
1292 if (is_text_reflected) {
1293 // revert order of points in expolygons
1294 // CW --> CCW
1295 shapes_data = shapes; // copy
1296 for (ExPolygon &shape : shapes_data) {
1297 shape.contour.reverse();
1298 for (Slic3r::Polygon &hole : shape.holes)
1299 hole.reverse();
1300 }
1301 shapes_ptr = &shapes_data;
1302 }
1303
1304 // Use CGAL to cut surface from triangle mesh
1305 SurfaceCut cut = cut_surface(*shapes_ptr, itss, cut_projection, projection_ratio);
1306
1307 if (is_text_reflected) {
1308 for (SurfaceCut::Contour &c : cut.contours)
1309 std::reverse(c.begin(), c.end());
1310 for (Vec3i32 &t : cut.indices)
1311 std::swap(t[0], t[1]);
1312 }
1313
1314 if (cut.empty()) return {}; // There is no valid surface for text projection.
1315 if (was_canceled()) return {};
1316
1317 // !! Projection needs to transform cut
1318 OrthoProject3d projection = create_emboss_projection(input.is_outside, input.shape.projection.depth, emboss_tr, cut);
1319 return cut2model(cut, projection);
1320}
void merge(const PointType &point)
Definition BoundingBox.cpp:139
BoundingBoxf3 transformed(const Transform3d &matrix) const
Definition BoundingBox.cpp:261
void reverse()
Definition MultiPoint.hpp:43
BoundingBoxf3 bounding_box(const TriangleMesh &m)
Definition TriangleMesh.hpp:391
indexed_triangle_set cut2model(const SurfaceCut &cut, const Emboss::IProject3d &projection)
Create model from surface cuts by projection.
Definition CutSurface.cpp:653
indexed_triangle_set its_cut_AoI(const indexed_triangle_set &its, const BoundingBox &bb, const Emboss::IProjection &projection)
Separate (A)rea (o)f (I)nterest .. AoI from model NOTE: Only 2d filtration, do not filtrate by Z coor...
Definition CutSurface.cpp:895
bool has_reflection(const Transform3d &transform)
Check whether transformation matrix contains odd number of mirroring. NOTE: In code is sometime funct...
Definition Point.hpp:179
Eigen::Matrix< int32_t, 3, 1, Eigen::DontAlign > Vec3i32
Definition Point.hpp:59
OrthoProject3d create_emboss_projection(bool is_outside, float emboss, Transform3d tr, SurfaceCut &cut)
Create tranformation for emboss Cutted surface.
Definition EmbossJob.cpp:1218
OrthoProject create_projection_for_cut(Transform3d tr, double shape_scale, const std::pair< float, float > &z_range)
Create projection for cut surface from mesh.
Definition EmbossJob.cpp:1196
TriangleMesh cut_surface(DataBase &input1, const SurfaceVolumeData &input2, const Fnc &was_canceled)
Cut surface into triangle mesh.
Definition EmbossJob.cpp:1389
Transform3d tr
Definition EmbossJob.hpp:169
Contours contours
Definition CutSurface.hpp:26
std::vector< Index > Contour
Definition CutSurface.hpp:23

References Slic3r::bounding_box(), Slic3r::SurfaceCut::contours, create_emboss_projection(), create_projection_for_cut(), Slic3r::cut2model(), Slic3r::cut_surface(), cut_surface_to_its(), Slic3r::EmbossProjection::depth, Slic3r::get_extents(), Slic3r::has_reflection(), Slic3r::GUI::Emboss::DataBase::is_outside, Slic3r::its_cut_AoI(), Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::max, Slic3r::BoundingBox3Base< PointType >::merge(), Slic3r::BoundingBoxBase< PointType, std::vector< PointType > >::min, Slic3r::EmbossShape::projection, Slic3r::MultiPoint::reverse(), safe_extension, Slic3r::EmbossShape::scale, Slic3r::GUI::Emboss::DataBase::shape, Slic3r::GUI::Emboss::SurfaceVolumeData::ModelSource::tr, Slic3r::BoundingBoxf3::transformed(), and was_canceled().

Referenced by cut_per_glyph_surface(), cut_surface(), and cut_surface_to_its().

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

◆ finalize()

bool anonymous_namespace{EmbossJob.cpp}::finalize ( bool canceled,
std::exception_ptr & eptr,
const DataBase & input )
1441{
1442 // doesn't care about exception when process was canceled by user
1443 if (canceled || input.cancel->load()) {
1444 eptr = nullptr;
1445 return false;
1446 }
1447 return !process(eptr);
1448}
bool process(std::exception_ptr &eptr)
Definition EmbossJob.cpp:1427

References Slic3r::GUI::Emboss::DataBase::cancel, finalize(), and process().

Referenced by finalize().

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

◆ find_closest()

const GLVolume * anonymous_namespace{EmbossJob.cpp}::find_closest ( const Selection & selection,
const Vec2d & screen_center,
const Camera & camera,
const ModelObjectPtrs & objects,
Vec2d * closest_center )

Find volume in selected objects with closest convex hull to screen center.

Parameters
selectionDefine where to search for closest
screen_centerCanvas center(dependent on camera settings)
objectsActual objects
closest_centerOUT: coordinate of controid of closest volume
Returns
closest volume when exists otherwise nullptr
1495{
1496 assert(closest_center != nullptr);
1497 const GLVolume *closest = nullptr;
1498 const Selection::IndicesList &indices = selection.get_volume_idxs();
1499 assert(!indices.empty()); // no selected volume
1500 if (indices.empty())
1501 return closest;
1502
1503 double center_sq_distance = std::numeric_limits<double>::max();
1504 for (unsigned int id : indices) {
1505 const GLVolume *gl_volume = selection.get_volume(id);
1506 if (const ModelVolume *volume = get_model_volume(*gl_volume, objects);
1507 volume == nullptr || !volume->is_model_part())
1508 continue;
1509 Slic3r::Polygon hull = CameraUtils::create_hull2d(camera, *gl_volume);
1510 Vec2d c = hull.centroid().cast<double>();
1511 Vec2d d = c - screen_center;
1512 bool is_bigger_x = std::fabs(d.x()) > std::fabs(d.y());
1513 if ((is_bigger_x && d.x() * d.x() > center_sq_distance) ||
1514 (!is_bigger_x && d.y() * d.y() > center_sq_distance))
1515 continue;
1516
1517 double distance = d.squaredNorm();
1518 if (center_sq_distance < distance)
1519 continue;
1520 center_sq_distance = distance;
1521
1522 *closest_center = c;
1523 closest = gl_volume;
1524 }
1525 return closest;
1526}
Definition 3DScene.hpp:90
static Polygon create_hull2d(const Camera &camera, const GLVolume &volume)
Create hull around GLVolume in 2d space of camera.
Definition CameraUtils.cpp:59
std::set< unsigned int > IndicesList
Definition Selection.hpp:49
const IndicesList & get_volume_idxs() const
Definition Selection.hpp:315
const GLVolume * get_volume(unsigned int volume_idx) const
Definition Selection.cpp:984
bool is_model_part() const
Definition Model.hpp:1025
Definition Polygon.hpp:31
Point centroid() const
Definition Polygon.cpp:154

References Slic3r::Polygon::centroid(), Slic3r::GUI::CameraUtils::create_hull2d(), find_closest(), Slic3r::GUI::get_model_volume(), Slic3r::GUI::Selection::get_volume(), Slic3r::GUI::Selection::get_volume_idxs(), and Slic3r::ModelVolume::is_model_part().

Referenced by find_closest().

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

◆ is_valid()

bool anonymous_namespace{EmbossJob.cpp}::is_valid ( ModelVolumeType volume_type)

Check if volume type is possible use for new text volume.

Parameters
volume_typeType
Returns
True when allowed otherwise false
1451{
1452 assert(volume_type != ModelVolumeType::INVALID);
1453 assert(volume_type == ModelVolumeType::MODEL_PART ||
1454 volume_type == ModelVolumeType::NEGATIVE_VOLUME ||
1455 volume_type == ModelVolumeType::PARAMETER_MODIFIER);
1456 if (volume_type == ModelVolumeType::MODEL_PART ||
1457 volume_type == ModelVolumeType::NEGATIVE_VOLUME ||
1458 volume_type == ModelVolumeType::PARAMETER_MODIFIER)
1459 return true;
1460
1461 BOOST_LOG_TRIVIAL(error) << "Can't create embossed volume with this type: " << (int) volume_type;
1462 return false;
1463}

References Slic3r::INVALID, is_valid(), Slic3r::MODEL_PART, Slic3r::NEGATIVE_VOLUME, and Slic3r::PARAMETER_MODIFIER.

Referenced by check(), check(), and is_valid().

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

◆ process()

bool anonymous_namespace{EmbossJob.cpp}::process ( std::exception_ptr & eptr)
1428{
1429 if (!eptr)
1430 return false;
1431 try {
1432 std::rethrow_exception(eptr);
1433 } catch (JobException &e) {
1434 create_message(e.what());
1435 eptr = nullptr;
1436 }
1437 return true;
1438}

References create_message(), and process().

Referenced by finalize(), and process().

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

◆ start_create_object_job()

bool anonymous_namespace{EmbossJob.cpp}::start_create_object_job ( const CreateVolumeParams & input,
DataBasePtr emboss_data,
const Vec2d & coor )

Start job for add object with text into scene.

Parameters
inputContain worker, build shape, gizmo
emboss_dataDefine params for create volume
coorScreen coordinat, where to create new object laying on bed
Returns
True when can add job to worker otherwise FALSE
1529{
1530 const Pointfs &bed_shape = input.build_volume.printable_area();
1531 auto gizmo_type = static_cast<GLGizmosManager::EType>(input.gizmo);
1532 DataCreateObject data{std::move(emboss_data), coor, input.camera, bed_shape, gizmo_type, input.angle};
1533
1534 // Fix: adding text on print bed with style containing use_surface
1535 if (data.base->shape.projection.use_surface)
1536 // Til the print bed is flat using surface for Object is useless
1537 data.base->shape.projection.use_surface = false;
1538
1539 auto job = std::make_unique<CreateObjectJob>(std::move(data));
1540 return queue_job(input.worker, std::move(job));
1541}
const std::vector< Vec2d > & printable_area() const
Definition BuildVolume.hpp:65
std::optional< float > angle
Definition EmbossJob.hpp:234
const Camera & camera
Definition EmbossJob.hpp:210
Worker & worker
Definition EmbossJob.hpp:216
const BuildVolume & build_volume
Definition EmbossJob.hpp:213
bool queue_job(Worker &w, ProcessFn fn, FinishFn finishfn)
Definition Worker.hpp:62
std::vector< Vec2d > Pointfs
Definition Point.hpp:77
Hold neccessary data to create ModelObject in job Object is placed on bed under screen coor OR to cen...
Definition EmbossJob.cpp:118

References Slic3r::GUI::Emboss::CreateVolumeParams::angle, anonymous_namespace{EmbossJob.cpp}::DataCreateObject::base, Slic3r::GUI::Emboss::CreateVolumeParams::build_volume, Slic3r::GUI::Emboss::CreateVolumeParams::camera, Slic3r::GUI::Emboss::CreateVolumeParams::gizmo, Slic3r::BuildVolume::printable_area(), Slic3r::EmbossShape::projection, Slic3r::GUI::queue_job(), Slic3r::GUI::Emboss::DataBase::shape, start_create_object_job(), Slic3r::EmbossProjection::use_surface, and Slic3r::GUI::Emboss::CreateVolumeParams::worker.

Referenced by start_create_object_job().

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

◆ start_create_volume_job()

bool anonymous_namespace{EmbossJob.cpp}::start_create_volume_job ( Worker & worker,
const ModelObject & object,
const std::optional< Transform3d > & volume_tr,
DataBasePtr data,
ModelVolumeType volume_type,
GLGizmosManager::EType gizmo )

Start job for add new volume to object with given transformation.

Parameters
workerDefine where to queue the job. e.g. wxGetApp().plater()->get_ui_job_worker()
objectDefine where to add
volume_trWanted volume transformation, when not set will be calculated after creation to be near the object
dataDefine what to emboss - shape
volume_typeType of volume: Part, negative, modifier
gizmoDefine which gizmo open on the success
Returns
Nullptr when job is sucessfully add to worker otherwise return data to be processed different way
1471{
1472 bool &use_surface = data->shape.projection.use_surface;
1473 std::unique_ptr<GUI::Job> job;
1474 if (use_surface) {
1475 // Model to cut surface from.
1476 SurfaceVolumeData::ModelSources sources = create_sources(object.volumes);
1477 if (sources.empty() || !volume_tr.has_value()) {
1478 use_surface = false;
1479 } else {
1480 SurfaceVolumeData sfvd{*volume_tr, std::move(sources)};
1481 CreateSurfaceVolumeData surface_data{std::move(sfvd), std::move(data), volume_type, object.id(), gizmo};
1482 job = std::make_unique<CreateSurfaceVolumeJob>(std::move(surface_data));
1483 }
1484 }
1485 if (!use_surface) {
1486 // create volume
1487 DataCreateVolume create_volume_data{std::move(data), volume_type, object.id(), volume_tr, gizmo};
1488 job = std::make_unique<CreateVolumeJob>(std::move(create_volume_data));
1489 }
1490 return queue_job(worker, std::move(job));
1491}
SurfaceVolumeData::ModelSources create_sources(const ModelVolumePtrs &volumes, std::optional< size_t > text_volume_id={})
Copied triangles from object to be able create mesh for cut surface from.
Definition EmbossJob.cpp:1407
Hold neccessary data to create ModelVolume in job Volume is created on the surface of existing volume...
Definition EmbossJob.cpp:76
Definition EmbossJob.hpp:160
Hold neccessary data to create(cut) volume from surface object in job.
Definition EmbossJob.cpp:158

References create_sources(), Slic3r::EmbossShape::projection, Slic3r::GUI::queue_job(), Slic3r::GUI::Emboss::DataBase::shape, start_create_volume_job(), and Slic3r::EmbossProjection::use_surface.

Referenced by start_create_volume_job(), and start_create_volume_on_surface_job().

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

◆ start_create_volume_on_surface_job()

bool anonymous_namespace{EmbossJob.cpp}::start_create_volume_on_surface_job ( CreateVolumeParams & input,
DataBasePtr data,
const Vec2d & screen_coor,
bool try_no_coor )

Start job to create volume on the surface of object.

Parameters
inputVariabless needed to create volume
dataDescribe what to emboss - shape
screen_coorWhere to add
try_no_coorTrue .. try to create volume without screen_coor, False ..
Returns
Nullptr when job is sucessfully add to worker otherwise return data to be processed different way
1544{
1545 auto on_bad_state = [&input, try_no_coor](DataBasePtr data_, const ModelObject *object = nullptr) {
1546 if (try_no_coor) {
1547 // Can't create on coordinate try to create somewhere
1548 return start_create_volume_without_position(input, std::move(data_));
1549 } else {
1550 // In centroid of convex hull is not hit with object. e.g. torid
1551 // soo create transfomation on border of object
1552
1553 // there is no point on surface so no use of surface will be applied
1554 if (data_->shape.projection.use_surface)
1555 data_->shape.projection.use_surface = false;
1556
1557 if (object == nullptr)
1558 return false;
1559
1560 auto gizmo_type = static_cast<GLGizmosManager::EType>(input.gizmo);
1561 return start_create_volume_job(input.worker, *object, {}, std::move(data_), input.volume_type, gizmo_type);
1562 }
1563 };
1564
1565 assert(input.gl_volume != nullptr);
1566 if (input.gl_volume == nullptr)
1567 return on_bad_state(std::move(data));
1568
1569 const Model *model = input.canvas.get_model();
1570
1571 assert(model != nullptr);
1572 if (model == nullptr)
1573 return on_bad_state(std::move(data));
1574
1575 const ModelObjectPtrs &objects = model->objects;
1576 const ModelVolume *volume = get_model_volume(*input.gl_volume, objects);
1577 assert(volume != nullptr);
1578 if (volume == nullptr)
1579 return on_bad_state(std::move(data));
1580
1581 const ModelInstance *instance = get_model_instance(*input.gl_volume, objects);
1582 assert(instance != nullptr);
1583 if (instance == nullptr)
1584 return on_bad_state(std::move(data));
1585
1586 const ModelObject *object = volume->get_object();
1587 assert(object != nullptr);
1588 if (object == nullptr)
1589 return on_bad_state(std::move(data));
1590
1591 auto cond = RaycastManager::AllowVolumes({volume->id().id});
1592 RaycastManager::Meshes meshes = create_meshes(input.canvas, cond);
1593 input.raycaster.actualize(*instance, &cond, &meshes);
1594 std::optional<RaycastManager::Hit> hit = ray_from_camera(input.raycaster, screen_coor, input.camera, &cond);
1595
1596 // context menu for add text could be open only by right click on an
1597 // object. After right click, object is selected and object_idx is set
1598 // also hit must exist. But there is options to add text by object list
1599 if (!hit.has_value())
1600 // When model is broken. It could appear that hit miss the object.
1601 // So add part near by in simmilar manner as right panel do
1602 return on_bad_state(std::move(data), object);
1603
1604 // Create result volume transformation
1605 Transform3d surface_trmat = create_transformation_onto_surface(hit->position, hit->normal, UP_LIMIT);
1606 apply_transformation(input.angle, input.distance, surface_trmat);
1607 Transform3d transform = instance->get_matrix().inverse() * surface_trmat;
1608 auto gizmo_type = static_cast<GLGizmosManager::EType>(input.gizmo);
1609 // Try to cast ray into scene and find object for add volume
1610 return start_create_volume_job(input.worker, *object, transform, std::move(data), input.volume_type, gizmo_type);
1611}
const Model * get_model() const
Definition GLCanvas3D.hpp:1026
void actualize(const ModelObject &object, const ISkip *skip=nullptr, Meshes *meshes=nullptr)
Actualize raycasters + transformation Detection of removed object Detection of removed instance Detec...
Definition RaycastManager.cpp:38
std::vector< Mesh > Meshes
Definition RaycastManager.hpp:29
const Transform3d & get_matrix() const
Definition Model.hpp:1511
ModelObjectPtrs objects
Definition Model.hpp:1702
size_t id
Definition ObjectID.hpp:39
void apply_transformation(const std::optional< float > &angle, const std::optional< float > &distance, Transform3d &transformation)
Use data from font property to modify transformation.
Definition Emboss.cpp:1480
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.
Definition Emboss.cpp:1792
RaycastManager & raycaster
Definition EmbossJob.hpp:222
const GLVolume * gl_volume
Definition EmbossJob.hpp:228
GLCanvas3D & canvas
Definition EmbossJob.hpp:207
std::unique_ptr< DataBase > DataBasePtr
Definition EmbossJob.hpp:105
bool start_create_volume_without_position(CreateVolumeParams &input, DataBasePtr data)
Same as previous function but without mouse position Need to suggest position or put near the selecti...
Definition EmbossJob.cpp:616
std::optional< float > distance
Definition EmbossJob.hpp:231
constexpr double UP_LIMIT
Definition SurfaceDrag.hpp:56
RaycastManager::Meshes create_meshes(GLCanvas3D &canvas, const RaycastManager::AllowVolumes &condition)
Use scene Raycasters and prepare data for actualize RaycasterManager.
Definition RaycastManager.cpp:330
ModelInstance * get_model_instance(const GLVolume &gl_volume, const Model &model)
Definition GLCanvas3D.cpp:13028
std::optional< RaycastManager::Hit > ray_from_camera(const RaycastManager &raycaster, const Vec2d &mouse_pos, const Camera &camera, const RaycastManager::ISkip *skip)
Unproject on mesh by Mesh raycasters.
Definition RaycastManager.cpp:365
Linef3 transform(const Linef3 &line, const Transform3d &t)
Definition Line.cpp:15
bool start_create_volume_job(Worker &worker, const ModelObject &object, const std::optional< Transform3d > &volume_tr, DataBasePtr data, ModelVolumeType volume_type, GLGizmosManager::EType gizmo)
Start job for add new volume to object with given transformation.
Definition EmbossJob.cpp:1465

References Slic3r::GUI::RaycastManager::actualize(), Slic3r::GUI::Emboss::CreateVolumeParams::angle, Slic3r::Emboss::apply_transformation(), Slic3r::GUI::Emboss::CreateVolumeParams::camera, Slic3r::GUI::Emboss::CreateVolumeParams::canvas, Slic3r::GUI::create_meshes(), Slic3r::Emboss::create_transformation_onto_surface(), Slic3r::GUI::Emboss::CreateVolumeParams::distance, Slic3r::ModelInstance::get_matrix(), Slic3r::GUI::GLCanvas3D::get_model(), Slic3r::GUI::get_model_instance(), Slic3r::GUI::get_model_volume(), Slic3r::ModelVolume::get_object(), Slic3r::GUI::Emboss::CreateVolumeParams::gizmo, Slic3r::GUI::Emboss::CreateVolumeParams::gl_volume, Slic3r::ObjectBase::id(), Slic3r::ObjectID::id, Slic3r::Model::objects, Slic3r::GUI::ray_from_camera(), Slic3r::GUI::Emboss::CreateVolumeParams::raycaster, start_create_volume_job(), start_create_volume_on_surface_job(), Slic3r::GUI::Emboss::start_create_volume_without_position(), Slic3r::transform(), Slic3r::GUI::UP_LIMIT, Slic3r::GUI::Emboss::CreateVolumeParams::volume_type, and Slic3r::GUI::Emboss::CreateVolumeParams::worker.

Referenced by start_create_volume_on_surface_job().

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

◆ try_create_mesh()

template<typename Fnc>
TriangleMesh anonymous_namespace{EmbossJob.cpp}::try_create_mesh ( DataBase & input,
const Fnc & was_canceled )

Try to create mesh from text.

Parameters
inputText to convert on mesh
  • Shape of characters + Property of font
fontFont file with cache NOTE: Cache glyphs is changed
was_canceledTo check if process was canceled
Returns
Triangle mesh model
959{
960 if (!input.text_lines.empty()) {
962 if (was_canceled()) return {};
963 if (!tm.empty()) return tm;
964 }
965
966 ExPolygons shapes = create_shape(input, was_canceled);
967 if (shapes.empty()) return {};
968 if (was_canceled()) return {};
969
970 // NOTE: SHAPE_SCALE is applied in ProjectZ
971 double scale = input.shape.scale;
972 double depth = input.shape.projection.depth / scale;
973 auto projectZ = std::make_unique<ProjectZ>(depth);
975 if (input.from_surface.has_value())
976 offset += *input.from_surface;
977 Transform3d tr = Eigen::Translation<double, 3>(0., 0.,static_cast<double>(offset)) * Eigen::Scaling(scale);
978 ProjectTransform project(std::move(projectZ), tr);
979 if (was_canceled()) return {};
980 return TriangleMesh(polygons2model(shapes, project));
981}
int scale(const int val)
Definition WipeTowerDialog.cpp:58
TriangleMesh create_mesh_per_glyph(DataBase &input, Fnc was_canceled)
Definition EmbossJob.cpp:866

References create_mesh_per_glyph(), create_shape(), Slic3r::EmbossProjection::depth, Slic3r::TriangleMesh::empty(), Slic3r::GUI::Emboss::DataBase::from_surface, Slic3r::GUI::Emboss::DataBase::is_outside, Slic3r::offset(), Slic3r::Emboss::polygons2model(), Slic3r::EmbossShape::projection, SAFE_SURFACE_OFFSET, scale(), Slic3r::EmbossShape::scale, Slic3r::GUI::Emboss::DataBase::shape, Slic3r::GUI::Emboss::DataBase::text_lines, try_create_mesh(), and was_canceled().

Referenced by create_mesh(), and try_create_mesh().

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

◆ update_name_in_list()

void anonymous_namespace{EmbossJob.cpp}::update_name_in_list ( const ObjectList & object_list,
const ModelVolume & volume )

Update name in right panel.

Parameters
obj_listRight panel data
volumeVolume with just changed name
1021{
1022 const ModelObjectPtrs *objects_ptr = object_list.objects();
1023 if (objects_ptr == nullptr)
1024 return;
1025
1026 const ModelObjectPtrs &objects = *objects_ptr;
1027 const ModelObject *object = volume.get_object();
1028 const ObjectID &object_id = object->id();
1029
1030 // search for index of object
1031 int object_index = -1;
1032 for (size_t i = 0; i < objects.size(); ++i)
1033 if (objects[i]->id() == object_id) {
1034 object_index = static_cast<int>(i);
1035 break;
1036 }
1037
1038 const ModelVolumePtrs volumes = object->volumes;
1039 const ObjectID &volume_id = volume.id();
1040
1041 // search for index of volume
1042 int volume_index = -1;
1043 for (size_t i = 0; i < volumes.size(); ++i)
1044 if (volumes[i]->id() == volume_id) {
1045 volume_index = static_cast<int>(i);
1046 break;
1047 }
1048
1049 if (object_index < 0 || volume_index < 0)
1050 return;
1051
1052 object_list.update_name_in_list(object_index, volume_index);
1053}
std::vector< ModelObject * > * objects() const
Definition GUI_ObjectList.hpp:235
void update_name_in_list(int obj_idx, int vol_idx) const
Definition GUI_ObjectList.cpp:1253
Definition ObjectID.hpp:23
std::vector< ModelVolume * > ModelVolumePtrs
Definition Model.hpp:139

References Slic3r::ModelVolume::get_object(), Slic3r::ObjectBase::id(), Slic3r::ObjectID::id, Slic3r::GUI::ObjectList::objects(), update_name_in_list(), and Slic3r::GUI::ObjectList::update_name_in_list().

Referenced by update_name_in_list().

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

◆ update_volume()

void anonymous_namespace{EmbossJob.cpp}::update_volume ( TriangleMesh && mesh,
const DataUpdate & data,
const Transform3d * tr = nullptr )

Must be called on main thread.

Parameters
meshNew mesh data
dataText configuration, ...
meshTransformation of volume
1056{
1057 // for sure that some object will be created
1058 if (mesh.its.empty())
1059 return create_message(_u8L("Empty mesh can't be created."));
1060
1061 Plater *plater = wxGetApp().plater();
1062 // Check gizmo is still open otherwise job should be canceled
1063 assert(plater->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Emboss ||
1064 plater->canvas3D()->get_gizmos_manager().get_current_type() == GLGizmosManager::Svg);
1065
1066 if (data.make_snapshot) {
1067 // TRN: This is the title of the action appearing in undo/redo stack.
1068 // It is same for Text and SVG.
1069 std::string snap_name = _u8L("Emboss attribute change");
1070 Plater::TakeSnapshot snapshot(plater, snap_name, UndoRedo::SnapshotType::GizmoAction);
1071 }
1072
1073 ModelVolume *volume = get_model_volume(data.volume_id, plater->model().objects);
1074
1075 // could appear when user delete edited volume
1076 if (volume == nullptr)
1077 return;
1078
1079 if (tr) {
1080 volume->set_transformation(*tr);
1081 } else {
1082 // apply fix matrix made by store to .3mf
1083 const std::optional<EmbossShape> &emboss_shape = volume->emboss_shape;
1084 assert(emboss_shape.has_value());
1085 if (emboss_shape.has_value() && emboss_shape->fix_3mf_tr.has_value())
1086 volume->set_transformation(volume->get_matrix() * emboss_shape->fix_3mf_tr->inverse());
1087 }
1088
1089 UpdateJob::update_volume(volume, std::move(mesh), *data.base);
1090}
static void update_volume(ModelVolume *volume, TriangleMesh &&mesh, const DataBase &base)
Update text volume.
Definition EmbossJob.cpp:448
Definition Plater.hpp:966
const Transform3d & get_matrix() const
Definition Model.hpp:1139
std::optional< EmbossShape > emboss_shape
Definition Model.hpp:1019
bool make_snapshot
Definition EmbossJob.hpp:119

References _u8L, Slic3r::GUI::Emboss::DataUpdate::base, create_message(), Slic3r::GUI::GLGizmosManager::Emboss, Slic3r::ModelVolume::emboss_shape, Slic3r::ModelVolume::get_matrix(), Slic3r::GUI::get_model_volume(), Slic3r::UndoRedo::GizmoAction, Slic3r::GUI::Emboss::DataUpdate::make_snapshot, Slic3r::GUI::plater(), Slic3r::ModelVolume::set_transformation(), Slic3r::GUI::GLGizmosManager::Svg, update_volume(), Slic3r::GUI::Emboss::UpdateJob::update_volume(), and Slic3r::GUI::Emboss::DataUpdate::volume_id.

Referenced by update_volume().

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

◆ was_canceled()

auto anonymous_namespace{EmbossJob.cpp}::was_canceled ( const Job::Ctl & ctl,
const DataBase & base )
292 {
293 return [&ctl, &cancel = base.cancel]() {
294 if (cancel->load())
295 return true;
296 return ctl.was_canceled();
297 };
298}
virtual bool was_canceled() const =0

References Slic3r::GUI::Emboss::DataBase::cancel, was_canceled(), and Slic3r::GUI::Job::Ctl::was_canceled().

Referenced by create_mesh(), create_mesh_per_glyph(), create_shape(), cut_per_glyph_surface(), cut_surface(), cut_surface_to_its(), anonymous_namespace{EmbossJob.cpp}::CreateObjectJob::process(), anonymous_namespace{EmbossJob.cpp}::CreateSurfaceVolumeJob::process(), anonymous_namespace{EmbossJob.cpp}::CreateVolumeJob::process(), try_create_mesh(), and was_canceled().

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

Variable Documentation

◆ safe_extension

float anonymous_namespace{EmbossJob.cpp}::safe_extension = 1.0f
constexpr

◆ SAFE_SURFACE_OFFSET

float anonymous_namespace{EmbossJob.cpp}::SAFE_SURFACE_OFFSET = 0.015f
constexpr