Projection text for cut surface is made with double preccission
This commit is contained in:
parent
8511b280bf
commit
3fa3ea0bb4
7 changed files with 439 additions and 416 deletions
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,7 @@ SurfaceCut cut_surface(const ExPolygons &shapes,
|
|||
/// <param name="projection">Way of emboss</param>
|
||||
/// <returns>Mesh</returns>
|
||||
indexed_triangle_set cut2model(const SurfaceCut &cut,
|
||||
const Emboss::IProject3f &projection);
|
||||
const Emboss::IProject3d &projection);
|
||||
|
||||
/// <summary>
|
||||
/// Separate (A)rea (o)f (I)nterest .. AoI from model
|
||||
|
@ -68,5 +68,7 @@ indexed_triangle_set its_cut_AoI(const indexed_triangle_set &its,
|
|||
/// <returns>Copy of indices by mask(with their vertices)</returns>
|
||||
indexed_triangle_set its_mask(const indexed_triangle_set &its, const std::vector<bool> &mask);
|
||||
|
||||
bool corefine_test(const std::string &model_path, const std::string &shape_path);
|
||||
|
||||
} // namespace Slic3r
|
||||
#endif // slic3r_CutSurface_hpp_
|
||||
|
|
|
@ -303,6 +303,7 @@ ExPolygons Emboss::heal_shape(const Polygons &shape) {
|
|||
return res;
|
||||
}
|
||||
|
||||
#define HEAL_CLOSE_POINTS
|
||||
bool Emboss::heal_shape(ExPolygons &shape, unsigned max_iteration)
|
||||
{
|
||||
if (shape.empty()) return true;
|
||||
|
@ -313,11 +314,11 @@ bool Emboss::heal_shape(ExPolygons &shape, unsigned max_iteration)
|
|||
|
||||
Pointfs intersections = intersection_points(shape);
|
||||
Points duplicits = collect_duplications(to_points(shape));
|
||||
Points close = priv::collect_close_points(shape);
|
||||
if (intersections.empty() && duplicits.empty() && close.empty()) break;
|
||||
//Points close = priv::collect_close_points(shape, 1.);
|
||||
if (intersections.empty() && duplicits.empty() /* && close.empty() */) break;
|
||||
|
||||
holes.clear();
|
||||
holes.reserve(intersections.size() + duplicits.size() + close.size());
|
||||
holes.reserve(intersections.size() + duplicits.size() /* + close.size()*/);
|
||||
|
||||
// Fix self intersection in result by subtracting hole 2x2
|
||||
for (const Vec2d &p : intersections) {
|
||||
|
@ -335,11 +336,11 @@ bool Emboss::heal_shape(ExPolygons &shape, unsigned max_iteration)
|
|||
}
|
||||
|
||||
// fix close points in simmilar way as duplicits
|
||||
for (const Point &p : close) {
|
||||
Slic3r::Polygon hole(priv::pts_3x3);
|
||||
hole.translate(p);
|
||||
holes.push_back(hole);
|
||||
}
|
||||
//for (const Point &p : close) {
|
||||
// Slic3r::Polygon hole(priv::pts_3x3);
|
||||
// hole.translate(p);
|
||||
// holes.push_back(hole);
|
||||
//}
|
||||
|
||||
holes = Slic3r::union_(holes);
|
||||
shape = Slic3r::diff_ex(shape, holes, ApplySafetyOffset::Yes);
|
||||
|
@ -1063,8 +1064,8 @@ indexed_triangle_set polygons2model_unique(
|
|||
|
||||
for (const Point &p : points) {
|
||||
auto p2 = projection.create_front_back(p);
|
||||
front_points.push_back(p2.first);
|
||||
back_points.push_back(p2.second);
|
||||
front_points.push_back(p2.first.cast<float>());
|
||||
back_points.push_back(p2.second.cast<float>());
|
||||
}
|
||||
|
||||
// insert back points, front are already in
|
||||
|
@ -1132,8 +1133,8 @@ indexed_triangle_set polygons2model_duplicit(
|
|||
max_index = index;
|
||||
const Point &p = points[i];
|
||||
auto p2 = projection.create_front_back(p);
|
||||
front_points.push_back(p2.first);
|
||||
back_points.push_back(p2.second);
|
||||
front_points.push_back(p2.first.cast<float>());
|
||||
back_points.push_back(p2.second.cast<float>());
|
||||
}
|
||||
assert(max_index+1 == count_point);
|
||||
|
||||
|
@ -1185,23 +1186,23 @@ indexed_triangle_set Emboss::polygons2model(const ExPolygons &shape2d,
|
|||
priv::polygons2model_duplicit(shape2d, projection, points, duplicits);
|
||||
}
|
||||
|
||||
std::pair<Vec3f, Vec3f> Emboss::ProjectZ::create_front_back(const Point &p) const
|
||||
std::pair<Vec3d, Vec3d> Emboss::ProjectZ::create_front_back(const Point &p) const
|
||||
{
|
||||
Vec3f front(
|
||||
static_cast<float>(p.x() * SHAPE_SCALE),
|
||||
static_cast<float>(p.y() * SHAPE_SCALE),
|
||||
0.f);
|
||||
Vec3d front(
|
||||
p.x() * SHAPE_SCALE,
|
||||
p.y() * SHAPE_SCALE,
|
||||
0.);
|
||||
return std::make_pair(front, project(front));
|
||||
}
|
||||
|
||||
Vec3f Emboss::ProjectZ::project(const Vec3f &point) const
|
||||
Vec3d Emboss::ProjectZ::project(const Vec3d &point) const
|
||||
{
|
||||
Vec3f res = point; // copy
|
||||
Vec3d res = point; // copy
|
||||
res.z() = m_depth;
|
||||
return res;
|
||||
}
|
||||
|
||||
std::optional<Point> Emboss::ProjectZ::unproject(const Vec3f &p) const {
|
||||
std::optional<Point> Emboss::ProjectZ::unproject(const Vec3d &p) const {
|
||||
return Point(p.x() / SHAPE_SCALE, p.y() / SHAPE_SCALE);
|
||||
}
|
||||
|
||||
|
@ -1267,18 +1268,18 @@ Transform3d Emboss::create_transformation_onto_surface(const Vec3f &position,
|
|||
|
||||
// OrthoProject
|
||||
|
||||
std::pair<Vec3f, Vec3f> Emboss::OrthoProject::create_front_back(const Point &p) const {
|
||||
std::pair<Vec3d, Vec3d> Emboss::OrthoProject::create_front_back(const Point &p) const {
|
||||
Vec3d front(p.x(), p.y(), 0.);
|
||||
Vec3f front_tr = (m_matrix * front).cast<float>();
|
||||
Vec3d front_tr = m_matrix * front;
|
||||
return std::make_pair(front_tr, project(front_tr));
|
||||
}
|
||||
|
||||
Vec3f Emboss::OrthoProject::project(const Vec3f &point) const
|
||||
Vec3d Emboss::OrthoProject::project(const Vec3d &point) const
|
||||
{
|
||||
return point + m_direction;
|
||||
}
|
||||
|
||||
std::optional<Point> Emboss::OrthoProject::unproject(const Vec3f &p) const {
|
||||
Vec3d pp = m_matrix_inv * p.cast<double>();
|
||||
std::optional<Point> Emboss::OrthoProject::unproject(const Vec3d &p) const {
|
||||
Vec3d pp = m_matrix_inv * p;
|
||||
return Point(pp.x(), pp.y());
|
||||
}
|
|
@ -215,10 +215,10 @@ public:
|
|||
/// <summary>
|
||||
/// Project spatial point
|
||||
/// </summary>
|
||||
class IProject3f
|
||||
class IProject3d
|
||||
{
|
||||
public:
|
||||
virtual ~IProject3f() = default;
|
||||
virtual ~IProject3d() = default;
|
||||
/// <summary>
|
||||
/// Move point with respect to projection direction
|
||||
/// e.g. Orthogonal projection will move with point by direction
|
||||
|
@ -226,14 +226,14 @@ public:
|
|||
/// </summary>
|
||||
/// <param name="point">Spatial point coordinate</param>
|
||||
/// <returns>Projected spatial point</returns>
|
||||
virtual Vec3f project(const Vec3f &point) const = 0;
|
||||
virtual Vec3d project(const Vec3d &point) const = 0;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Project 2d point into space
|
||||
/// Could be plane, sphere, cylindric, ...
|
||||
/// </summary>
|
||||
class IProjection : public IProject3f
|
||||
class IProjection : public IProject3d
|
||||
{
|
||||
public:
|
||||
virtual ~IProjection() = default;
|
||||
|
@ -246,9 +246,9 @@ public:
|
|||
/// first - front spatial point
|
||||
/// second - back spatial point
|
||||
/// </returns>
|
||||
virtual std::pair<Vec3f, Vec3f> create_front_back(const Point &p) const = 0;
|
||||
virtual std::pair<Vec3d, Vec3d> create_front_back(const Point &p) const = 0;
|
||||
|
||||
virtual std::optional<Point> unproject(const Vec3f &p) const = 0;
|
||||
virtual std::optional<Point> unproject(const Vec3d &p) const = 0;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@ -272,59 +272,59 @@ public:
|
|||
class ProjectZ : public IProjection
|
||||
{
|
||||
public:
|
||||
ProjectZ(float depth) : m_depth(depth) {}
|
||||
ProjectZ(double depth) : m_depth(depth) {}
|
||||
// Inherited via IProject
|
||||
std::pair<Vec3f, Vec3f> create_front_back(const Point &p) const override;
|
||||
Vec3f project(const Vec3f &point) const override;
|
||||
std::optional<Point> unproject(const Vec3f &p) const override;
|
||||
float m_depth;
|
||||
std::pair<Vec3d, Vec3d> create_front_back(const Point &p) const override;
|
||||
Vec3d project(const Vec3d &point) const override;
|
||||
std::optional<Point> unproject(const Vec3d &p) const override;
|
||||
double m_depth;
|
||||
};
|
||||
|
||||
class ProjectScale : public IProjection
|
||||
{
|
||||
std::unique_ptr<IProjection> core;
|
||||
float m_scale;
|
||||
double m_scale;
|
||||
public:
|
||||
ProjectScale(std::unique_ptr<IProjection> core, float scale)
|
||||
ProjectScale(std::unique_ptr<IProjection> core, double scale)
|
||||
: core(std::move(core)), m_scale(scale)
|
||||
{}
|
||||
|
||||
// Inherited via IProject
|
||||
std::pair<Vec3f, Vec3f> create_front_back(const Point &p) const override
|
||||
std::pair<Vec3d, Vec3d> create_front_back(const Point &p) const override
|
||||
{
|
||||
auto res = core->create_front_back(p);
|
||||
return std::make_pair(res.first * m_scale, res.second * m_scale);
|
||||
}
|
||||
Vec3f project(const Vec3f &point) const override{
|
||||
Vec3d project(const Vec3d &point) const override{
|
||||
return core->project(point);
|
||||
}
|
||||
std::optional<Point> unproject(const Vec3f &p) const override {
|
||||
std::optional<Point> unproject(const Vec3d &p) const override {
|
||||
return core->unproject(p / m_scale);
|
||||
}
|
||||
};
|
||||
|
||||
class OrthoProject3f : public Emboss::IProject3f
|
||||
class OrthoProject3d : public Emboss::IProject3d
|
||||
{
|
||||
// size and direction of emboss for ortho projection
|
||||
Vec3f m_direction;
|
||||
Vec3d m_direction;
|
||||
public:
|
||||
OrthoProject3f(Vec3f direction) : m_direction(direction) {}
|
||||
Vec3f project(const Vec3f &point) const override{ return point + m_direction;}
|
||||
OrthoProject3d(Vec3d direction) : m_direction(direction) {}
|
||||
Vec3d project(const Vec3d &point) const override{ return point + m_direction;}
|
||||
};
|
||||
|
||||
class OrthoProject: public Emboss::IProjection {
|
||||
Transform3d m_matrix;
|
||||
// size and direction of emboss for ortho projection
|
||||
Vec3f m_direction;
|
||||
Vec3d m_direction;
|
||||
Transform3d m_matrix_inv;
|
||||
public:
|
||||
OrthoProject(Transform3d matrix, Vec3f direction)
|
||||
OrthoProject(Transform3d matrix, Vec3d direction)
|
||||
: m_matrix(matrix), m_direction(direction), m_matrix_inv(matrix.inverse())
|
||||
{}
|
||||
// Inherited via IProject
|
||||
std::pair<Vec3f, Vec3f> create_front_back(const Point &p) const override;
|
||||
Vec3f project(const Vec3f &point) const override;
|
||||
std::optional<Point> unproject(const Vec3f &p) const override;
|
||||
std::pair<Vec3d, Vec3d> create_front_back(const Point &p) const override;
|
||||
Vec3d project(const Vec3d &point) const override;
|
||||
std::optional<Point> unproject(const Vec3d &p) const override;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ static Emboss::OrthoProject create_projection_for_cut(
|
|||
/// <param name="tr">Text voliume transformation inside object</param>
|
||||
/// <param name="cut">Cutted surface from model</param>
|
||||
/// <returns>Projection</returns>
|
||||
static Emboss::OrthoProject3f create_emboss_projection(
|
||||
static Emboss::OrthoProject3d create_emboss_projection(
|
||||
bool is_outside, float emboss, Transform3d tr, SurfaceCut &cut);
|
||||
|
||||
static void create_message(const std::string &message); // only in finalize
|
||||
|
@ -428,7 +428,7 @@ void UseSurfaceJob::process(Ctl &ctl) {
|
|||
if (was_canceled()) return;
|
||||
|
||||
// !! Projection needs to transform cut
|
||||
Emboss::OrthoProject3f projection = priv::create_emboss_projection(
|
||||
Emboss::OrthoProject3d projection = priv::create_emboss_projection(
|
||||
m_input.is_outside, fp.emboss, emboss_tr, cut);
|
||||
|
||||
indexed_triangle_set new_its = cut2model(cut, projection);
|
||||
|
@ -664,8 +664,8 @@ Emboss::OrthoProject priv::create_projection_for_cut(
|
|||
double shape_scale,
|
||||
const std::pair<float, float> &z_range)
|
||||
{
|
||||
float min_z = z_range.first - priv::safe_extension;
|
||||
float max_z = z_range.second + priv::safe_extension;
|
||||
double min_z = z_range.first - priv::safe_extension;
|
||||
double max_z = z_range.second + priv::safe_extension;
|
||||
assert(min_z < max_z);
|
||||
// range between min and max value
|
||||
double projection_size = max_z - min_z;
|
||||
|
@ -676,8 +676,7 @@ Emboss::OrthoProject priv::create_projection_for_cut(
|
|||
// Y .. from bottom to top
|
||||
// Z .. from text to eye
|
||||
Vec3d untransformed_direction(0., 0., projection_size);
|
||||
Vec3f project_direction =
|
||||
(transformation_for_vector * untransformed_direction).cast<float>();
|
||||
Vec3d project_direction = transformation_for_vector * untransformed_direction;
|
||||
|
||||
// Projection is in direction from far plane
|
||||
tr.translate(Vec3d(0., 0., min_z));
|
||||
|
@ -685,7 +684,7 @@ Emboss::OrthoProject priv::create_projection_for_cut(
|
|||
return Emboss::OrthoProject(tr, project_direction);
|
||||
}
|
||||
|
||||
Emboss::OrthoProject3f priv::create_emboss_projection(
|
||||
Emboss::OrthoProject3d priv::create_emboss_projection(
|
||||
bool is_outside, float emboss, Transform3d tr, SurfaceCut &cut)
|
||||
{
|
||||
// Offset of clossed side to model
|
||||
|
@ -694,8 +693,8 @@ Emboss::OrthoProject3f priv::create_emboss_projection(
|
|||
front_move = (is_outside) ? emboss : surface_offset,
|
||||
back_move = -((is_outside) ? surface_offset : emboss);
|
||||
its_transform(cut, tr.pretranslate(Vec3d(0., 0., front_move)));
|
||||
Vec3f from_front_to_back(0.f, 0.f, back_move - front_move);
|
||||
return Emboss::OrthoProject3f(from_front_to_back);
|
||||
Vec3d from_front_to_back(0., 0., back_move - front_move);
|
||||
return Emboss::OrthoProject3d(from_front_to_back);
|
||||
}
|
||||
|
||||
bool priv::process(std::exception_ptr &eptr) {
|
||||
|
|
|
@ -11,7 +11,7 @@ TEST_CASE("Cut character from surface", "[]")
|
|||
char letter = '%';
|
||||
float flatness = 2.;
|
||||
unsigned int font_index = 0; // collection
|
||||
float z_depth = 50.f; // projection size
|
||||
double z_depth = 50.f; // projection size
|
||||
|
||||
auto font = Emboss::create_font_file(font_path.c_str());
|
||||
REQUIRE(font != nullptr);
|
||||
|
@ -24,7 +24,7 @@ TEST_CASE("Cut character from surface", "[]")
|
|||
Transform3d tr = Transform3d::Identity();
|
||||
tr.translate(Vec3d(0., 0., -z_depth));
|
||||
tr.scale(Emboss::SHAPE_SCALE);
|
||||
Emboss::OrthoProject cut_projection(tr, Vec3f(0.f, 0.f, z_depth));
|
||||
Emboss::OrthoProject cut_projection(tr, Vec3d(0., 0., z_depth));
|
||||
|
||||
auto object = its_make_cube(782 - 49 + 50, 724 + 10 + 50, 5);
|
||||
its_translate(object, Vec3f(49 - 25, -10 - 25, -40));
|
||||
|
@ -38,7 +38,7 @@ TEST_CASE("Cut character from surface", "[]")
|
|||
CHECK(!surfaces.empty());
|
||||
|
||||
Emboss::OrthoProject projection(Transform3d::Identity(),
|
||||
Vec3f(0.f, 0.f, 10.f));
|
||||
Vec3d(0.f, 0.f, 10.f));
|
||||
its_translate(surfaces, Vec3f(0.f, 0.f, 10));
|
||||
|
||||
indexed_triangle_set its = cut2model(surfaces, projection);
|
||||
|
@ -81,8 +81,8 @@ static Emboss::OrthoProject create_projection_for_cut(
|
|||
{
|
||||
// create sure that emboss object is bigger than source object
|
||||
const float safe_extension = 1.0f;
|
||||
float min_z = z_range.first - safe_extension;
|
||||
float max_z = z_range.second + safe_extension;
|
||||
double min_z = z_range.first - safe_extension;
|
||||
double max_z = z_range.second + safe_extension;
|
||||
assert(min_z < max_z);
|
||||
// range between min and max value
|
||||
double projection_size = max_z - min_z;
|
||||
|
@ -93,8 +93,7 @@ static Emboss::OrthoProject create_projection_for_cut(
|
|||
// Y .. from bottom to top
|
||||
// Z .. from text to eye
|
||||
Vec3d untransformed_direction(0., 0., projection_size);
|
||||
Vec3f project_direction =
|
||||
(transformation_for_vector * untransformed_direction).cast<float>();
|
||||
Vec3d project_direction = transformation_for_vector * untransformed_direction;
|
||||
|
||||
// Projection is in direction from far plane
|
||||
tr.translate(Vec3d(0., 0., min_z));
|
||||
|
|
|
@ -433,8 +433,8 @@ TEST_CASE("Cut surface", "[]")
|
|||
std::string font_path = get_font_filepath();
|
||||
char letter = '%';
|
||||
float flatness = 2.;
|
||||
unsigned int font_index = 0; // collection
|
||||
float z_depth = 50.f; // projection size
|
||||
unsigned int font_index = 0; // collection
|
||||
double z_depth = 50.; // projection size
|
||||
|
||||
auto font = Emboss::create_font_file(font_path.c_str());
|
||||
REQUIRE(font != nullptr);
|
||||
|
@ -451,7 +451,7 @@ TEST_CASE("Cut surface", "[]")
|
|||
Transform3d tr = Transform3d::Identity();
|
||||
tr.translate(Vec3d(0., 0., -z_depth));
|
||||
tr.scale(Emboss::SHAPE_SCALE);
|
||||
Emboss::OrthoProject cut_projection(tr, Vec3f(0.f, 0.f, z_depth));
|
||||
Emboss::OrthoProject cut_projection(tr, Vec3d(0., 0., z_depth));
|
||||
|
||||
auto object = its_make_cube(782 - 49 + 50, 724 + 10 + 50, 5);
|
||||
its_translate(object, Vec3f(49 - 25, -10 - 25, -40));
|
||||
|
@ -462,8 +462,8 @@ TEST_CASE("Cut surface", "[]")
|
|||
auto surfaces = cut_surface(shape, {object}, cut_projection, 0);
|
||||
CHECK(!surfaces.empty());
|
||||
|
||||
Emboss::OrthoProject projection(Transform3d::Identity(), Vec3f(0.f, 0.f, 10.f));
|
||||
its_translate(surfaces, Vec3f(0.f, 0.f, 10));
|
||||
Emboss::OrthoProject projection(Transform3d::Identity(), Vec3d(0., 0., 10.));
|
||||
its_translate(surfaces, Vec3f(0., 0., 10.));
|
||||
|
||||
indexed_triangle_set its = cut2model(surfaces, projection);
|
||||
CHECK(!its.empty());
|
||||
|
|
Loading…
Reference in a new issue