Projection text for cut surface is made with double preccission

This commit is contained in:
Filip Sykala - NTB T15p 2022-10-12 16:17:38 +02:00
parent 8511b280bf
commit 3fa3ea0bb4
7 changed files with 439 additions and 416 deletions

File diff suppressed because it is too large Load diff

View file

@ -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_

View file

@ -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());
}

View file

@ -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;
};
};

View file

@ -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) {

View file

@ -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));

View file

@ -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());