Removed Point::scale(),translate(),coincides_with(),distance_to(),
distance_to_squared(),perp_distance_to(),negative(),vector_to(), translate(), distance_to() etc, replaced with the Eigen equivalents.
This commit is contained in:
parent
3b89717149
commit
1ba64da3fe
45 changed files with 526 additions and 792 deletions
|
@ -68,8 +68,8 @@ BoundingBox BoundingBox::rotated(double angle, const Point ¢er) const
|
||||||
template <class PointClass> void
|
template <class PointClass> void
|
||||||
BoundingBoxBase<PointClass>::scale(double factor)
|
BoundingBoxBase<PointClass>::scale(double factor)
|
||||||
{
|
{
|
||||||
this->min.scale(factor);
|
this->min *= factor;
|
||||||
this->max.scale(factor);
|
this->max *= factor;
|
||||||
}
|
}
|
||||||
template void BoundingBoxBase<Point>::scale(double factor);
|
template void BoundingBoxBase<Point>::scale(double factor);
|
||||||
template void BoundingBoxBase<Pointf>::scale(double factor);
|
template void BoundingBoxBase<Pointf>::scale(double factor);
|
||||||
|
@ -188,8 +188,9 @@ template double BoundingBox3Base<Pointf3>::radius() const;
|
||||||
template <class PointClass> void
|
template <class PointClass> void
|
||||||
BoundingBoxBase<PointClass>::offset(coordf_t delta)
|
BoundingBoxBase<PointClass>::offset(coordf_t delta)
|
||||||
{
|
{
|
||||||
this->min.translate(-delta, -delta);
|
PointClass v(delta, delta);
|
||||||
this->max.translate(delta, delta);
|
this->min -= v;
|
||||||
|
this->max += v;
|
||||||
}
|
}
|
||||||
template void BoundingBoxBase<Point>::offset(coordf_t delta);
|
template void BoundingBoxBase<Point>::offset(coordf_t delta);
|
||||||
template void BoundingBoxBase<Pointf>::offset(coordf_t delta);
|
template void BoundingBoxBase<Pointf>::offset(coordf_t delta);
|
||||||
|
@ -197,8 +198,9 @@ template void BoundingBoxBase<Pointf>::offset(coordf_t delta);
|
||||||
template <class PointClass> void
|
template <class PointClass> void
|
||||||
BoundingBox3Base<PointClass>::offset(coordf_t delta)
|
BoundingBox3Base<PointClass>::offset(coordf_t delta)
|
||||||
{
|
{
|
||||||
this->min.translate(-delta, -delta, -delta);
|
PointClass v(delta, delta, delta);
|
||||||
this->max.translate(delta, delta, delta);
|
this->min -= v;
|
||||||
|
this->max += v;
|
||||||
}
|
}
|
||||||
template void BoundingBox3Base<Pointf3>::offset(coordf_t delta);
|
template void BoundingBox3Base<Pointf3>::offset(coordf_t delta);
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ public:
|
||||||
void scale(double factor);
|
void scale(double factor);
|
||||||
PointClass size() const;
|
PointClass size() const;
|
||||||
double radius() const;
|
double radius() const;
|
||||||
void translate(coordf_t x, coordf_t y) { assert(this->defined); this->min.translate(x, y); this->max.translate(x, y); }
|
void translate(coordf_t x, coordf_t y) { assert(this->defined); PointClass v(x, y); this->min += v; this->max += v; }
|
||||||
void translate(const Pointf &pos) { this->translate(pos.x(), pos.y()); }
|
void translate(const Pointf &v) { this->min += v; this->max += v; }
|
||||||
void offset(coordf_t delta);
|
void offset(coordf_t delta);
|
||||||
PointClass center() const;
|
PointClass center() const;
|
||||||
bool contains(const PointClass &point) const {
|
bool contains(const PointClass &point) const {
|
||||||
|
@ -90,8 +90,8 @@ public:
|
||||||
void merge(const BoundingBox3Base<PointClass> &bb);
|
void merge(const BoundingBox3Base<PointClass> &bb);
|
||||||
PointClass size() const;
|
PointClass size() const;
|
||||||
double radius() const;
|
double radius() const;
|
||||||
void translate(coordf_t x, coordf_t y, coordf_t z) { this->min.translate(x, y, z); this->max.translate(x, y, z); }
|
void translate(coordf_t x, coordf_t y, coordf_t z) { assert(this->defined); PointClass v(x, y, z); this->min += v; this->max += v; }
|
||||||
void translate(const Pointf3 &pos) { this->translate(pos.x(), pos.y(), pos.z()); }
|
void translate(const Pointf3 &v) { this->min += v; this->max += v; }
|
||||||
void offset(coordf_t delta);
|
void offset(coordf_t delta);
|
||||||
PointClass center() const;
|
PointClass center() const;
|
||||||
coordf_t max_size() const;
|
coordf_t max_size() const;
|
||||||
|
|
|
@ -282,10 +282,12 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
|
||||||
extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
|
extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
|
||||||
direction might still benefit from anchors if long enough)
|
direction might still benefit from anchors if long enough)
|
||||||
double angle_tolerance = PI / 180.0 * 5.0; */
|
double angle_tolerance = PI / 180.0 * 5.0; */
|
||||||
for (Lines::const_iterator line = unsupported_lines.begin(); line != unsupported_lines.end(); ++line) {
|
for (const Line &line : unsupported_lines)
|
||||||
if (!Slic3r::Geometry::directions_parallel(line->direction(), angle))
|
if (! Slic3r::Geometry::directions_parallel(line.direction(), angle)) {
|
||||||
unsupported->push_back(*line);
|
unsupported->emplace_back(Polyline());
|
||||||
}
|
unsupported->back().points.emplace_back(line.a);
|
||||||
|
unsupported->back().points.emplace_back(line.b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -634,8 +634,8 @@ _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons
|
||||||
// convert Lines to Polylines
|
// convert Lines to Polylines
|
||||||
Polylines polylines;
|
Polylines polylines;
|
||||||
polylines.reserve(subject.size());
|
polylines.reserve(subject.size());
|
||||||
for (Lines::const_iterator line = subject.begin(); line != subject.end(); ++line)
|
for (const Line &line : subject)
|
||||||
polylines.push_back(*line);
|
polylines.emplace_back(Polyline(line.a, line.b));
|
||||||
|
|
||||||
// perform operation
|
// perform operation
|
||||||
polylines = _clipper_pl(clipType, polylines, clip, safety_offset_);
|
polylines = _clipper_pl(clipType, polylines, clip, safety_offset_);
|
||||||
|
|
|
@ -767,7 +767,7 @@ void EdgeGrid::Grid::calculate_sdf()
|
||||||
const Slic3r::Point &p1 = pts[ipt];
|
const Slic3r::Point &p1 = pts[ipt];
|
||||||
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
||||||
// Segment vector
|
// Segment vector
|
||||||
const Slic3r::Point v_seg = p1.vector_to(p2);
|
const Slic3r::Point v_seg = p2 - p1;
|
||||||
// l2 of v_seg
|
// l2 of v_seg
|
||||||
const int64_t l2_seg = int64_t(v_seg.x()) * int64_t(v_seg.x()) + int64_t(v_seg.y()) * int64_t(v_seg.y());
|
const int64_t l2_seg = int64_t(v_seg.x()) * int64_t(v_seg.x()) + int64_t(v_seg.y()) * int64_t(v_seg.y());
|
||||||
// For each corner of this cell and its 1 ring neighbours:
|
// For each corner of this cell and its 1 ring neighbours:
|
||||||
|
@ -781,7 +781,7 @@ void EdgeGrid::Grid::calculate_sdf()
|
||||||
continue;
|
continue;
|
||||||
float &d_min = m_signed_distance_field[corner_r * ncols + corner_c];
|
float &d_min = m_signed_distance_field[corner_r * ncols + corner_c];
|
||||||
Slic3r::Point pt(m_bbox.min.x() + corner_c * m_resolution, m_bbox.min.y() + corner_r * m_resolution);
|
Slic3r::Point pt(m_bbox.min.x() + corner_c * m_resolution, m_bbox.min.y() + corner_r * m_resolution);
|
||||||
Slic3r::Point v_pt = p1.vector_to(pt);
|
Slic3r::Point v_pt = pt - p1;
|
||||||
// dot(p2-p1, pt-p1)
|
// dot(p2-p1, pt-p1)
|
||||||
int64_t t_pt = int64_t(v_seg.x()) * int64_t(v_pt.x()) + int64_t(v_seg.y()) * int64_t(v_pt.y());
|
int64_t t_pt = int64_t(v_seg.x()) * int64_t(v_pt.x()) + int64_t(v_seg.y()) * int64_t(v_pt.y());
|
||||||
if (t_pt < 0) {
|
if (t_pt < 0) {
|
||||||
|
@ -790,7 +790,7 @@ void EdgeGrid::Grid::calculate_sdf()
|
||||||
if (dabs < d_min) {
|
if (dabs < d_min) {
|
||||||
// Previous point.
|
// Previous point.
|
||||||
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
||||||
Slic3r::Point v_seg_prev = p0.vector_to(p1);
|
Slic3r::Point v_seg_prev = p1 - p0;
|
||||||
int64_t t2_pt = int64_t(v_seg_prev.x()) * int64_t(v_pt.x()) + int64_t(v_seg_prev.y()) * int64_t(v_pt.y());
|
int64_t t2_pt = int64_t(v_seg_prev.x()) * int64_t(v_pt.x()) + int64_t(v_seg_prev.y()) * int64_t(v_pt.y());
|
||||||
if (t2_pt > 0) {
|
if (t2_pt > 0) {
|
||||||
// Inside the wedge between the previous and the next segment.
|
// Inside the wedge between the previous and the next segment.
|
||||||
|
@ -1164,8 +1164,8 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
|
||||||
// End points of the line segment.
|
// End points of the line segment.
|
||||||
const Slic3r::Point &p1 = pts[ipt];
|
const Slic3r::Point &p1 = pts[ipt];
|
||||||
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
||||||
Slic3r::Point v_seg = p1.vector_to(p2);
|
Slic3r::Point v_seg = p2 - p1;
|
||||||
Slic3r::Point v_pt = p1.vector_to(pt);
|
Slic3r::Point v_pt = pt - p1;
|
||||||
// dot(p2-p1, pt-p1)
|
// dot(p2-p1, pt-p1)
|
||||||
int64_t t_pt = int64_t(v_seg.x()) * int64_t(v_pt.x()) + int64_t(v_seg.y()) * int64_t(v_pt.y());
|
int64_t t_pt = int64_t(v_seg.x()) * int64_t(v_pt.x()) + int64_t(v_seg.y()) * int64_t(v_pt.y());
|
||||||
// l2 of seg
|
// l2 of seg
|
||||||
|
@ -1176,7 +1176,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
|
||||||
if (dabs < d_min) {
|
if (dabs < d_min) {
|
||||||
// Previous point.
|
// Previous point.
|
||||||
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
||||||
Slic3r::Point v_seg_prev = p0.vector_to(p1);
|
Slic3r::Point v_seg_prev = p1 - p0;
|
||||||
int64_t t2_pt = int64_t(v_seg_prev.x()) * int64_t(v_pt.x()) + int64_t(v_seg_prev.y()) * int64_t(v_pt.y());
|
int64_t t2_pt = int64_t(v_seg_prev.x()) * int64_t(v_pt.x()) + int64_t(v_seg_prev.y()) * int64_t(v_pt.y());
|
||||||
if (t2_pt > 0) {
|
if (t2_pt > 0) {
|
||||||
// Inside the wedge between the previous and the next segment.
|
// Inside the wedge between the previous and the next segment.
|
||||||
|
|
|
@ -34,54 +34,43 @@ ExPolygon::operator Polylines() const
|
||||||
return to_polylines(*this);
|
return to_polylines(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExPolygon::scale(double factor)
|
||||||
ExPolygon::scale(double factor)
|
|
||||||
{
|
{
|
||||||
contour.scale(factor);
|
contour.scale(factor);
|
||||||
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
|
for (Polygon &hole : holes)
|
||||||
(*it).scale(factor);
|
hole.scale(factor);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExPolygon::translate(double x, double y)
|
||||||
ExPolygon::translate(double x, double y)
|
|
||||||
{
|
{
|
||||||
contour.translate(x, y);
|
contour.translate(x, y);
|
||||||
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
|
for (Polygon &hole : holes)
|
||||||
(*it).translate(x, y);
|
hole.translate(x, y);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExPolygon::rotate(double angle)
|
||||||
ExPolygon::rotate(double angle)
|
|
||||||
{
|
{
|
||||||
contour.rotate(angle);
|
contour.rotate(angle);
|
||||||
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
|
for (Polygon &hole : holes)
|
||||||
(*it).rotate(angle);
|
hole.rotate(angle);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void ExPolygon::rotate(double angle, const Point ¢er)
|
||||||
ExPolygon::rotate(double angle, const Point ¢er)
|
|
||||||
{
|
{
|
||||||
contour.rotate(angle, center);
|
contour.rotate(angle, center);
|
||||||
for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
|
for (Polygon &hole : holes)
|
||||||
(*it).rotate(angle, center);
|
hole.rotate(angle, center);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double ExPolygon::area() const
|
||||||
ExPolygon::area() const
|
|
||||||
{
|
{
|
||||||
double a = this->contour.area();
|
double a = this->contour.area();
|
||||||
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
|
for (const Polygon &hole : holes)
|
||||||
a -= -(*it).area(); // holes have negative area
|
a -= - hole.area(); // holes have negative area
|
||||||
}
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool ExPolygon::is_valid() const
|
||||||
ExPolygon::is_valid() const
|
|
||||||
{
|
{
|
||||||
if (!this->contour.is_valid() || !this->contour.is_counter_clockwise()) return false;
|
if (!this->contour.is_valid() || !this->contour.is_counter_clockwise()) return false;
|
||||||
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
|
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
|
||||||
|
@ -90,20 +79,17 @@ ExPolygon::is_valid() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool ExPolygon::contains(const Line &line) const
|
||||||
ExPolygon::contains(const Line &line) const
|
|
||||||
{
|
{
|
||||||
return this->contains((Polyline)line);
|
return this->contains(Polyline(line.a, line.b));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool ExPolygon::contains(const Polyline &polyline) const
|
||||||
ExPolygon::contains(const Polyline &polyline) const
|
|
||||||
{
|
{
|
||||||
return diff_pl((Polylines)polyline, *this).empty();
|
return diff_pl((Polylines)polyline, *this).empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool ExPolygon::contains(const Polylines &polylines) const
|
||||||
ExPolygon::contains(const Polylines &polylines) const
|
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
BoundingBox bbox = get_extents(polylines);
|
BoundingBox bbox = get_extents(polylines);
|
||||||
|
@ -120,8 +106,7 @@ ExPolygon::contains(const Polylines &polylines) const
|
||||||
return pl_out.empty();
|
return pl_out.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool ExPolygon::contains(const Point &point) const
|
||||||
ExPolygon::contains(const Point &point) const
|
|
||||||
{
|
{
|
||||||
if (!this->contour.contains(point)) return false;
|
if (!this->contour.contains(point)) return false;
|
||||||
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
|
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
|
||||||
|
@ -131,8 +116,7 @@ ExPolygon::contains(const Point &point) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// inclusive version of contains() that also checks whether point is on boundaries
|
// inclusive version of contains() that also checks whether point is on boundaries
|
||||||
bool
|
bool ExPolygon::contains_b(const Point &point) const
|
||||||
ExPolygon::contains_b(const Point &point) const
|
|
||||||
{
|
{
|
||||||
return this->contains(point) || this->has_boundary_point(point);
|
return this->contains(point) || this->has_boundary_point(point);
|
||||||
}
|
}
|
||||||
|
@ -243,25 +227,24 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl
|
||||||
Point new_front = polyline.points.front();
|
Point new_front = polyline.points.front();
|
||||||
Point new_back = polyline.points.back();
|
Point new_back = polyline.points.back();
|
||||||
if (polyline.endpoints.first && !this->has_boundary_point(new_front)) {
|
if (polyline.endpoints.first && !this->has_boundary_point(new_front)) {
|
||||||
Line line(polyline.points.front(), polyline.points[1]);
|
Vec2d p1 = polyline.points.front().cast<double>();
|
||||||
|
Vec2d p2 = polyline.points[1].cast<double>();
|
||||||
// prevent the line from touching on the other side, otherwise intersection() might return that solution
|
// prevent the line from touching on the other side, otherwise intersection() might return that solution
|
||||||
if (polyline.points.size() == 2) line.b = line.midpoint();
|
if (polyline.points.size() == 2)
|
||||||
|
p2 = (p1 + p2) * 0.5;
|
||||||
line.extend_start(max_width);
|
// Extend the start of the segment.
|
||||||
(void)this->contour.intersection(line, &new_front);
|
p1 -= (p2 - p1).normalized() * max_width;
|
||||||
|
this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_front);
|
||||||
}
|
}
|
||||||
if (polyline.endpoints.second && !this->has_boundary_point(new_back)) {
|
if (polyline.endpoints.second && !this->has_boundary_point(new_back)) {
|
||||||
Line line(
|
Vec2d p1 = (polyline.points.end() - 2)->cast<double>();
|
||||||
*(polyline.points.end() - 2),
|
Vec2d p2 = polyline.points.back().cast<double>();
|
||||||
polyline.points.back()
|
|
||||||
);
|
|
||||||
|
|
||||||
// prevent the line from touching on the other side, otherwise intersection() might return that solution
|
// prevent the line from touching on the other side, otherwise intersection() might return that solution
|
||||||
if (polyline.points.size() == 2) line.a = line.midpoint();
|
if (polyline.points.size() == 2)
|
||||||
line.extend_end(max_width);
|
p1 = (p1 + p2) * 0.5;
|
||||||
|
// Extend the start of the segment.
|
||||||
(void)this->contour.intersection(line, &new_back);
|
p2 += (p2 - p1).normalized() * max_width;
|
||||||
|
this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_back);
|
||||||
}
|
}
|
||||||
polyline.points.front() = new_front;
|
polyline.points.front() = new_front;
|
||||||
polyline.points.back() = new_back;
|
polyline.points.back() = new_back;
|
||||||
|
|
|
@ -220,7 +220,7 @@ void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang)
|
||||||
double min_non_overhang = std::numeric_limits<double>::max();
|
double min_non_overhang = std::numeric_limits<double>::max();
|
||||||
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
|
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
|
||||||
Point p_tmp = point.projection_onto(path->polyline);
|
Point p_tmp = point.projection_onto(path->polyline);
|
||||||
double dist = point.distance_to(p_tmp);
|
double dist = (p_tmp - point).cast<double>().norm();
|
||||||
if (dist < min) {
|
if (dist < min) {
|
||||||
p = p_tmp;
|
p = p_tmp;
|
||||||
min = dist;
|
min = dist;
|
||||||
|
|
|
@ -50,10 +50,15 @@ public:
|
||||||
src.clear();
|
src.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void append(const ExtrusionPaths &paths) {
|
void append(const ExtrusionPaths &paths) {
|
||||||
this->entities.reserve(this->entities.size() + paths.size());
|
this->entities.reserve(this->entities.size() + paths.size());
|
||||||
for (ExtrusionPaths::const_iterator path = paths.begin(); path != paths.end(); ++path)
|
for (const ExtrusionPath &path : paths)
|
||||||
this->entities.push_back(path->clone());
|
this->entities.emplace_back(path.clone());
|
||||||
|
}
|
||||||
|
void append(ExtrusionPaths &&paths) {
|
||||||
|
this->entities.reserve(this->entities.size() + paths.size());
|
||||||
|
for (ExtrusionPath &path : paths)
|
||||||
|
this->entities.emplace_back(new ExtrusionPath(std::move(path)));
|
||||||
}
|
}
|
||||||
void replace(size_t i, const ExtrusionEntity &entity);
|
void replace(size_t i, const ExtrusionEntity &entity);
|
||||||
void remove(size_t i);
|
void remove(size_t i);
|
||||||
|
|
|
@ -187,7 +187,7 @@ void Fill3DHoneycomb::_fill_surface_single(
|
||||||
const Point &last_point = pts_end.back();
|
const Point &last_point = pts_end.back();
|
||||||
// TODO: we should also check that both points are on a fill_boundary to avoid
|
// TODO: we should also check that both points are on a fill_boundary to avoid
|
||||||
// connecting paths on the boundaries of internal regions
|
// connecting paths on the boundaries of internal regions
|
||||||
if (first_point.distance_to(last_point) <= 1.5 * distance &&
|
if ((last_point - first_point).cast<double>().norm() <= 1.5 * distance &&
|
||||||
expolygon_off.contains(Line(last_point, first_point))) {
|
expolygon_off.contains(Line(last_point, first_point))) {
|
||||||
// Append the polyline.
|
// Append the polyline.
|
||||||
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
|
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
|
||||||
|
|
|
@ -49,7 +49,7 @@ static inline Polyline make_wave(
|
||||||
point.y() = clamp(0., height, double(point.y()));
|
point.y() = clamp(0., height, double(point.y()));
|
||||||
if (vertical)
|
if (vertical)
|
||||||
std::swap(point.x(), point.y());
|
std::swap(point.x(), point.y());
|
||||||
polyline.points.emplace_back(convert_to<Point>(point * scaleFactor));
|
polyline.points.emplace_back((point * scaleFactor).cast<coord_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return polyline;
|
return polyline;
|
||||||
|
@ -177,7 +177,7 @@ void FillGyroid::_fill_surface_single(
|
||||||
// TODO: we should also check that both points are on a fill_boundary to avoid
|
// TODO: we should also check that both points are on a fill_boundary to avoid
|
||||||
// connecting paths on the boundaries of internal regions
|
// connecting paths on the boundaries of internal regions
|
||||||
// TODO: avoid crossing current infill path
|
// TODO: avoid crossing current infill path
|
||||||
if (first_point.distance_to(last_point) <= 5 * distance &&
|
if ((last_point - first_point).cast<double>().norm() <= 5 * distance &&
|
||||||
expolygon_off.contains(Line(last_point, first_point))) {
|
expolygon_off.contains(Line(last_point, first_point))) {
|
||||||
// Append the polyline.
|
// Append the polyline.
|
||||||
pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
|
pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
|
||||||
|
|
|
@ -101,7 +101,7 @@ void FillHoneycomb::_fill_surface_single(
|
||||||
for (Polylines::iterator it_path = chained.begin(); it_path != chained.end(); ++ it_path) {
|
for (Polylines::iterator it_path = chained.begin(); it_path != chained.end(); ++ it_path) {
|
||||||
if (! paths.empty()) {
|
if (! paths.empty()) {
|
||||||
// distance between first point of this path and last point of last path
|
// distance between first point of this path and last point of last path
|
||||||
double distance = paths.back().last_point().distance_to(it_path->first_point());
|
double distance = (it_path->first_point() - paths.back().last_point()).cast<double>().norm();
|
||||||
if (distance <= m.hex_width) {
|
if (distance <= m.hex_width) {
|
||||||
paths.back().points.insert(paths.back().points.end(), it_path->points.begin(), it_path->points.end());
|
paths.back().points.insert(paths.back().points.end(), it_path->points.begin(), it_path->points.end());
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -103,7 +103,7 @@ void FillRectilinear::_fill_surface_single(
|
||||||
const Point &first_point = it_polyline->points.front();
|
const Point &first_point = it_polyline->points.front();
|
||||||
const Point &last_point = pts_end.back();
|
const Point &last_point = pts_end.back();
|
||||||
// Distance in X, Y.
|
// Distance in X, Y.
|
||||||
const Vector distance = first_point.vector_to(last_point);
|
const Vector distance = last_point - first_point;
|
||||||
// TODO: we should also check that both points are on a fill_boundary to avoid
|
// TODO: we should also check that both points are on a fill_boundary to avoid
|
||||||
// connecting paths on the boundaries of internal regions
|
// connecting paths on the boundaries of internal regions
|
||||||
if (this->_can_connect(std::abs(distance.x()), std::abs(distance.y())) &&
|
if (this->_can_connect(std::abs(distance.x()), std::abs(distance.y())) &&
|
||||||
|
|
|
@ -55,14 +55,14 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
|
||||||
coordf_t len = 0;
|
coordf_t len = 0;
|
||||||
if (seg1 <= seg2) {
|
if (seg1 <= seg2) {
|
||||||
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
|
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
|
||||||
len += pPrev->distance_to(*(pThis = &poly.points[i]));
|
len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
|
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
|
||||||
len += pPrev->distance_to(*(pThis = &poly.points[i]));
|
len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
|
||||||
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
|
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
|
||||||
len += pPrev->distance_to(*(pThis = &poly.points[i]));
|
len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
|
||||||
}
|
}
|
||||||
len += pPrev->distance_to(p2);
|
len += (*pPrev - p2).cast<double>().norm();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,11 +217,11 @@ Point SegmentIntersection::pos() const
|
||||||
const Point &seg_start = poly.points[(this->iSegment == 0) ? poly.points.size() - 1 : this->iSegment - 1];
|
const Point &seg_start = poly.points[(this->iSegment == 0) ? poly.points.size() - 1 : this->iSegment - 1];
|
||||||
const Point &seg_end = poly.points[this->iSegment];
|
const Point &seg_end = poly.points[this->iSegment];
|
||||||
// Point, vector of the segment.
|
// Point, vector of the segment.
|
||||||
const Pointf p1 = convert_to<Pointf>(seg_start);
|
const Pointf p1(seg_start.cast<coordf_t>());
|
||||||
const Pointf v1 = convert_to<Pointf>(seg_end - seg_start);
|
const Pointf v1((seg_end - seg_start).cast<coordf_t>());
|
||||||
// Point, vector of this hatching line.
|
// Point, vector of this hatching line.
|
||||||
const Pointf p2 = convert_to<Pointf>(line->pos);
|
const Pointf p2(line->pos.cast<coordf_t>());
|
||||||
const Pointf v2 = convert_to<Pointf>(line->dir);
|
const Pointf v2(line->dir.cast<coordf_t>());
|
||||||
// Intersect the two rays.
|
// Intersect the two rays.
|
||||||
double denom = v1.x() * v2.y() - v2.x() * v1.y();
|
double denom = v1.x() * v2.y() - v2.x() * v1.y();
|
||||||
Point out;
|
Point out;
|
||||||
|
@ -276,13 +276,13 @@ int SegmentIntersection::ordering_along_line(const SegmentIntersection &other) c
|
||||||
// other.iSegment succeeds this->iSegment
|
// other.iSegment succeeds this->iSegment
|
||||||
assert(seg_end_a == seg_start_b);
|
assert(seg_end_a == seg_start_b);
|
||||||
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
|
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
|
||||||
if (cross(this->line->dir, seg_end_b - this->line->pos) == 0)
|
if (cross2(Vec2i64(this->line->dir.cast<int64_t>()), (seg_end_b - this->line->pos).cast<int64_t>()) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
} else if ((other.iSegment + 1) % poly_a.points.size() == this->iSegment) {
|
} else if ((other.iSegment + 1) % poly_a.points.size() == this->iSegment) {
|
||||||
// this->iSegment succeeds other.iSegment
|
// this->iSegment succeeds other.iSegment
|
||||||
assert(seg_start_a == seg_end_b);
|
assert(seg_start_a == seg_end_b);
|
||||||
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
|
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
|
||||||
if (cross(this->line->dir, seg_start_a - this->line->pos) == 0)
|
if (cross2(Vec2i64(this->line->dir.cast<int64_t>()), (seg_start_a - this->line->pos).cast<int64_t>()) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// General case.
|
// General case.
|
||||||
|
@ -290,35 +290,35 @@ int SegmentIntersection::ordering_along_line(const SegmentIntersection &other) c
|
||||||
}
|
}
|
||||||
|
|
||||||
// First test, whether both points of one segment are completely in one half-plane of the other line.
|
// First test, whether both points of one segment are completely in one half-plane of the other line.
|
||||||
const Point vec_b = seg_end_b - seg_start_b;
|
const Vec2i64 vec_b = (seg_end_b - seg_start_b).cast<int64_t>();
|
||||||
int side_start = signum(cross(vec_b, seg_start_a - seg_start_b));
|
int side_start = signum(cross2(vec_b, (seg_start_a - seg_start_b).cast<int64_t>()));
|
||||||
int side_end = signum(cross(vec_b, seg_end_a - seg_start_b));
|
int side_end = signum(cross2(vec_b, (seg_end_a - seg_start_b).cast<int64_t>()));
|
||||||
int side = side_start * side_end;
|
int side = side_start * side_end;
|
||||||
if (side > 0)
|
if (side > 0)
|
||||||
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
|
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
|
||||||
return signum(cross(vec_b, this->line->dir)) * side_start;
|
return signum(cross2(vec_b, this->line->dir.cast<int64_t>())) * side_start;
|
||||||
|
|
||||||
const Point vec_a = seg_end_a - seg_start_a;
|
const Vec2i64 vec_a = (seg_end_a - seg_start_a).cast<int64_t>();
|
||||||
int side_start2 = signum(cross(vec_a, seg_start_b - seg_start_a));
|
int side_start2 = signum(cross2(vec_a, (seg_start_b - seg_start_a).cast<int64_t>()));
|
||||||
int side_end2 = signum(cross(vec_a, seg_end_b - seg_start_a));
|
int side_end2 = signum(cross2(vec_a, (seg_end_b - seg_start_a).cast<int64_t>()));
|
||||||
int side2 = side_start2 * side_end2;
|
int side2 = side_start2 * side_end2;
|
||||||
//if (side == 0 && side2 == 0)
|
//if (side == 0 && side2 == 0)
|
||||||
// The segments share one of their end points.
|
// The segments share one of their end points.
|
||||||
if (side2 > 0)
|
if (side2 > 0)
|
||||||
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
|
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
|
||||||
return signum(cross(this->line->dir, vec_a)) * side_start2;
|
return signum(cross2(this->line->dir.cast<int64_t>(), vec_a)) * side_start2;
|
||||||
|
|
||||||
// The two segments intersect and they are not sucessive segments of the same contour.
|
// The two segments intersect and they are not sucessive segments of the same contour.
|
||||||
// Ordering of the points depends on the position of the segment intersection (left / right from this->line),
|
// Ordering of the points depends on the position of the segment intersection (left / right from this->line),
|
||||||
// therefore a simple test over the input segment end points is not sufficient.
|
// therefore a simple test over the input segment end points is not sufficient.
|
||||||
|
|
||||||
// Find the parameters of intersection of the two segmetns with this->line.
|
// Find the parameters of intersection of the two segmetns with this->line.
|
||||||
int64_t denom1 = cross(this->line->dir, vec_a);
|
int64_t denom1 = cross2(this->line->dir.cast<int64_t>(), vec_a);
|
||||||
int64_t denom2 = cross(this->line->dir, vec_b);
|
int64_t denom2 = cross2(this->line->dir.cast<int64_t>(), vec_b);
|
||||||
Point vx_a = seg_start_a - this->line->pos;
|
Vec2i64 vx_a = (seg_start_a - this->line->pos).cast<int64_t>();
|
||||||
Point vx_b = seg_start_b - this->line->pos;
|
Vec2i64 vx_b = (seg_start_b - this->line->pos).cast<int64_t>();
|
||||||
int64_t t1_times_denom1 = int64_t(vx_a.x()) * int64_t(vec_a.y()) - int64_t(vx_a.y()) * int64_t(vec_a.x());
|
int64_t t1_times_denom1 = vx_a.x() * vec_a.y() - vx_a.y() * vec_a.x();
|
||||||
int64_t t2_times_denom2 = int64_t(vx_b.x()) * int64_t(vec_b.y()) - int64_t(vx_b.y()) * int64_t(vec_b.x());
|
int64_t t2_times_denom2 = vx_b.x() * vec_b.y() - vx_b.y() * vec_b.x();
|
||||||
assert(denom1 != 0);
|
assert(denom1 != 0);
|
||||||
assert(denom2 != 0);
|
assert(denom2 != 0);
|
||||||
return Int128::compare_rationals_filtered(t1_times_denom1, denom1, t2_times_denom2, denom2);
|
return Int128::compare_rationals_filtered(t1_times_denom1, denom1, t2_times_denom2, denom2);
|
||||||
|
@ -330,7 +330,7 @@ bool SegmentIntersection::operator<(const SegmentIntersection &other) const
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Point p1 = this->pos();
|
Point p1 = this->pos();
|
||||||
Point p2 = other.pos();
|
Point p2 = other.pos();
|
||||||
int64_t d = dot(this->line->dir, p2 - p1);
|
int64_t d = this->line->dir.cast<int64_t>().dot((p2 - p1).cast<int64_t>());
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
int ordering = this->ordering_along_line(other);
|
int ordering = this->ordering_along_line(other);
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -510,7 +510,7 @@ static bool prepare_infill_hatching_segments(
|
||||||
for (size_t i = 1; i < sil.intersections.size(); ++ i) {
|
for (size_t i = 1; i < sil.intersections.size(); ++ i) {
|
||||||
Point p1 = sil.intersections[i - 1].pos();
|
Point p1 = sil.intersections[i - 1].pos();
|
||||||
Point p2 = sil.intersections[i].pos();
|
Point p2 = sil.intersections[i].pos();
|
||||||
int64_t d = dot(sil.dir, p2 - p1);
|
int64_t d = sil.dir.cast<int64_t>().dot((p2 - p1).cast<int64_t>());
|
||||||
assert(d >= - int64_t(SCALED_EPSILON));
|
assert(d >= - int64_t(SCALED_EPSILON));
|
||||||
}
|
}
|
||||||
#endif /* _DEBUG */
|
#endif /* _DEBUG */
|
||||||
|
@ -672,14 +672,14 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
|
||||||
coordf_t len = 0;
|
coordf_t len = 0;
|
||||||
if (seg1 <= seg2) {
|
if (seg1 <= seg2) {
|
||||||
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
|
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
|
||||||
len += pPrev->distance_to(*(pThis = &poly.points[i]));
|
len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
|
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
|
||||||
len += pPrev->distance_to(*(pThis = &poly.points[i]));
|
len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
|
||||||
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
|
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
|
||||||
len += pPrev->distance_to(*(pThis = &poly.points[i]));
|
len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
|
||||||
}
|
}
|
||||||
len += pPrev->distance_to(p2);
|
len += (*pPrev - p2).cast<double>().norm();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1191,7 +1191,7 @@ static bool fill_hatching_segments_legacy(
|
||||||
intrsctn.consumed_vertical_up :
|
intrsctn.consumed_vertical_up :
|
||||||
seg.intersections[i-1].consumed_vertical_up;
|
seg.intersections[i-1].consumed_vertical_up;
|
||||||
if (! consumed) {
|
if (! consumed) {
|
||||||
coordf_t dist2 = pointLast.distance_to(intrsctn.pos());
|
coordf_t dist2 = (intrsctn.pos() - pointLast).cast<double>().norm();
|
||||||
if (dist2 < dist2min) {
|
if (dist2 < dist2min) {
|
||||||
dist2min = dist2;
|
dist2min = dist2;
|
||||||
i_vline = i_vline2;
|
i_vline = i_vline2;
|
||||||
|
|
|
@ -53,7 +53,7 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
|
||||||
Polyline result = (use_external ? m_external_mp.get() : m_layer_mp.get())->
|
Polyline result = (use_external ? m_external_mp.get() : m_layer_mp.get())->
|
||||||
shortest_path(gcodegen.last_pos() + scaled_origin, point + scaled_origin);
|
shortest_path(gcodegen.last_pos() + scaled_origin, point + scaled_origin);
|
||||||
if (use_external)
|
if (use_external)
|
||||||
result.translate(scaled_origin.negative());
|
result.translate(- scaled_origin);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +681,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||||
for (const ExPolygon &expoly : layer->slices.expolygons)
|
for (const ExPolygon &expoly : layer->slices.expolygons)
|
||||||
for (const Point © : object->_shifted_copies) {
|
for (const Point © : object->_shifted_copies) {
|
||||||
islands.emplace_back(expoly.contour);
|
islands.emplace_back(expoly.contour);
|
||||||
islands.back().translate(copy);
|
islands.back().translate(- copy);
|
||||||
}
|
}
|
||||||
//FIXME Mege the islands in parallel.
|
//FIXME Mege the islands in parallel.
|
||||||
m_avoid_crossing_perimeters.init_external_mp(union_ex(islands));
|
m_avoid_crossing_perimeters.init_external_mp(union_ex(islands));
|
||||||
|
@ -699,7 +699,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
|
||||||
for (unsigned int extruder_id : print.extruders()) {
|
for (unsigned int extruder_id : print.extruders()) {
|
||||||
const Pointf &extruder_offset = print.config.extruder_offset.get_at(extruder_id);
|
const Pointf &extruder_offset = print.config.extruder_offset.get_at(extruder_id);
|
||||||
Polygon s(outer_skirt);
|
Polygon s(outer_skirt);
|
||||||
s.translate(-scale_(extruder_offset.x()), -scale_(extruder_offset.y()));
|
s.translate(Point::new_scale(- extruder_offset.x(), - extruder_offset.y()));
|
||||||
skirts.emplace_back(std::move(s));
|
skirts.emplace_back(std::move(s));
|
||||||
}
|
}
|
||||||
m_ooze_prevention.enable = true;
|
m_ooze_prevention.enable = true;
|
||||||
|
@ -1547,7 +1547,7 @@ void GCode::set_origin(const Pointf &pointf)
|
||||||
scale_(m_origin.x() - pointf.x()),
|
scale_(m_origin.x() - pointf.x()),
|
||||||
scale_(m_origin.y() - pointf.y())
|
scale_(m_origin.y() - pointf.y())
|
||||||
);
|
);
|
||||||
m_last_pos.translate(translate);
|
m_last_pos += translate;
|
||||||
m_wipe.path.translate(translate);
|
m_wipe.path.translate(translate);
|
||||||
m_origin = pointf;
|
m_origin = pointf;
|
||||||
}
|
}
|
||||||
|
@ -1678,8 +1678,8 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
|
||||||
j = 0;
|
j = 0;
|
||||||
const Point &p1 = polygon.points[i];
|
const Point &p1 = polygon.points[i];
|
||||||
const Point &p2 = polygon.points[j];
|
const Point &p2 = polygon.points[j];
|
||||||
const Slic3r::Point v_seg = p1.vector_to(p2);
|
const Slic3r::Point v_seg = p2 - p1;
|
||||||
const Slic3r::Point v_pt = p1.vector_to(pt);
|
const Slic3r::Point v_pt = pt - p1;
|
||||||
const int64_t l2_seg = int64_t(v_seg.x()) * int64_t(v_seg.x()) + int64_t(v_seg.y()) * int64_t(v_seg.y());
|
const int64_t l2_seg = int64_t(v_seg.x()) * int64_t(v_seg.x()) + int64_t(v_seg.y()) * int64_t(v_seg.y());
|
||||||
int64_t t_pt = int64_t(v_seg.x()) * int64_t(v_pt.x()) + int64_t(v_seg.y()) * int64_t(v_pt.y());
|
int64_t t_pt = int64_t(v_seg.x()) * int64_t(v_pt.x()) + int64_t(v_seg.y()) * int64_t(v_pt.y());
|
||||||
if (t_pt < 0) {
|
if (t_pt < 0) {
|
||||||
|
@ -1714,7 +1714,7 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(i_min != size_t(-1));
|
assert(i_min != size_t(-1));
|
||||||
if (pt_min.distance_to(polygon.points[i_min]) > eps) {
|
if ((pt_min - polygon.points[i_min]).cast<double>().norm() > eps) {
|
||||||
// Insert a new point on the segment i_min, i_min+1.
|
// Insert a new point on the segment i_min, i_min+1.
|
||||||
return polygon.points.insert(polygon.points.begin() + (i_min + 1), pt_min);
|
return polygon.points.insert(polygon.points.begin() + (i_min + 1), pt_min);
|
||||||
}
|
}
|
||||||
|
@ -1726,8 +1726,8 @@ std::vector<float> polygon_parameter_by_length(const Polygon &polygon)
|
||||||
// Parametrize the polygon by its length.
|
// Parametrize the polygon by its length.
|
||||||
std::vector<float> lengths(polygon.points.size()+1, 0.);
|
std::vector<float> lengths(polygon.points.size()+1, 0.);
|
||||||
for (size_t i = 1; i < polygon.points.size(); ++ i)
|
for (size_t i = 1; i < polygon.points.size(); ++ i)
|
||||||
lengths[i] = lengths[i-1] + float(polygon.points[i].distance_to(polygon.points[i-1]));
|
lengths[i] = lengths[i-1] + (polygon.points[i] - polygon.points[i-1]).cast<float>().norm();
|
||||||
lengths.back() = lengths[lengths.size()-2] + float(polygon.points.front().distance_to(polygon.points.back()));
|
lengths.back() = lengths[lengths.size()-2] + (polygon.points.front() - polygon.points.back()).cast<float>().norm();
|
||||||
return lengths;
|
return lengths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1775,8 +1775,8 @@ std::vector<float> polygon_angles_at_vertices(const Polygon &polygon, const std:
|
||||||
const Point &p0 = polygon.points[idx_prev];
|
const Point &p0 = polygon.points[idx_prev];
|
||||||
const Point &p1 = polygon.points[idx_curr];
|
const Point &p1 = polygon.points[idx_curr];
|
||||||
const Point &p2 = polygon.points[idx_next];
|
const Point &p2 = polygon.points[idx_next];
|
||||||
const Point v1 = p0.vector_to(p1);
|
const Point v1 = p1 - p0;
|
||||||
const Point v2 = p1.vector_to(p2);
|
const Point v2 = p2 - p1;
|
||||||
int64_t dot = int64_t(v1.x())*int64_t(v2.x()) + int64_t(v1.y())*int64_t(v2.y());
|
int64_t dot = int64_t(v1.x())*int64_t(v2.x()) + int64_t(v1.y())*int64_t(v2.y());
|
||||||
int64_t cross = int64_t(v1.x())*int64_t(v2.y()) - int64_t(v1.y())*int64_t(v2.x());
|
int64_t cross = int64_t(v1.x())*int64_t(v2.y()) - int64_t(v1.y())*int64_t(v2.x());
|
||||||
float angle = float(atan2(double(cross), double(dot)));
|
float angle = float(atan2(double(cross), double(dot)));
|
||||||
|
@ -2031,19 +2031,17 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
||||||
// create the destination point along the first segment and rotate it
|
// create the destination point along the first segment and rotate it
|
||||||
// we make sure we don't exceed the segment length because we don't know
|
// we make sure we don't exceed the segment length because we don't know
|
||||||
// the rotation of the second segment so we might cross the object boundary
|
// the rotation of the second segment so we might cross the object boundary
|
||||||
Line first_segment(
|
Vec2d p1 = paths.front().polyline.points.front().cast<double>();
|
||||||
paths.front().polyline.points[0],
|
Vec2d p2 = paths.front().polyline.points[1].cast<double>();
|
||||||
paths.front().polyline.points[1]
|
Vec2d v = p2 - p1;
|
||||||
);
|
double nd = scale_(EXTRUDER_CONFIG(nozzle_diameter));
|
||||||
double distance = std::min<double>(
|
double l2 = v.squaredNorm();
|
||||||
scale_(EXTRUDER_CONFIG(nozzle_diameter)),
|
// Shift by no more than a nozzle diameter.
|
||||||
first_segment.length()
|
//FIXME Hiding the seams will not work nicely for very densely discretized contours!
|
||||||
);
|
Point pt = ((nd * nd >= l2) ? p2 : (p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
|
||||||
Point point = first_segment.point_at(distance);
|
pt.rotate(angle, paths.front().polyline.points.front());
|
||||||
point.rotate(angle, first_segment.a);
|
|
||||||
|
|
||||||
// generate the travel move
|
// generate the travel move
|
||||||
gcode += m_writer.travel_to_xy(this->point_to_gcode(point), "move inwards before travel");
|
gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), "move inwards before travel");
|
||||||
}
|
}
|
||||||
|
|
||||||
return gcode;
|
return gcode;
|
||||||
|
|
|
@ -1042,12 +1042,12 @@ MedialAxis::validate_edge(const VD::edge_type* edge)
|
||||||
calculate the distance to that endpoint instead. */
|
calculate the distance to that endpoint instead. */
|
||||||
|
|
||||||
coordf_t w0 = cell_r->contains_segment()
|
coordf_t w0 = cell_r->contains_segment()
|
||||||
? line.a.distance_to(segment_r)*2
|
? segment_r.distance_to(line.a)*2
|
||||||
: line.a.distance_to(this->retrieve_endpoint(cell_r))*2;
|
: (this->retrieve_endpoint(cell_r) - line.a).cast<double>().norm()*2;
|
||||||
|
|
||||||
coordf_t w1 = cell_l->contains_segment()
|
coordf_t w1 = cell_l->contains_segment()
|
||||||
? line.b.distance_to(segment_l)*2
|
? segment_l.distance_to(line.b)*2
|
||||||
: line.b.distance_to(this->retrieve_endpoint(cell_l))*2;
|
: (this->retrieve_endpoint(cell_l) - line.b).cast<double>().norm()*2;
|
||||||
|
|
||||||
if (cell_l->contains_segment() && cell_r->contains_segment()) {
|
if (cell_l->contains_segment() && cell_r->contains_segment()) {
|
||||||
// calculate the relative angle between the two boundary segments
|
// calculate the relative angle between the two boundary segments
|
||||||
|
|
|
@ -7,8 +7,7 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
std::string
|
std::string Line::wkt() const
|
||||||
Line::wkt() const
|
|
||||||
{
|
{
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "LINESTRING(" << this->a.x() << " " << this->a.y() << ","
|
ss << "LINESTRING(" << this->a.x() << " " << this->a.y() << ","
|
||||||
|
@ -16,124 +15,58 @@ Line::wkt() const
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Line::operator Lines() const
|
bool Line::intersection_infinite(const Line &other, Point* point) const
|
||||||
{
|
{
|
||||||
Lines lines;
|
Vec2d a1 = this->a.cast<double>();
|
||||||
lines.push_back(*this);
|
Vec2d a2 = other.a.cast<double>();
|
||||||
return lines;
|
Vec2d v12 = (other.a - this->a).cast<double>();
|
||||||
}
|
Vec2d v1 = (this->b - this->a).cast<double>();
|
||||||
|
Vec2d v2 = (other.b - other.a).cast<double>();
|
||||||
Line::operator Polyline() const
|
double denom = cross2(v1, v2);
|
||||||
{
|
if (std::fabs(denom) < EPSILON)
|
||||||
Polyline pl;
|
|
||||||
pl.points.push_back(this->a);
|
|
||||||
pl.points.push_back(this->b);
|
|
||||||
return pl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Line::scale(double factor)
|
|
||||||
{
|
|
||||||
this->a.scale(factor);
|
|
||||||
this->b.scale(factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Line::translate(double x, double y)
|
|
||||||
{
|
|
||||||
this->a.translate(x, y);
|
|
||||||
this->b.translate(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Line::rotate(double angle, const Point ¢er)
|
|
||||||
{
|
|
||||||
this->a.rotate(angle, center);
|
|
||||||
this->b.rotate(angle, center);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Line::reverse()
|
|
||||||
{
|
|
||||||
std::swap(this->a, this->b);
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
Line::length() const
|
|
||||||
{
|
|
||||||
return this->a.distance_to(this->b);
|
|
||||||
}
|
|
||||||
|
|
||||||
Point
|
|
||||||
Line::midpoint() const
|
|
||||||
{
|
|
||||||
return Point((this->a.x() + this->b.x()) / 2.0, (this->a.y() + this->b.y()) / 2.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Line::point_at(double distance, Point* point) const
|
|
||||||
{
|
|
||||||
double len = this->length();
|
|
||||||
*point = this->a;
|
|
||||||
if (this->a.x() != this->b.x())
|
|
||||||
point->x() = this->a.x() + (this->b.x() - this->a.x()) * distance / len;
|
|
||||||
if (this->a.y() != this->b.y())
|
|
||||||
point->y() = this->a.y() + (this->b.y() - this->a.y()) * distance / len;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point
|
|
||||||
Line::point_at(double distance) const
|
|
||||||
{
|
|
||||||
Point p;
|
|
||||||
this->point_at(distance, &p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Line::intersection_infinite(const Line &other, Point* point) const
|
|
||||||
{
|
|
||||||
Vector x = this->a.vector_to(other.a);
|
|
||||||
Vector d1 = this->vector();
|
|
||||||
Vector d2 = other.vector();
|
|
||||||
|
|
||||||
double cross = d1.x() * d2.y() - d1.y() * d2.x();
|
|
||||||
if (std::fabs(cross) < EPSILON)
|
|
||||||
return false;
|
return false;
|
||||||
|
double t1 = cross2(v12, v2) / denom;
|
||||||
double t1 = (x.x() * d2.y() - x.y() * d2.x())/cross;
|
*point = (a1 + t1 * v1).cast<coord_t>();
|
||||||
point->x() = this->a.x() + d1.x() * t1;
|
|
||||||
point->y() = this->a.y() + d1.y() * t1;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
/* distance to the closest point of line */
|
||||||
Line::coincides_with(const Line &line) const
|
double Line::distance_to(const Point &point) const
|
||||||
{
|
{
|
||||||
return this->a == line.a && this->b == line.b;
|
const Line &line = *this;
|
||||||
|
const Vec2d v = (line.b - line.a).cast<double>();
|
||||||
|
const Vec2d va = (point - line.a).cast<double>();
|
||||||
|
const double l2 = v.squaredNorm(); // avoid a sqrt
|
||||||
|
if (l2 == 0.0)
|
||||||
|
// line.a == line.b case
|
||||||
|
return va.norm();
|
||||||
|
// Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
|
||||||
|
// We find projection of this point onto the line.
|
||||||
|
// It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
|
||||||
|
const double t = va.dot(v) / l2;
|
||||||
|
if (t < 0.0) return va.norm(); // beyond the 'a' end of the segment
|
||||||
|
else if (t > 1.0) return (point - line.b).cast<double>().norm(); // beyond the 'b' end of the segment
|
||||||
|
return (t * v - va).norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double Line::perp_distance_to(const Point &point) const
|
||||||
Line::distance_to(const Point &point) const
|
|
||||||
{
|
{
|
||||||
return point.distance_to(*this);
|
const Line &line = *this;
|
||||||
|
const Vec2d v = (line.b - line.a).cast<double>();
|
||||||
|
const Vec2d va = (point - line.a).cast<double>();
|
||||||
|
if (line.a == line.b)
|
||||||
|
return va.norm();
|
||||||
|
return std::abs(cross2(v, va)) / v.norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double Line::orientation() const
|
||||||
Line::atan2_() const
|
|
||||||
{
|
|
||||||
return atan2(this->b.y() - this->a.y(), this->b.x() - this->a.x());
|
|
||||||
}
|
|
||||||
|
|
||||||
double
|
|
||||||
Line::orientation() const
|
|
||||||
{
|
{
|
||||||
double angle = this->atan2_();
|
double angle = this->atan2_();
|
||||||
if (angle < 0) angle = 2*PI + angle;
|
if (angle < 0) angle = 2*PI + angle;
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double Line::direction() const
|
||||||
Line::direction() const
|
|
||||||
{
|
{
|
||||||
double atan2 = this->atan2_();
|
double atan2 = this->atan2_();
|
||||||
return (fabs(atan2 - PI) < EPSILON) ? 0
|
return (fabs(atan2 - PI) < EPSILON) ? 0
|
||||||
|
@ -141,105 +74,42 @@ Line::direction() const
|
||||||
: atan2;
|
: atan2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Line::parallel_to(double angle) const
|
||||||
Line::parallel_to(double angle) const {
|
{
|
||||||
return Slic3r::Geometry::directions_parallel(this->direction(), angle);
|
return Slic3r::Geometry::directions_parallel(this->direction(), angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Line::intersection(const Line &l2, Point *intersection) const
|
||||||
Line::parallel_to(const Line &line) const {
|
|
||||||
return this->parallel_to(line.direction());
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector
|
|
||||||
Line::vector() const
|
|
||||||
{
|
{
|
||||||
return Vector(this->b.x() - this->a.x(), this->b.y() - this->a.y());
|
const Line &l1 = *this;
|
||||||
}
|
const Vec2d v1 = (l1.b - l1.a).cast<double>();
|
||||||
|
const Vec2d v2 = (l2.b - l2.a).cast<double>();
|
||||||
Vector
|
const Vec2d v12 = (l1.a - l2.a).cast<double>();
|
||||||
Line::normal() const
|
double denom = cross2(v1, v2);
|
||||||
{
|
double nume_a = cross2(v2, v12);
|
||||||
return Vector((this->b.y() - this->a.y()), -(this->b.x() - this->a.x()));
|
double nume_b = cross2(v1, v12);
|
||||||
}
|
if (fabs(denom) < EPSILON)
|
||||||
|
#if 0
|
||||||
void
|
// Lines are collinear. Return true if they are coincident (overlappign).
|
||||||
Line::extend_end(double distance)
|
return ! (fabs(nume_a) < EPSILON && fabs(nume_b) < EPSILON);
|
||||||
{
|
#else
|
||||||
// relocate last point by extending the segment by the specified length
|
return false;
|
||||||
Line line = *this;
|
#endif
|
||||||
line.reverse();
|
double t1 = nume_a / denom;
|
||||||
this->b = line.point_at(-distance);
|
double t2 = nume_b / denom;
|
||||||
}
|
if (t1 >= 0 && t1 <= 1.0f && t2 >= 0 && t2 <= 1.0f) {
|
||||||
|
|
||||||
void
|
|
||||||
Line::extend_start(double distance)
|
|
||||||
{
|
|
||||||
// relocate first point by extending the first segment by the specified length
|
|
||||||
this->a = this->point_at(-distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Line::intersection(const Line& line, Point* intersection) const
|
|
||||||
{
|
|
||||||
double denom = ((double)(line.b.y() - line.a.y())*(this->b.x() - this->a.x())) -
|
|
||||||
((double)(line.b.x() - line.a.x())*(this->b.y() - this->a.y()));
|
|
||||||
|
|
||||||
double nume_a = ((double)(line.b.x() - line.a.x())*(this->a.y() - line.a.y())) -
|
|
||||||
((double)(line.b.y() - line.a.y())*(this->a.x() - line.a.x()));
|
|
||||||
|
|
||||||
double nume_b = ((double)(this->b.x() - this->a.x())*(this->a.y() - line.a.y())) -
|
|
||||||
((double)(this->b.y() - this->a.y())*(this->a.x() - line.a.x()));
|
|
||||||
|
|
||||||
if (fabs(denom) < EPSILON) {
|
|
||||||
if (fabs(nume_a) < EPSILON && fabs(nume_b) < EPSILON) {
|
|
||||||
return false; // coincident
|
|
||||||
}
|
|
||||||
return false; // parallel
|
|
||||||
}
|
|
||||||
|
|
||||||
double ua = nume_a / denom;
|
|
||||||
double ub = nume_b / denom;
|
|
||||||
|
|
||||||
if (ua >= 0 && ua <= 1.0f && ub >= 0 && ub <= 1.0f)
|
|
||||||
{
|
|
||||||
// Get the intersection point.
|
// Get the intersection point.
|
||||||
intersection->x() = this->a.x() + ua*(this->b.x() - this->a.x());
|
(*intersection) = (l1.a.cast<double>() + t1 * v1).cast<coord_t>();
|
||||||
intersection->y() = this->a.y() + ua*(this->b.y() - this->a.y());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // not intersecting
|
return false; // not intersecting
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
|
||||||
Line::ccw(const Point& point) const
|
|
||||||
{
|
|
||||||
return point.ccw(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Line3::length() const
|
|
||||||
{
|
|
||||||
return (b - a).norm();
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Line3::vector() const
|
|
||||||
{
|
|
||||||
return Vector3(b - a);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointf3 Linef3::intersect_plane(double z) const
|
Pointf3 Linef3::intersect_plane(double z) const
|
||||||
{
|
{
|
||||||
Vec3d v = this->b - this->a;
|
auto v = (this->b - this->a).cast<double>();
|
||||||
double t = (z - this->a.z()) / v.z();
|
double t = (z - this->a.z()) / v.z();
|
||||||
return Pointf3(this->a.x() + v.x() * t, this->a.y() + v.y() * t, z);
|
return Pointf3(this->a.x() + v.x() * t, this->a.y() + v.y() * t, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
Linef3::scale(double factor)
|
|
||||||
{
|
|
||||||
this->a.scale(factor);
|
|
||||||
this->b.scale(factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,77 +18,77 @@ typedef std::vector<ThickLine> ThickLines;
|
||||||
class Line
|
class Line
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Point a;
|
Line() {}
|
||||||
Point b;
|
explicit Line(Point _a, Point _b): a(_a), b(_b) {}
|
||||||
Line() {};
|
|
||||||
explicit Line(Point _a, Point _b): a(_a), b(_b) {};
|
|
||||||
std::string wkt() const;
|
std::string wkt() const;
|
||||||
operator Lines() const;
|
explicit operator Lines() const { Lines lines; lines.emplace_back(*this); return lines; }
|
||||||
operator Polyline() const;
|
void scale(double factor) { this->a *= factor; this->b *= factor; }
|
||||||
void scale(double factor);
|
void translate(double x, double y) { Vector v(x, y); this->a += v; this->b += v; }
|
||||||
void translate(double x, double y);
|
void rotate(double angle, const Point ¢er) { this->a.rotate(angle, center); this->b.rotate(angle, center); }
|
||||||
void rotate(double angle, const Point ¢er);
|
void reverse() { std::swap(this->a, this->b); }
|
||||||
void reverse();
|
double length() const { return (b - a).cast<double>().norm(); }
|
||||||
double length() const;
|
Point midpoint() const { return (this->a + this->b) / 2; }
|
||||||
Point midpoint() const;
|
bool intersection_infinite(const Line &other, Point* point) const;
|
||||||
void point_at(double distance, Point* point) const;
|
bool coincides_with(const Line &line) const { return this->a == line.a && this->b == line.b; }
|
||||||
Point point_at(double distance) const;
|
|
||||||
bool intersection_infinite(const Line &other, Point* point) const;
|
|
||||||
bool coincides_with(const Line &line) const;
|
|
||||||
double distance_to(const Point &point) const;
|
double distance_to(const Point &point) const;
|
||||||
bool parallel_to(double angle) const;
|
double perp_distance_to(const Point &point) const;
|
||||||
bool parallel_to(const Line &line) const;
|
bool parallel_to(double angle) const;
|
||||||
double atan2_() const;
|
bool parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
|
||||||
|
double atan2_() const { return atan2(this->b.y() - this->a.y(), this->b.x() - this->a.x()); }
|
||||||
double orientation() const;
|
double orientation() const;
|
||||||
double direction() const;
|
double direction() const;
|
||||||
Vector vector() const;
|
Vector vector() const { return this->b - this->a; }
|
||||||
Vector normal() const;
|
Vector normal() const { return Vector((this->b.y() - this->a.y()), -(this->b.x() - this->a.x())); }
|
||||||
void extend_end(double distance);
|
bool intersection(const Line& line, Point* intersection) const;
|
||||||
void extend_start(double distance);
|
double ccw(const Point& point) const { return point.ccw(*this); }
|
||||||
bool intersection(const Line& line, Point* intersection) const;
|
|
||||||
double ccw(const Point& point) const;
|
Point a;
|
||||||
|
Point b;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThickLine : public Line
|
class ThickLine : public Line
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
coordf_t a_width, b_width;
|
ThickLine() : a_width(0), b_width(0) {}
|
||||||
|
ThickLine(Point a, Point b) : Line(a, b), a_width(0), b_width(0) {}
|
||||||
ThickLine() : a_width(0), b_width(0) {};
|
ThickLine(Point a, Point b, double wa, double wb) : Line(a, b), a_width(wa), b_width(wb) {}
|
||||||
ThickLine(Point _a, Point _b) : Line(_a, _b), a_width(0), b_width(0) {};
|
|
||||||
|
coordf_t a_width, b_width;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Line3
|
class Line3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Point3 a;
|
|
||||||
Point3 b;
|
|
||||||
|
|
||||||
Line3() {}
|
Line3() {}
|
||||||
Line3(const Point3& _a, const Point3& _b) : a(_a), b(_b) {}
|
Line3(const Point3& _a, const Point3& _b) : a(_a), b(_b) {}
|
||||||
|
|
||||||
double length() const;
|
double length() const { return (this->a - this->b).cast<double>().norm(); }
|
||||||
Vector3 vector() const;
|
Vector3 vector() const { return this->b - this->a; }
|
||||||
|
|
||||||
|
Point3 a;
|
||||||
|
Point3 b;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Linef
|
class Linef
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Linef() {}
|
||||||
|
explicit Linef(Pointf _a, Pointf _b): a(_a), b(_b) {}
|
||||||
|
|
||||||
Pointf a;
|
Pointf a;
|
||||||
Pointf b;
|
Pointf b;
|
||||||
Linef() {};
|
|
||||||
explicit Linef(Pointf _a, Pointf _b): a(_a), b(_b) {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Linef3
|
class Linef3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Linef3() {}
|
||||||
|
explicit Linef3(Pointf3 _a, Pointf3 _b): a(_a), b(_b) {}
|
||||||
|
Pointf3 intersect_plane(double z) const;
|
||||||
|
void scale(double factor) { this->a *= factor; this->b *= factor; }
|
||||||
|
|
||||||
Pointf3 a;
|
Pointf3 a;
|
||||||
Pointf3 b;
|
Pointf3 b;
|
||||||
Linef3() {};
|
|
||||||
explicit Linef3(Pointf3 _a, Pointf3 _b): a(_a), b(_b) {};
|
|
||||||
Pointf3 intersect_plane(double z) const;
|
|
||||||
void scale(double factor);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -256,12 +256,10 @@ void Model::center_instances_around_point(const Pointf &point)
|
||||||
for (size_t i = 0; i < o->instances.size(); ++ i)
|
for (size_t i = 0; i < o->instances.size(); ++ i)
|
||||||
bb.merge(o->instance_bounding_box(i, false));
|
bb.merge(o->instance_bounding_box(i, false));
|
||||||
|
|
||||||
Sizef3 size = bb.size();
|
Pointf shift = point - 0.5 * bb.size().xy() - bb.min.xy();
|
||||||
coordf_t shift_x = -bb.min.x() + point.x() - size.x()/2;
|
|
||||||
coordf_t shift_y = -bb.min.y() + point.y() - size.y()/2;
|
|
||||||
for (ModelObject *o : this->objects) {
|
for (ModelObject *o : this->objects) {
|
||||||
for (ModelInstance *i : o->instances)
|
for (ModelInstance *i : o->instances)
|
||||||
i->offset.translate(shift_x, shift_y);
|
i->offset += shift;
|
||||||
o->invalidate_bounding_box();
|
o->invalidate_bounding_box();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,7 +683,7 @@ void Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb)
|
||||||
for (const ModelInstance *i : instances) {
|
for (const ModelInstance *i : instances) {
|
||||||
for (const Pointf &pos : positions) {
|
for (const Pointf &pos : positions) {
|
||||||
ModelInstance *instance = o->add_instance(*i);
|
ModelInstance *instance = o->add_instance(*i);
|
||||||
instance->offset.translate(pos);
|
instance->offset += pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o->invalidate_bounding_box();
|
o->invalidate_bounding_box();
|
||||||
|
@ -1075,16 +1073,15 @@ void ModelObject::center_around_origin()
|
||||||
vector.y() -= size.y()/2;
|
vector.y() -= size.y()/2;
|
||||||
|
|
||||||
this->translate(vector);
|
this->translate(vector);
|
||||||
this->origin_translation.translate(vector);
|
this->origin_translation += vector;
|
||||||
|
|
||||||
if (!this->instances.empty()) {
|
if (!this->instances.empty()) {
|
||||||
for (ModelInstance *i : this->instances) {
|
for (ModelInstance *i : this->instances) {
|
||||||
// apply rotation and scaling to vector as well before translating instance,
|
// apply rotation and scaling to vector as well before translating instance,
|
||||||
// in order to leave final position unaltered
|
// in order to leave final position unaltered
|
||||||
Vectorf v = vector.negative().xy();
|
Vectorf v = - vector.xy();
|
||||||
v.rotate(i->rotation);
|
v.rotate(i->rotation);
|
||||||
v.scale(i->scaling_factor);
|
i->offset += v * i->scaling_factor;
|
||||||
i->offset.translate(v);
|
|
||||||
}
|
}
|
||||||
this->invalidate_bounding_box();
|
this->invalidate_bounding_box();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
|
||||||
{
|
{
|
||||||
// If we have an empty configuration space, return a straight move.
|
// If we have an empty configuration space, return a straight move.
|
||||||
if (m_islands.empty())
|
if (m_islands.empty())
|
||||||
return Line(from, to);
|
return Polyline(from, to);
|
||||||
|
|
||||||
// Are both points in the same island?
|
// Are both points in the same island?
|
||||||
int island_idx_from = -1;
|
int island_idx_from = -1;
|
||||||
|
@ -74,7 +74,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
|
||||||
// Since both points are in the same island, is a direct move possible?
|
// Since both points are in the same island, is a direct move possible?
|
||||||
// If so, we avoid generating the visibility environment.
|
// If so, we avoid generating the visibility environment.
|
||||||
if (island.m_island.contains(Line(from, to)))
|
if (island.m_island.contains(Line(from, to)))
|
||||||
return Line(from, to);
|
return Polyline(from, to);
|
||||||
// Both points are inside a single island, but the straight line crosses the island boundary.
|
// Both points are inside a single island, but the straight line crosses the island boundary.
|
||||||
island_idx = idx;
|
island_idx = idx;
|
||||||
break;
|
break;
|
||||||
|
@ -90,7 +90,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
|
||||||
if (env.m_env.expolygons.empty()) {
|
if (env.m_env.expolygons.empty()) {
|
||||||
// if this environment is empty (probably because it's too small), perform straight move
|
// if this environment is empty (probably because it's too small), perform straight move
|
||||||
// and avoid running the algorithms on empty dataset
|
// and avoid running the algorithms on empty dataset
|
||||||
return Line(from, to);
|
return Polyline(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now check whether points are inside the environment.
|
// Now check whether points are inside the environment.
|
||||||
|
@ -224,7 +224,7 @@ const MotionPlannerGraph& MotionPlanner::init_graph(int island_idx)
|
||||||
else
|
else
|
||||||
v1_idx = i_v1->second;
|
v1_idx = i_v1->second;
|
||||||
// Euclidean distance is used as weight for the graph edge
|
// Euclidean distance is used as weight for the graph edge
|
||||||
graph->add_edge(v0_idx, v1_idx, p0.distance_to(p1));
|
graph->add_edge(v0_idx, v1_idx, (p1 - p0).cast<double>().norm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ static inline size_t nearest_waypoint_index(const Point &start_point, const Poin
|
||||||
size_t idx = size_t(-1);
|
size_t idx = size_t(-1);
|
||||||
double dmin = std::numeric_limits<double>::infinity();
|
double dmin = std::numeric_limits<double>::infinity();
|
||||||
for (const Point &p : middle_points) {
|
for (const Point &p : middle_points) {
|
||||||
double d = start_point.distance_to(p) + p.distance_to(end_point);
|
double d = (p - start_point).cast<double>().norm() + (end_point - p).cast<double>().norm();
|
||||||
if (d < dmin) {
|
if (d < dmin) {
|
||||||
idx = &p - middle_points.data();
|
idx = &p - middle_points.data();
|
||||||
dmin = d;
|
dmin = d;
|
||||||
|
|
|
@ -11,18 +11,20 @@ MultiPoint::operator Points() const
|
||||||
void MultiPoint::scale(double factor)
|
void MultiPoint::scale(double factor)
|
||||||
{
|
{
|
||||||
for (Point &pt : points)
|
for (Point &pt : points)
|
||||||
pt.scale(factor);
|
pt *= factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiPoint::translate(double x, double y)
|
void MultiPoint::translate(double x, double y)
|
||||||
{
|
{
|
||||||
|
Vector v(x, y);
|
||||||
for (Point &pt : points)
|
for (Point &pt : points)
|
||||||
pt.translate(x, y);
|
pt += v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiPoint::translate(const Point &vector)
|
void MultiPoint::translate(const Point &v)
|
||||||
{
|
{
|
||||||
this->translate(vector.x(), vector.y());
|
for (Point &pt : points)
|
||||||
|
pt += v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiPoint::rotate(double cos_angle, double sin_angle)
|
void MultiPoint::rotate(double cos_angle, double sin_angle)
|
||||||
|
@ -79,7 +81,7 @@ MultiPoint::find_point(const Point &point) const
|
||||||
bool
|
bool
|
||||||
MultiPoint::has_boundary_point(const Point &point) const
|
MultiPoint::has_boundary_point(const Point &point) const
|
||||||
{
|
{
|
||||||
double dist = point.distance_to(point.projection_onto(*this));
|
double dist = (point.projection_onto(*this) - point).cast<double>().norm();
|
||||||
return dist < SCALED_EPSILON;
|
return dist < SCALED_EPSILON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +139,10 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
|
||||||
if (l.intersection(line, &ip)) {
|
if (l.intersection(line, &ip)) {
|
||||||
if (! found) {
|
if (! found) {
|
||||||
found = true;
|
found = true;
|
||||||
dmin = ip.distance_to(line.a);
|
dmin = (line.a - ip).cast<double>().norm();
|
||||||
*intersection = ip;
|
*intersection = ip;
|
||||||
} else {
|
} else {
|
||||||
double d = ip.distance_to(line.a);
|
double d = (line.a - ip).cast<double>().norm();
|
||||||
if (d < dmin) {
|
if (d < dmin) {
|
||||||
dmin = d;
|
dmin = d;
|
||||||
*intersection = ip;
|
*intersection = ip;
|
||||||
|
@ -176,7 +178,7 @@ MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
|
||||||
Line full(points.front(), points.back());
|
Line full(points.front(), points.back());
|
||||||
for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
|
for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
|
||||||
// we use shortest distance, not perpendicular distance
|
// we use shortest distance, not perpendicular distance
|
||||||
double d = it->distance_to(full);
|
double d = full.distance_to(*it);
|
||||||
if (d > dmax) {
|
if (d > dmax) {
|
||||||
index = it - points.begin();
|
index = it - points.begin();
|
||||||
dmax = d;
|
dmax = d;
|
||||||
|
@ -215,7 +217,7 @@ void MultiPoint3::translate(double x, double y)
|
||||||
|
|
||||||
void MultiPoint3::translate(const Point& vector)
|
void MultiPoint3::translate(const Point& vector)
|
||||||
{
|
{
|
||||||
translate(vector.x(), vector.y());
|
this->translate(vector.x(), vector.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
double MultiPoint3::length() const
|
double MultiPoint3::length() const
|
||||||
|
|
|
@ -18,10 +18,11 @@ public:
|
||||||
Points points;
|
Points points;
|
||||||
|
|
||||||
operator Points() const;
|
operator Points() const;
|
||||||
MultiPoint() {};
|
MultiPoint() {}
|
||||||
MultiPoint(const MultiPoint &other) : points(other.points) {}
|
MultiPoint(const MultiPoint &other) : points(other.points) {}
|
||||||
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
|
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
|
||||||
explicit MultiPoint(const Points &_points): points(_points) {}
|
MultiPoint(std::initializer_list<Point> list) : points(list) {}
|
||||||
|
explicit MultiPoint(const Points &_points) : points(_points) {}
|
||||||
MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; }
|
MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; }
|
||||||
MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; }
|
MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; }
|
||||||
void scale(double factor);
|
void scale(double factor);
|
||||||
|
@ -43,9 +44,9 @@ public:
|
||||||
int idx = -1;
|
int idx = -1;
|
||||||
if (! this->points.empty()) {
|
if (! this->points.empty()) {
|
||||||
idx = 0;
|
idx = 0;
|
||||||
double dist_min = this->points.front().distance_to(point);
|
double dist_min = (point - this->points.front()).cast<double>().norm();
|
||||||
for (int i = 1; i < int(this->points.size()); ++ i) {
|
for (int i = 1; i < int(this->points.size()); ++ i) {
|
||||||
double d = this->points[i].distance_to(point);
|
double d = (this->points[i] - point).cast<double>().norm();
|
||||||
if (d < dist_min) {
|
if (d < dist_min) {
|
||||||
dist_min = d;
|
dist_min = d;
|
||||||
idx = i;
|
idx = i;
|
||||||
|
|
|
@ -366,99 +366,103 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
|
static inline ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, Flow &flow, const float tolerance)
|
||||||
{
|
{
|
||||||
// this value determines granularity of adaptive width, as G-code does not allow
|
ExtrusionPaths paths;
|
||||||
// variable extrusion within a single move; this value shall only affect the amount
|
ExtrusionPath path(role);
|
||||||
// of segments, and any pruning shall be performed before we apply this tolerance
|
ThickLines lines = thick_polyline.thicklines();
|
||||||
const double tolerance = scale_(0.05);
|
|
||||||
|
|
||||||
ExtrusionEntityCollection coll;
|
for (int i = 0; i < (int)lines.size(); ++i) {
|
||||||
for (const ThickPolyline &p : polylines) {
|
const ThickLine& line = lines[i];
|
||||||
ExtrusionPaths paths;
|
|
||||||
ExtrusionPath path(role);
|
|
||||||
ThickLines lines = p.thicklines();
|
|
||||||
|
|
||||||
for (int i = 0; i < (int)lines.size(); ++i) {
|
const coordf_t line_len = line.length();
|
||||||
const ThickLine& line = lines[i];
|
if (line_len < SCALED_EPSILON) continue;
|
||||||
|
|
||||||
const coordf_t line_len = line.length();
|
double thickness_delta = fabs(line.a_width - line.b_width);
|
||||||
if (line_len < SCALED_EPSILON) continue;
|
if (thickness_delta > tolerance) {
|
||||||
|
const unsigned short segments = ceil(thickness_delta / tolerance);
|
||||||
double thickness_delta = fabs(line.a_width - line.b_width);
|
const coordf_t seg_len = line_len / segments;
|
||||||
if (thickness_delta > tolerance) {
|
Points pp;
|
||||||
const unsigned short segments = ceil(thickness_delta / tolerance);
|
std::vector<coordf_t> width;
|
||||||
const coordf_t seg_len = line_len / segments;
|
{
|
||||||
Points pp;
|
pp.push_back(line.a);
|
||||||
std::vector<coordf_t> width;
|
width.push_back(line.a_width);
|
||||||
{
|
for (size_t j = 1; j < segments; ++j) {
|
||||||
pp.push_back(line.a);
|
pp.push_back((line.a.cast<double>() + (line.b - line.a).cast<double>().normalized() * (j * seg_len)).cast<coord_t>());
|
||||||
width.push_back(line.a_width);
|
|
||||||
for (size_t j = 1; j < segments; ++j) {
|
|
||||||
pp.push_back(line.point_at(j*seg_len));
|
|
||||||
|
|
||||||
coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
|
|
||||||
width.push_back(w);
|
|
||||||
width.push_back(w);
|
|
||||||
}
|
|
||||||
pp.push_back(line.b);
|
|
||||||
width.push_back(line.b_width);
|
|
||||||
|
|
||||||
assert(pp.size() == segments + 1);
|
coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
|
||||||
assert(width.size() == segments*2);
|
width.push_back(w);
|
||||||
|
width.push_back(w);
|
||||||
}
|
}
|
||||||
|
pp.push_back(line.b);
|
||||||
|
width.push_back(line.b_width);
|
||||||
|
|
||||||
// delete this line and insert new ones
|
assert(pp.size() == segments + 1);
|
||||||
lines.erase(lines.begin() + i);
|
assert(width.size() == segments*2);
|
||||||
for (size_t j = 0; j < segments; ++j) {
|
|
||||||
ThickLine new_line(pp[j], pp[j+1]);
|
|
||||||
new_line.a_width = width[2*j];
|
|
||||||
new_line.b_width = width[2*j+1];
|
|
||||||
lines.insert(lines.begin() + i + j, new_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
-- i;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const double w = fmax(line.a_width, line.b_width);
|
// delete this line and insert new ones
|
||||||
if (path.polyline.points.empty()) {
|
lines.erase(lines.begin() + i);
|
||||||
path.polyline.append(line.a);
|
for (size_t j = 0; j < segments; ++j) {
|
||||||
|
ThickLine new_line(pp[j], pp[j+1]);
|
||||||
|
new_line.a_width = width[2*j];
|
||||||
|
new_line.b_width = width[2*j+1];
|
||||||
|
lines.insert(lines.begin() + i + j, new_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
-- i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double w = fmax(line.a_width, line.b_width);
|
||||||
|
if (path.polyline.points.empty()) {
|
||||||
|
path.polyline.append(line.a);
|
||||||
|
path.polyline.append(line.b);
|
||||||
|
// Convert from spacing to extrusion width based on the extrusion model
|
||||||
|
// of a square extrusion ended with semi circles.
|
||||||
|
flow.width = unscale(w) + flow.height * (1. - 0.25 * PI);
|
||||||
|
#ifdef SLIC3R_DEBUG
|
||||||
|
printf(" filling %f gap\n", flow.width);
|
||||||
|
#endif
|
||||||
|
path.mm3_per_mm = flow.mm3_per_mm();
|
||||||
|
path.width = flow.width;
|
||||||
|
path.height = flow.height;
|
||||||
|
} else {
|
||||||
|
thickness_delta = fabs(scale_(flow.width) - w);
|
||||||
|
if (thickness_delta <= tolerance) {
|
||||||
|
// the width difference between this line and the current flow width is
|
||||||
|
// within the accepted tolerance
|
||||||
path.polyline.append(line.b);
|
path.polyline.append(line.b);
|
||||||
// Convert from spacing to extrusion width based on the extrusion model
|
|
||||||
// of a square extrusion ended with semi circles.
|
|
||||||
flow.width = unscale(w) + flow.height * (1. - 0.25 * PI);
|
|
||||||
#ifdef SLIC3R_DEBUG
|
|
||||||
printf(" filling %f gap\n", flow.width);
|
|
||||||
#endif
|
|
||||||
path.mm3_per_mm = flow.mm3_per_mm();
|
|
||||||
path.width = flow.width;
|
|
||||||
path.height = flow.height;
|
|
||||||
} else {
|
} else {
|
||||||
thickness_delta = fabs(scale_(flow.width) - w);
|
// we need to initialize a new line
|
||||||
if (thickness_delta <= tolerance) {
|
paths.emplace_back(std::move(path));
|
||||||
// the width difference between this line and the current flow width is
|
path = ExtrusionPath(role);
|
||||||
// within the accepted tolerance
|
-- i;
|
||||||
path.polyline.append(line.b);
|
|
||||||
} else {
|
|
||||||
// we need to initialize a new line
|
|
||||||
paths.emplace_back(std::move(path));
|
|
||||||
path = ExtrusionPath(role);
|
|
||||||
-- i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (path.polyline.is_valid())
|
}
|
||||||
paths.emplace_back(std::move(path));
|
if (path.polyline.is_valid())
|
||||||
|
paths.emplace_back(std::move(path));
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
|
||||||
|
{
|
||||||
|
// This value determines granularity of adaptive width, as G-code does not allow
|
||||||
|
// variable extrusion within a single move; this value shall only affect the amount
|
||||||
|
// of segments, and any pruning shall be performed before we apply this tolerance.
|
||||||
|
ExtrusionEntityCollection coll;
|
||||||
|
const double tolerance = scale_(0.05);
|
||||||
|
for (const ThickPolyline &p : polylines) {
|
||||||
|
ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance);
|
||||||
// Append paths to collection.
|
// Append paths to collection.
|
||||||
if (! paths.empty()) {
|
if (! paths.empty()) {
|
||||||
if (paths.front().first_point() == paths.back().last_point())
|
if (paths.front().first_point() == paths.back().last_point())
|
||||||
coll.append(ExtrusionLoop(paths));
|
coll.append(ExtrusionLoop(std::move(paths)));
|
||||||
else
|
else
|
||||||
coll.append(paths);
|
coll.append(std::move(paths));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return coll;
|
return coll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,38 +98,6 @@ bool Point::nearest_point(const Points &points, Point* point) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* distance to the closest point of line */
|
|
||||||
double Point::distance_to(const Line &line) const
|
|
||||||
{
|
|
||||||
const double dx = line.b.x() - line.a.x();
|
|
||||||
const double dy = line.b.y() - line.a.y();
|
|
||||||
|
|
||||||
const double l2 = dx*dx + dy*dy; // avoid a sqrt
|
|
||||||
if (l2 == 0.0) return this->distance_to(line.a); // line.a == line.b case
|
|
||||||
|
|
||||||
// Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
|
|
||||||
// We find projection of this point onto the line.
|
|
||||||
// It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
|
|
||||||
const double t = ((this->x() - line.a.x()) * dx + (this->y() - line.a.y()) * dy) / l2;
|
|
||||||
if (t < 0.0) return this->distance_to(line.a); // beyond the 'a' end of the segment
|
|
||||||
else if (t > 1.0) return this->distance_to(line.b); // beyond the 'b' end of the segment
|
|
||||||
Point projection(
|
|
||||||
line.a.x() + t * dx,
|
|
||||||
line.a.y() + t * dy
|
|
||||||
);
|
|
||||||
return this->distance_to(projection);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Point::perp_distance_to(const Line &line) const
|
|
||||||
{
|
|
||||||
if (line.a == line.b) return this->distance_to(line.a);
|
|
||||||
|
|
||||||
double n = (double)(line.b.x() - line.a.x()) * (double)(line.a.y() - this->y())
|
|
||||||
- (double)(line.a.x() - this->x()) * (double)(line.b.y() - line.a.y());
|
|
||||||
|
|
||||||
return std::abs(n) / line.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Three points are a counter-clockwise turn if ccw > 0, clockwise if
|
/* Three points are a counter-clockwise turn if ccw > 0, clockwise if
|
||||||
* ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
|
* ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
|
||||||
* gives the signed area of the triangle formed by p1, p2 and this point.
|
* gives the signed area of the triangle formed by p1, p2 and this point.
|
||||||
|
@ -161,14 +129,14 @@ double Point::ccw_angle(const Point &p1, const Point &p2) const
|
||||||
Point Point::projection_onto(const MultiPoint &poly) const
|
Point Point::projection_onto(const MultiPoint &poly) const
|
||||||
{
|
{
|
||||||
Point running_projection = poly.first_point();
|
Point running_projection = poly.first_point();
|
||||||
double running_min = this->distance_to(running_projection);
|
double running_min = (running_projection - *this).cast<double>().norm();
|
||||||
|
|
||||||
Lines lines = poly.lines();
|
Lines lines = poly.lines();
|
||||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
Point point_temp = this->projection_onto(*line);
|
Point point_temp = this->projection_onto(*line);
|
||||||
if (this->distance_to(point_temp) < running_min) {
|
if ((point_temp - *this).cast<double>().norm() < running_min) {
|
||||||
running_projection = point_temp;
|
running_projection = point_temp;
|
||||||
running_min = this->distance_to(running_projection);
|
running_min = (running_projection - *this).cast<double>().norm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return running_projection;
|
return running_projection;
|
||||||
|
@ -193,14 +161,10 @@ Point Point::projection_onto(const Line &line) const
|
||||||
/ ( sqr<double>(lx) + sqr<double>(ly) );
|
/ ( sqr<double>(lx) + sqr<double>(ly) );
|
||||||
|
|
||||||
if (0.0 <= theta && theta <= 1.0)
|
if (0.0 <= theta && theta <= 1.0)
|
||||||
return theta * line.a + (1.0-theta) * line.b;
|
return (theta * line.a.cast<coordf_t>() + (1.0-theta) * line.b.cast<coordf_t>()).cast<coord_t>();
|
||||||
|
|
||||||
// Else pick closest endpoint.
|
// Else pick closest endpoint.
|
||||||
if (this->distance_to(line.a) < this->distance_to(line.b)) {
|
return ((line.a - *this).cast<double>().squaredNorm() < (line.b - *this).cast<double>().squaredNorm()) ? line.a : line.b;
|
||||||
return line.a;
|
|
||||||
} else {
|
|
||||||
return line.b;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream &stm, const Pointf &pointf)
|
std::ostream& operator<<(std::ostream &stm, const Pointf &pointf)
|
||||||
|
|
|
@ -35,6 +35,8 @@ typedef std::vector<Pointf3> Pointf3s;
|
||||||
// Vector types with a fixed point coordinate base type.
|
// Vector types with a fixed point coordinate base type.
|
||||||
typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
|
typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
|
||||||
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
|
typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
|
||||||
|
typedef Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
|
||||||
|
typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
|
||||||
|
|
||||||
// Vector types with a double coordinate base type.
|
// Vector types with a double coordinate base type.
|
||||||
typedef Eigen::Matrix<float, 2, 1, Eigen::DontAlign> Vec2f;
|
typedef Eigen::Matrix<float, 2, 1, Eigen::DontAlign> Vec2f;
|
||||||
|
@ -47,6 +49,11 @@ typedef Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign> Transform2d
|
||||||
typedef Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign> Transform3f;
|
typedef Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign> Transform3f;
|
||||||
typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d;
|
typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d;
|
||||||
|
|
||||||
|
inline int64_t cross2(const Vec2i64 &v1, const Vec2i64 &v2) { return v1.x() * v2.y() - v1.y() * v2.x(); }
|
||||||
|
inline coord_t cross2(const Vec2crd &v1, const Vec2crd &v2) { return v1.x() * v2.y() - v1.y() * v2.x(); }
|
||||||
|
inline float cross2(const Vec2f &v1, const Vec2f &v2) { return v1.x() * v2.y() - v1.y() * v2.x(); }
|
||||||
|
inline double cross2(const Vec2d &v1, const Vec2d &v2) { return v1.x() * v2.y() - v1.y() * v2.x(); }
|
||||||
|
|
||||||
class Point : public Vec2crd
|
class Point : public Vec2crd
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -66,7 +73,7 @@ public:
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Point& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
Point& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
this->Point::operator=(other);
|
this->Vec2crd::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,51 +88,33 @@ public:
|
||||||
|
|
||||||
Point& operator+=(const Point& rhs) { this->x() += rhs.x(); this->y() += rhs.y(); return *this; }
|
Point& operator+=(const Point& rhs) { this->x() += rhs.x(); this->y() += rhs.y(); return *this; }
|
||||||
Point& operator-=(const Point& rhs) { this->x() -= rhs.x(); this->y() -= rhs.y(); return *this; }
|
Point& operator-=(const Point& rhs) { this->x() -= rhs.x(); this->y() -= rhs.y(); return *this; }
|
||||||
Point& operator*=(const coord_t& rhs) { this->x() *= rhs; this->y() *= rhs; return *this; }
|
Point& operator*=(const double &rhs) { this->x() *= rhs; this->y() *= rhs; return *this; }
|
||||||
|
|
||||||
std::string wkt() const;
|
std::string wkt() const;
|
||||||
std::string dump_perl() const;
|
std::string dump_perl() const;
|
||||||
void scale(double factor) { *this *= factor; }
|
|
||||||
void translate(double x, double y) { *this += Vector(x, y); }
|
|
||||||
void translate(const Vector &vector) { *this += vector; }
|
|
||||||
void rotate(double angle);
|
void rotate(double angle);
|
||||||
void rotate(double angle, const Point ¢er);
|
void rotate(double angle, const Point ¢er);
|
||||||
Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
|
Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
|
||||||
Point rotated(double angle, const Point ¢er) const { Point res(*this); res.rotate(angle, center); return res; }
|
Point rotated(double angle, const Point ¢er) const { Point res(*this); res.rotate(angle, center); return res; }
|
||||||
bool coincides_with(const Point &rhs) const { return *this == rhs; }
|
|
||||||
bool coincides_with_epsilon(const Point &point) const;
|
bool coincides_with_epsilon(const Point &point) const;
|
||||||
int nearest_point_index(const Points &points) const;
|
int nearest_point_index(const Points &points) const;
|
||||||
int nearest_point_index(const PointConstPtrs &points) const;
|
int nearest_point_index(const PointConstPtrs &points) const;
|
||||||
int nearest_point_index(const PointPtrs &points) const;
|
int nearest_point_index(const PointPtrs &points) const;
|
||||||
bool nearest_point(const Points &points, Point* point) const;
|
bool nearest_point(const Points &points, Point* point) const;
|
||||||
double distance_to(const Point &point) const { return (point - *this).norm(); }
|
|
||||||
double distance_to_sq(const Point &point) const { return (point - *this).squaredNorm(); }
|
|
||||||
double distance_to(const Line &line) const;
|
|
||||||
double perp_distance_to(const Line &line) const;
|
|
||||||
double ccw(const Point &p1, const Point &p2) const;
|
double ccw(const Point &p1, const Point &p2) const;
|
||||||
double ccw(const Line &line) const;
|
double ccw(const Line &line) const;
|
||||||
double ccw_angle(const Point &p1, const Point &p2) const;
|
double ccw_angle(const Point &p1, const Point &p2) const;
|
||||||
Point projection_onto(const MultiPoint &poly) const;
|
Point projection_onto(const MultiPoint &poly) const;
|
||||||
Point projection_onto(const Line &line) const;
|
Point projection_onto(const Line &line) const;
|
||||||
Point negative() const { return Point(- *this); }
|
|
||||||
Vector vector_to(const Point &point) const { return Vector(point - *this); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Point operator+(const Point& point1, const Point& point2) { return Point(point1.x() + point2.x(), point1.y() + point2.y()); }
|
|
||||||
inline Point operator-(const Point& point1, const Point& point2) { return Point(point1.x() - point2.x(), point1.y() - point2.y()); }
|
|
||||||
inline Point operator*(double scalar, const Point& point2) { return Point(scalar * point2.x(), scalar * point2.y()); }
|
|
||||||
inline int64_t cross(const Point &v1, const Point &v2) { return int64_t(v1.x()) * int64_t(v2.y()) - int64_t(v1.y()) * int64_t(v2.x()); }
|
|
||||||
inline int64_t dot(const Point &v1, const Point &v2) { return int64_t(v1.x()) * int64_t(v2.x()) + int64_t(v1.y()) * int64_t(v2.y()); }
|
|
||||||
|
|
||||||
namespace int128 {
|
namespace int128 {
|
||||||
|
// Exact orientation predicate,
|
||||||
// Exact orientation predicate,
|
// returns +1: CCW, 0: collinear, -1: CW.
|
||||||
// returns +1: CCW, 0: collinear, -1: CW.
|
int orient(const Point &p1, const Point &p2, const Point &p3);
|
||||||
int orient(const Point &p1, const Point &p2, const Point &p3);
|
// Exact orientation predicate,
|
||||||
|
// returns +1: CCW, 0: collinear, -1: CW.
|
||||||
// Exact orientation predicate,
|
int cross(const Point &v1, const Slic3r::Point &v2);
|
||||||
// returns +1: CCW, 0: collinear, -1: CW.
|
|
||||||
int cross(const Point &v1, const Slic3r::Point &v2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// To be used by std::unordered_map, std::unordered_multimap and friends.
|
// To be used by std::unordered_map, std::unordered_multimap and friends.
|
||||||
|
@ -204,7 +193,7 @@ public:
|
||||||
const ValueType &value = it->second;
|
const ValueType &value = it->second;
|
||||||
const Point *pt2 = m_point_accessor(value);
|
const Point *pt2 = m_point_accessor(value);
|
||||||
if (pt2 != nullptr) {
|
if (pt2 != nullptr) {
|
||||||
const double d2 = pt.distance_to_sq(*pt2);
|
const double d2 = (pt - *pt2).squaredNorm();
|
||||||
if (d2 < dist_min) {
|
if (d2 < dist_min) {
|
||||||
dist_min = d2;
|
dist_min = d2;
|
||||||
value_min = &value;
|
value_min = &value;
|
||||||
|
@ -243,7 +232,7 @@ public:
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Point3& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
Point3& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
this->Point3::operator=(other);
|
this->Vec3crd::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +257,6 @@ public:
|
||||||
typedef coordf_t coord_type;
|
typedef coordf_t coord_type;
|
||||||
|
|
||||||
explicit Pointf() { (*this)(0) = (*this)(1) = 0.; }
|
explicit Pointf() { (*this)(0) = (*this)(1) = 0.; }
|
||||||
// explicit Pointf(double x, double y) { (*this)(0) = x; (*this)(1) = y; }
|
|
||||||
explicit Pointf(coordf_t x, coordf_t y) { (*this)(0) = x; (*this)(1) = y; }
|
explicit Pointf(coordf_t x, coordf_t y) { (*this)(0) = x; (*this)(1) = y; }
|
||||||
// This constructor allows you to construct Pointf from Eigen expressions
|
// This constructor allows you to construct Pointf from Eigen expressions
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
@ -280,7 +268,7 @@ public:
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Pointf& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
Pointf& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
this->Pointf::operator=(other);
|
this->Vec2d::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,13 +279,8 @@ public:
|
||||||
|
|
||||||
std::string wkt() const;
|
std::string wkt() const;
|
||||||
std::string dump_perl() const;
|
std::string dump_perl() const;
|
||||||
void scale(double factor) { *this *= factor; }
|
|
||||||
void translate(double x, double y) { *this += Vec2d(x, y); }
|
|
||||||
void translate(const Vectorf &vector) { *this += vector; }
|
|
||||||
void rotate(double angle);
|
void rotate(double angle);
|
||||||
void rotate(double angle, const Pointf ¢er);
|
void rotate(double angle, const Pointf ¢er);
|
||||||
Pointf negative() const { return Pointf(- *this); }
|
|
||||||
Vectorf vector_to(const Pointf &point) const { return point - *this; }
|
|
||||||
Pointf& operator+=(const Pointf& rhs) { this->x() += rhs.x(); this->y() += rhs.y(); return *this; }
|
Pointf& operator+=(const Pointf& rhs) { this->x() += rhs.x(); this->y() += rhs.y(); return *this; }
|
||||||
Pointf& operator-=(const Pointf& rhs) { this->x() -= rhs.x(); this->y() -= rhs.y(); return *this; }
|
Pointf& operator-=(const Pointf& rhs) { this->x() -= rhs.x(); this->y() -= rhs.y(); return *this; }
|
||||||
Pointf& operator*=(const coordf_t& rhs) { this->x() *= rhs; this->y() *= rhs; return *this; }
|
Pointf& operator*=(const coordf_t& rhs) { this->x() *= rhs; this->y() *= rhs; return *this; }
|
||||||
|
@ -307,21 +290,6 @@ public:
|
||||||
bool operator< (const Pointf& rhs) const { return this->x() < rhs.x() || (this->x() == rhs.x() && this->y() < rhs.y()); }
|
bool operator< (const Pointf& rhs) const { return this->x() < rhs.x() || (this->x() == rhs.x() && this->y() < rhs.y()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Pointf operator+(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x() + point2.x(), point1.y() + point2.y()); }
|
|
||||||
inline Pointf operator-(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x() - point2.x(), point1.y() - point2.y()); }
|
|
||||||
inline Pointf operator*(double scalar, const Pointf& point2) { return Pointf(scalar * point2.x(), scalar * point2.y()); }
|
|
||||||
inline Pointf operator*(const Pointf& point2, double scalar) { return Pointf(scalar * point2.x(), scalar * point2.y()); }
|
|
||||||
inline coordf_t cross(const Pointf &v1, const Pointf &v2) { return v1.x() * v2.y() - v1.y() * v2.x(); }
|
|
||||||
inline coordf_t dot(const Pointf &v1, const Pointf &v2) { return v1.x() * v2.x() + v1.y() * v2.y(); }
|
|
||||||
inline coordf_t dot(const Pointf &v) { return v.x() * v.x() + v.y() * v.y(); }
|
|
||||||
inline double length(const Vectorf &v) { return sqrt(dot(v)); }
|
|
||||||
inline double l2(const Vectorf &v) { return dot(v); }
|
|
||||||
inline Vectorf normalize(const Vectorf& v)
|
|
||||||
{
|
|
||||||
coordf_t len = ::sqrt(sqr(v.x()) + sqr(v.y()));
|
|
||||||
return (len != 0.0) ? 1.0 / len * v : Vectorf(0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Pointf3 : public Vec3d
|
class Pointf3 : public Vec3d
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -340,7 +308,7 @@ public:
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
Pointf3& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
Pointf3& operator=(const Eigen::MatrixBase<OtherDerived> &other)
|
||||||
{
|
{
|
||||||
this->Pointf3::operator=(other);
|
this->Vec3d::operator=(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,40 +319,12 @@ public:
|
||||||
const coordf_t& z() const { return (*this)(2); }
|
const coordf_t& z() const { return (*this)(2); }
|
||||||
coordf_t& z() { return (*this)(2); }
|
coordf_t& z() { return (*this)(2); }
|
||||||
|
|
||||||
void scale(double factor) { *this *= factor; }
|
|
||||||
void translate(const Vectorf3 &vector) { *this += vector; }
|
|
||||||
void translate(double x, double y, double z) { *this += Vec3d(x, y, z); }
|
|
||||||
double distance_to(const Pointf3 &point) const { return (point - *this).norm(); }
|
|
||||||
Pointf3 negative() const { return Pointf3(- *this); }
|
|
||||||
Vectorf3 vector_to(const Pointf3 &point) const { return point - *this; }
|
|
||||||
|
|
||||||
bool operator==(const Pointf3 &rhs) const { return this->x() == rhs.x() && this->y() == rhs.y() && this->z() == rhs.z(); }
|
bool operator==(const Pointf3 &rhs) const { return this->x() == rhs.x() && this->y() == rhs.y() && this->z() == rhs.z(); }
|
||||||
bool operator!=(const Pointf3 &rhs) const { return ! (*this == rhs); }
|
bool operator!=(const Pointf3 &rhs) const { return ! (*this == rhs); }
|
||||||
|
|
||||||
Pointf xy() const { return Pointf(this->x(), this->y()); }
|
Pointf xy() const { return Pointf(this->x(), this->y()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Pointf3 operator+(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x() + p2.x(), p1.y() + p2.y(), p1.z() + p2.z()); }
|
|
||||||
inline Pointf3 operator-(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x() - p2.x(), p1.y() - p2.y(), p1.z() - p2.z()); }
|
|
||||||
inline Pointf3 operator-(const Pointf3& p) { return Pointf3(-p.x(), -p.y(), -p.z()); }
|
|
||||||
inline Pointf3 operator*(double scalar, const Pointf3& p) { return Pointf3(scalar * p.x(), scalar * p.y(), scalar * p.z()); }
|
|
||||||
inline Pointf3 operator*(const Pointf3& p, double scalar) { return Pointf3(scalar * p.x(), scalar * p.y(), scalar * p.z()); }
|
|
||||||
inline Pointf3 cross(const Pointf3& v1, const Pointf3& v2) { return Pointf3(v1.y() * v2.z() - v1.z() * v2.y(), v1.z() * v2.x() - v1.x() * v2.z(), v1.x() * v2.y() - v1.y() * v2.x()); }
|
|
||||||
inline coordf_t dot(const Pointf3& v1, const Pointf3& v2) { return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z(); }
|
|
||||||
inline coordf_t dot(const Pointf3& v) { return v.x() * v.x() + v.y() * v.y() + v.z() * v.z(); }
|
|
||||||
inline double length(const Vectorf3 &v) { return sqrt(dot(v)); }
|
|
||||||
inline double l2(const Vectorf3 &v) { return dot(v); }
|
|
||||||
inline Pointf3 normalize(const Pointf3& v)
|
|
||||||
{
|
|
||||||
coordf_t len = ::sqrt(sqr(v.x()) + sqr(v.y()) + sqr(v.z()));
|
|
||||||
return (len != 0.0) ? 1.0 / len * v : Pointf3(0.0, 0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename TO> inline TO convert_to(const Point &src) { return TO(typename TO::coord_type(src.x()), typename TO::coord_type(src.y())); }
|
|
||||||
template<typename TO> inline TO convert_to(const Pointf &src) { return TO(typename TO::coord_type(src.x()), typename TO::coord_type(src.y())); }
|
|
||||||
template<typename TO> inline TO convert_to(const Point3 &src) { return TO(typename TO::coord_type(src.x()), typename TO::coord_type(src.y()), typename TO::coord_type(src.z())); }
|
|
||||||
template<typename TO> inline TO convert_to(const Pointf3 &src) { return TO(typename TO::coord_type(src.x()), typename TO::coord_type(src.y()), typename TO::coord_type(src.z())); }
|
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
// start Boost
|
// start Boost
|
||||||
|
|
|
@ -300,24 +300,24 @@ Point Polygon::point_projection(const Point &point) const
|
||||||
for (size_t i = 0; i < this->points.size(); ++ i) {
|
for (size_t i = 0; i < this->points.size(); ++ i) {
|
||||||
const Point &pt0 = this->points[i];
|
const Point &pt0 = this->points[i];
|
||||||
const Point &pt1 = this->points[(i + 1 == this->points.size()) ? 0 : i + 1];
|
const Point &pt1 = this->points[(i + 1 == this->points.size()) ? 0 : i + 1];
|
||||||
double d = pt0.distance_to(point);
|
double d = (point - pt0).cast<double>().norm();
|
||||||
if (d < dmin) {
|
if (d < dmin) {
|
||||||
dmin = d;
|
dmin = d;
|
||||||
proj = pt0;
|
proj = pt0;
|
||||||
}
|
}
|
||||||
d = pt1.distance_to(point);
|
d = (point - pt1).cast<double>().norm();
|
||||||
if (d < dmin) {
|
if (d < dmin) {
|
||||||
dmin = d;
|
dmin = d;
|
||||||
proj = pt1;
|
proj = pt1;
|
||||||
}
|
}
|
||||||
Pointf v1(coordf_t(pt1.x() - pt0.x()), coordf_t(pt1.y() - pt0.y()));
|
Pointf v1(coordf_t(pt1.x() - pt0.x()), coordf_t(pt1.y() - pt0.y()));
|
||||||
coordf_t div = dot(v1);
|
coordf_t div = v1.squaredNorm();
|
||||||
if (div > 0.) {
|
if (div > 0.) {
|
||||||
Pointf v2(coordf_t(point.x() - pt0.x()), coordf_t(point.y() - pt0.y()));
|
Pointf v2(coordf_t(point.x() - pt0.x()), coordf_t(point.y() - pt0.y()));
|
||||||
coordf_t t = dot(v1, v2) / div;
|
coordf_t t = v1.dot(v2) / div;
|
||||||
if (t > 0. && t < 1.) {
|
if (t > 0. && t < 1.) {
|
||||||
Point foot(coord_t(floor(coordf_t(pt0.x()) + t * v1.x() + 0.5)), coord_t(floor(coordf_t(pt0.y()) + t * v1.y() + 0.5)));
|
Point foot(coord_t(floor(coordf_t(pt0.x()) + t * v1.x() + 0.5)), coord_t(floor(coordf_t(pt0.y()) + t * v1.y() + 0.5)));
|
||||||
d = foot.distance_to(point);
|
d = (point - foot).cast<double>().norm();
|
||||||
if (d < dmin) {
|
if (d < dmin) {
|
||||||
dmin = d;
|
dmin = d;
|
||||||
proj = foot;
|
proj = foot;
|
||||||
|
|
|
@ -52,92 +52,82 @@ Polyline::lines() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes the given distance from the end of the polyline
|
// removes the given distance from the end of the polyline
|
||||||
void
|
void Polyline::clip_end(double distance)
|
||||||
Polyline::clip_end(double distance)
|
|
||||||
{
|
{
|
||||||
while (distance > 0) {
|
while (distance > 0) {
|
||||||
Point last_point = this->last_point();
|
Vec2d last_point = this->last_point().cast<double>();
|
||||||
this->points.pop_back();
|
this->points.pop_back();
|
||||||
if (this->points.empty()) break;
|
if (this->points.empty())
|
||||||
|
break;
|
||||||
double last_segment_length = last_point.distance_to(this->last_point());
|
Vec2d v = this->last_point().cast<double>() - last_point;
|
||||||
if (last_segment_length <= distance) {
|
double lsqr = v.squaredNorm();
|
||||||
distance -= last_segment_length;
|
if (lsqr > distance * distance) {
|
||||||
continue;
|
this->points.emplace_back((last_point + v * (distance / sqrt(lsqr))).cast<coord_t>());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
distance -= sqrt(lsqr);
|
||||||
Line segment(last_point, this->last_point());
|
|
||||||
this->points.push_back(segment.point_at(distance));
|
|
||||||
distance = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// removes the given distance from the start of the polyline
|
// removes the given distance from the start of the polyline
|
||||||
void
|
void Polyline::clip_start(double distance)
|
||||||
Polyline::clip_start(double distance)
|
|
||||||
{
|
{
|
||||||
this->reverse();
|
this->reverse();
|
||||||
this->clip_end(distance);
|
this->clip_end(distance);
|
||||||
if (this->points.size() >= 2) this->reverse();
|
if (this->points.size() >= 2)
|
||||||
|
this->reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Polyline::extend_end(double distance)
|
||||||
Polyline::extend_end(double distance)
|
|
||||||
{
|
{
|
||||||
// relocate last point by extending the last segment by the specified length
|
// relocate last point by extending the last segment by the specified length
|
||||||
Line line(
|
Vec2d v = (this->points.back() - *(this->points.end() - 2)).cast<double>().normalized();
|
||||||
this->points.back(),
|
this->points.back() += (v * distance).cast<coord_t>();
|
||||||
*(this->points.end() - 2)
|
|
||||||
);
|
|
||||||
this->points.back() = line.point_at(-distance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Polyline::extend_start(double distance)
|
||||||
Polyline::extend_start(double distance)
|
|
||||||
{
|
{
|
||||||
// relocate first point by extending the first segment by the specified length
|
// relocate first point by extending the first segment by the specified length
|
||||||
this->points.front() = Line(this->points.front(), this->points[1]).point_at(-distance);
|
Vec2d v = (this->points.front() - this->points[1]).cast<double>().normalized();
|
||||||
|
this->points.front() += (v * distance).cast<coord_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this method returns a collection of points picked on the polygon contour
|
/* this method returns a collection of points picked on the polygon contour
|
||||||
so that they are evenly spaced according to the input distance */
|
so that they are evenly spaced according to the input distance */
|
||||||
Points
|
Points Polyline::equally_spaced_points(double distance) const
|
||||||
Polyline::equally_spaced_points(double distance) const
|
|
||||||
{
|
{
|
||||||
Points points;
|
Points points;
|
||||||
points.push_back(this->first_point());
|
points.emplace_back(this->first_point());
|
||||||
double len = 0;
|
double len = 0;
|
||||||
|
|
||||||
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
|
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
|
||||||
double segment_length = it->distance_to(*(it-1));
|
Vec2d p1 = (it-1)->cast<double>();
|
||||||
|
Vec2d v = it->cast<double>() - p1;
|
||||||
|
double segment_length = v.norm();
|
||||||
len += segment_length;
|
len += segment_length;
|
||||||
if (len < distance) continue;
|
if (len < distance)
|
||||||
|
continue;
|
||||||
if (len == distance) {
|
if (len == distance) {
|
||||||
points.push_back(*it);
|
points.emplace_back(*it);
|
||||||
len = 0;
|
len = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double take = segment_length - (len - distance); // how much we take of this segment
|
double take = segment_length - (len - distance); // how much we take of this segment
|
||||||
Line segment(*(it-1), *it);
|
points.emplace_back((p1 + v * (take / v.norm())).cast<coord_t>());
|
||||||
points.push_back(segment.point_at(take));
|
-- it;
|
||||||
--it;
|
len = - take;
|
||||||
len = -take;
|
|
||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Polyline::simplify(double tolerance)
|
||||||
Polyline::simplify(double tolerance)
|
|
||||||
{
|
{
|
||||||
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
|
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This method simplifies all *lines* contained in the supplied area */
|
/* This method simplifies all *lines* contained in the supplied area */
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void Polyline::simplify_by_visibility(const T &area)
|
||||||
Polyline::simplify_by_visibility(const T &area)
|
|
||||||
{
|
{
|
||||||
Points &pp = this->points;
|
Points &pp = this->points;
|
||||||
|
|
||||||
|
@ -157,21 +147,20 @@ Polyline::simplify_by_visibility(const T &area)
|
||||||
template void Polyline::simplify_by_visibility<ExPolygon>(const ExPolygon &area);
|
template void Polyline::simplify_by_visibility<ExPolygon>(const ExPolygon &area);
|
||||||
template void Polyline::simplify_by_visibility<ExPolygonCollection>(const ExPolygonCollection &area);
|
template void Polyline::simplify_by_visibility<ExPolygonCollection>(const ExPolygonCollection &area);
|
||||||
|
|
||||||
void
|
void Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
|
||||||
Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
|
|
||||||
{
|
{
|
||||||
if (this->points.empty()) return;
|
if (this->points.empty()) return;
|
||||||
|
|
||||||
// find the line to split at
|
// find the line to split at
|
||||||
size_t line_idx = 0;
|
size_t line_idx = 0;
|
||||||
Point p = this->first_point();
|
Point p = this->first_point();
|
||||||
double min = point.distance_to(p);
|
double min = (p - point).cast<double>().norm();
|
||||||
Lines lines = this->lines();
|
Lines lines = this->lines();
|
||||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
Point p_tmp = point.projection_onto(*line);
|
Point p_tmp = point.projection_onto(*line);
|
||||||
if (point.distance_to(p_tmp) < min) {
|
if ((p_tmp - point).cast<double>().norm() < min) {
|
||||||
p = p_tmp;
|
p = p_tmp;
|
||||||
min = point.distance_to(p);
|
min = (p - point).cast<double>().norm();
|
||||||
line_idx = line - lines.begin();
|
line_idx = line - lines.begin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,8 +182,7 @@ Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Polyline::is_straight() const
|
||||||
Polyline::is_straight() const
|
|
||||||
{
|
{
|
||||||
/* Check that each segment's direction is equal to the line connecting
|
/* Check that each segment's direction is equal to the line connecting
|
||||||
first point and last point. (Checking each line against the previous
|
first point and last point. (Checking each line against the previous
|
||||||
|
@ -208,8 +196,7 @@ Polyline::is_straight() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string Polyline::wkt() const
|
||||||
Polyline::wkt() const
|
|
||||||
{
|
{
|
||||||
std::ostringstream wkt;
|
std::ostringstream wkt;
|
||||||
wkt << "LINESTRING((";
|
wkt << "LINESTRING((";
|
||||||
|
@ -254,30 +241,17 @@ bool remove_degenerate(Polylines &polylines)
|
||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThickLines
|
ThickLines ThickPolyline::thicklines() const
|
||||||
ThickPolyline::thicklines() const
|
|
||||||
{
|
{
|
||||||
ThickLines lines;
|
ThickLines lines;
|
||||||
if (this->points.size() >= 2) {
|
if (this->points.size() >= 2) {
|
||||||
lines.reserve(this->points.size() - 1);
|
lines.reserve(this->points.size() - 1);
|
||||||
for (size_t i = 0; i < this->points.size()-1; ++i) {
|
for (size_t i = 0; i + 1 < this->points.size(); ++ i)
|
||||||
ThickLine line(this->points[i], this->points[i+1]);
|
lines.emplace_back(this->points[i], this->points[i + 1], this->width[2 * i], this->width[2 * i + 1]);
|
||||||
line.a_width = this->width[2*i];
|
|
||||||
line.b_width = this->width[2*i+1];
|
|
||||||
lines.push_back(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ThickPolyline::reverse()
|
|
||||||
{
|
|
||||||
Polyline::reverse();
|
|
||||||
std::reverse(this->width.begin(), this->width.end());
|
|
||||||
std::swap(this->endpoints.first, this->endpoints.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lines3 Polyline3::lines() const
|
Lines3 Polyline3::lines() const
|
||||||
{
|
{
|
||||||
Lines3 lines;
|
Lines3 lines;
|
||||||
|
|
|
@ -19,6 +19,8 @@ public:
|
||||||
Polyline() {};
|
Polyline() {};
|
||||||
Polyline(const Polyline &other) : MultiPoint(other.points) {}
|
Polyline(const Polyline &other) : MultiPoint(other.points) {}
|
||||||
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {}
|
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {}
|
||||||
|
Polyline(std::initializer_list<Point> list) : MultiPoint(list) {}
|
||||||
|
explicit Polyline(const Point &p1, const Point &p2) { points.reserve(2); points.emplace_back(p1); points.emplace_back(p2); }
|
||||||
Polyline& operator=(const Polyline &other) { points = other.points; return *this; }
|
Polyline& operator=(const Polyline &other) { points = other.points; return *this; }
|
||||||
Polyline& operator=(Polyline &&other) { points = std::move(other.points); return *this; }
|
Polyline& operator=(Polyline &&other) { points = std::move(other.points); return *this; }
|
||||||
static Polyline new_scale(std::vector<Pointf> points) {
|
static Polyline new_scale(std::vector<Pointf> points) {
|
||||||
|
@ -129,12 +131,17 @@ inline void polylines_append(Polylines &dst, Polylines &&src)
|
||||||
bool remove_degenerate(Polylines &polylines);
|
bool remove_degenerate(Polylines &polylines);
|
||||||
|
|
||||||
class ThickPolyline : public Polyline {
|
class ThickPolyline : public Polyline {
|
||||||
public:
|
public:
|
||||||
std::vector<coordf_t> width;
|
ThickPolyline() : endpoints(std::make_pair(false, false)) {}
|
||||||
std::pair<bool,bool> endpoints;
|
|
||||||
ThickPolyline() : endpoints(std::make_pair(false, false)) {};
|
|
||||||
ThickLines thicklines() const;
|
ThickLines thicklines() const;
|
||||||
void reverse();
|
void reverse() {
|
||||||
|
Polyline::reverse();
|
||||||
|
std::reverse(this->width.begin(), this->width.end());
|
||||||
|
std::swap(this->endpoints.first, this->endpoints.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<coordf_t> width;
|
||||||
|
std::pair<bool,bool> endpoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Polyline3 : public MultiPoint3
|
class Polyline3 : public MultiPoint3
|
||||||
|
|
|
@ -726,7 +726,7 @@ BoundingBox Print::bounding_box() const
|
||||||
for (const PrintObject *object : this->objects)
|
for (const PrintObject *object : this->objects)
|
||||||
for (Point copy : object->_shifted_copies) {
|
for (Point copy : object->_shifted_copies) {
|
||||||
bb.merge(copy);
|
bb.merge(copy);
|
||||||
copy.translate(object->size.xy());
|
copy += object->size.xy();
|
||||||
bb.merge(copy);
|
bb.merge(copy);
|
||||||
}
|
}
|
||||||
return bb;
|
return bb;
|
||||||
|
@ -902,7 +902,7 @@ void Print::_make_skirt()
|
||||||
for (const Point &shift : object->_shifted_copies) {
|
for (const Point &shift : object->_shifted_copies) {
|
||||||
Points copy_points = object_points;
|
Points copy_points = object_points;
|
||||||
for (Point &pt : copy_points)
|
for (Point &pt : copy_points)
|
||||||
pt.translate(shift);
|
pt += shift;
|
||||||
append(points, copy_points);
|
append(points, copy_points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1052,10 +1052,7 @@ void Print::_make_wipe_tower()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
// Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
|
||||||
#pragma warning(push)
|
std::vector<float> wiping_matrix(cast<float>(this->config.wiping_volumes_matrix.values));
|
||||||
#pragma warning(disable:4244) // disable Visual Studio's warning: conversion from 'double' to 'float', possible loss of data
|
|
||||||
std::vector<float> wiping_matrix((this->config.wiping_volumes_matrix.values).begin(),(this->config.wiping_volumes_matrix.values).end());
|
|
||||||
#pragma warning(pop)
|
|
||||||
// Extract purging volumes for each extruder pair:
|
// Extract purging volumes for each extruder pair:
|
||||||
std::vector<std::vector<float>> wipe_volumes;
|
std::vector<std::vector<float>> wipe_volumes;
|
||||||
const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON);
|
const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON);
|
||||||
|
|
|
@ -85,11 +85,8 @@ bool PrintObject::set_copies(const Points &points)
|
||||||
std::vector<Points::size_type> ordered_copies;
|
std::vector<Points::size_type> ordered_copies;
|
||||||
Slic3r::Geometry::chained_path(points, ordered_copies);
|
Slic3r::Geometry::chained_path(points, ordered_copies);
|
||||||
|
|
||||||
for (size_t point_idx : ordered_copies) {
|
for (size_t point_idx : ordered_copies)
|
||||||
Point copy = points[point_idx];
|
this->_shifted_copies.push_back(points[point_idx] + this->_copies_shift);
|
||||||
copy.translate(this->_copies_shift);
|
|
||||||
this->_shifted_copies.push_back(copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool invalidated = this->_print->invalidate_step(psSkirt);
|
bool invalidated = this->_print->invalidate_step(psSkirt);
|
||||||
invalidated |= this->_print->invalidate_step(psBrim);
|
invalidated |= this->_print->invalidate_step(psBrim);
|
||||||
|
|
|
@ -506,8 +506,8 @@ public:
|
||||||
|
|
||||||
for (ExPolygon &island : islands) {
|
for (ExPolygon &island : islands) {
|
||||||
BoundingBox bbox = get_extents(island.contour);
|
BoundingBox bbox = get_extents(island.contour);
|
||||||
auto it_lower = std::lower_bound(m_island_samples.begin(), m_island_samples.end(), bbox.min - Point(1, 1));
|
auto it_lower = std::lower_bound(m_island_samples.begin(), m_island_samples.end(), Point(bbox.min - Point(1, 1)));
|
||||||
auto it_upper = std::upper_bound(m_island_samples.begin(), m_island_samples.end(), bbox.max + Point(1, 1));
|
auto it_upper = std::upper_bound(m_island_samples.begin(), m_island_samples.end(), Point(bbox.max + Point(1, 1)));
|
||||||
samples_inside.clear();
|
samples_inside.clear();
|
||||||
for (auto it = it_lower; it != it_upper; ++ it)
|
for (auto it = it_lower; it != it_upper; ++ it)
|
||||||
if (bbox.contains(*it))
|
if (bbox.contains(*it))
|
||||||
|
@ -2059,9 +2059,9 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
|
||||||
// Intersection of a ray (p1, p2) with a circle placed at center_last, with radius of circle_distance.
|
// Intersection of a ray (p1, p2) with a circle placed at center_last, with radius of circle_distance.
|
||||||
const Pointf v_seg(coordf_t(p2.x()) - coordf_t(p1.x()), coordf_t(p2.y()) - coordf_t(p1.y()));
|
const Pointf v_seg(coordf_t(p2.x()) - coordf_t(p1.x()), coordf_t(p2.y()) - coordf_t(p1.y()));
|
||||||
const Pointf v_cntr(coordf_t(p1.x() - center_last.x()), coordf_t(p1.y() - center_last.y()));
|
const Pointf v_cntr(coordf_t(p1.x() - center_last.x()), coordf_t(p1.y() - center_last.y()));
|
||||||
coordf_t a = dot(v_seg);
|
coordf_t a = v_seg.squaredNorm();
|
||||||
coordf_t b = 2. * dot(v_seg, v_cntr);
|
coordf_t b = 2. * v_seg.dot(v_cntr);
|
||||||
coordf_t c = dot(v_cntr) - circle_distance * circle_distance;
|
coordf_t c = v_cntr.squaredNorm() - circle_distance * circle_distance;
|
||||||
coordf_t disc = b * b - 4. * a * c;
|
coordf_t disc = b * b - 4. * a * c;
|
||||||
if (disc > 0.) {
|
if (disc > 0.) {
|
||||||
// The circle intersects a ray. Avoid the parts of the segment inside the circle.
|
// The circle intersects a ray. Avoid the parts of the segment inside the circle.
|
||||||
|
@ -2100,9 +2100,9 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
|
||||||
circle_centers.push_back(center_last);
|
circle_centers.push_back(center_last);
|
||||||
}
|
}
|
||||||
external_loops.push_back(std::move(contour));
|
external_loops.push_back(std::move(contour));
|
||||||
for (Points::const_iterator it_center = circle_centers.begin(); it_center != circle_centers.end(); ++ it_center) {
|
for (const Point ¢er : circle_centers) {
|
||||||
circles.push_back(circle);
|
circles.push_back(circle);
|
||||||
circles.back().translate(*it_center);
|
circles.back().translate(center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2392,7 +2392,7 @@ void modulate_extrusion_by_overlapping_layers(
|
||||||
if (end_and_dist2.first == nullptr) {
|
if (end_and_dist2.first == nullptr) {
|
||||||
// New fragment connecting to pt_current was not found.
|
// New fragment connecting to pt_current was not found.
|
||||||
// Verify that the last point found is close to the original end point of the unfragmented path.
|
// Verify that the last point found is close to the original end point of the unfragmented path.
|
||||||
//const double d2 = pt_end.distance_to_sq(pt_current);
|
//const double d2 = (pt_end - pt_current).squaredNorm();
|
||||||
//assert(d2 < coordf_t(search_radius * search_radius));
|
//assert(d2 < coordf_t(search_radius * search_radius));
|
||||||
// End of the path.
|
// End of the path.
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -130,6 +130,17 @@ inline void append(std::vector<T>& dest, std::vector<T>&& src)
|
||||||
src.shrink_to_fit();
|
src.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Casting an std::vector<> from one type to another type without warnings about a loss of accuracy.
|
||||||
|
template<typename T_TO, typename T_FROM>
|
||||||
|
std::vector<T_TO> cast(const std::vector<T_FROM> &src)
|
||||||
|
{
|
||||||
|
std::vector<T_TO> dst;
|
||||||
|
dst.reserve(src.size());
|
||||||
|
for (const T_FROM &a : src)
|
||||||
|
dst.emplace_back((T_TO)a);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void remove_nulls(std::vector<T*> &vec)
|
inline void remove_nulls(std::vector<T*> &vec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,11 +34,11 @@ void Bed_2D::repaint()
|
||||||
|
|
||||||
auto cbb = BoundingBoxf(Pointf(0, 0),Pointf(cw, ch));
|
auto cbb = BoundingBoxf(Pointf(0, 0),Pointf(cw, ch));
|
||||||
// leave space for origin point
|
// leave space for origin point
|
||||||
cbb.min.translate(4, 0);
|
cbb.min.x() += 4;
|
||||||
cbb.max.translate(-4, -4);
|
cbb.max -= Vec2d(4., 4.);
|
||||||
|
|
||||||
// leave space for origin label
|
// leave space for origin label
|
||||||
cbb.max.translate(0, -13);
|
cbb.max.y() -= 13;
|
||||||
|
|
||||||
// read new size
|
// read new size
|
||||||
cw = cbb.size().x();
|
cw = cbb.size().x();
|
||||||
|
@ -113,7 +113,7 @@ void Bed_2D::repaint()
|
||||||
dc.DrawLine(wxPoint(origin_px.x(), origin_px.y()), wxPoint(x_end.x(), x_end.y()));
|
dc.DrawLine(wxPoint(origin_px.x(), origin_px.y()), wxPoint(x_end.x(), x_end.y()));
|
||||||
for (auto angle : { -arrow_angle, arrow_angle }){
|
for (auto angle : { -arrow_angle, arrow_angle }){
|
||||||
auto end = x_end;
|
auto end = x_end;
|
||||||
end.translate(-arrow_len, 0);
|
end.x() -= arrow_len;
|
||||||
end.rotate(angle, x_end);
|
end.rotate(angle, x_end);
|
||||||
dc.DrawLine(wxPoint(x_end.x(), x_end.y()), wxPoint(end.x(), end.y()));
|
dc.DrawLine(wxPoint(x_end.x(), x_end.y()), wxPoint(end.x(), end.y()));
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ void Bed_2D::repaint()
|
||||||
dc.DrawLine(wxPoint(origin_px.x(), origin_px.y()), wxPoint(y_end.x(), y_end.y()));
|
dc.DrawLine(wxPoint(origin_px.x(), origin_px.y()), wxPoint(y_end.x(), y_end.y()));
|
||||||
for (auto angle : { -arrow_angle, arrow_angle }) {
|
for (auto angle : { -arrow_angle, arrow_angle }) {
|
||||||
auto end = y_end;
|
auto end = y_end;
|
||||||
end.translate(0, +arrow_len);
|
end.y() += arrow_len;
|
||||||
end.rotate(angle, y_end);
|
end.rotate(angle, y_end);
|
||||||
dc.DrawLine(wxPoint(y_end.x(), y_end.y()), wxPoint(end.x(), end.y()));
|
dc.DrawLine(wxPoint(y_end.x(), y_end.y()), wxPoint(end.x(), end.y()));
|
||||||
}
|
}
|
||||||
|
@ -157,9 +157,7 @@ void Bed_2D::repaint()
|
||||||
|
|
||||||
// convert G - code coordinates into pixels
|
// convert G - code coordinates into pixels
|
||||||
Point Bed_2D::to_pixels(Pointf point){
|
Point Bed_2D::to_pixels(Pointf point){
|
||||||
auto p = Pointf(point);
|
auto p = point * m_scale_factor + m_shift;
|
||||||
p.scale(m_scale_factor);
|
|
||||||
p.translate(m_shift);
|
|
||||||
return Point(p.x(), GetSize().GetHeight() - p.y());
|
return Point(p.x(), GetSize().GetHeight() - p.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,10 +176,7 @@ void Bed_2D::mouse_event(wxMouseEvent event){
|
||||||
|
|
||||||
// convert pixels into G - code coordinates
|
// convert pixels into G - code coordinates
|
||||||
Pointf Bed_2D::to_units(Point point){
|
Pointf Bed_2D::to_units(Point point){
|
||||||
auto p = Pointf(point.x(), GetSize().GetHeight() - point.y());
|
return (Pointf(point.x(), GetSize().GetHeight() - point.y()) - m_shift) * (1. / m_scale_factor);
|
||||||
p.translate(m_shift.negative());
|
|
||||||
p.scale(1 / m_scale_factor);
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bed_2D::set_pos(Pointf pos){
|
void Bed_2D::set_pos(Pointf pos){
|
||||||
|
|
|
@ -929,7 +929,7 @@ static void thick_lines_to_indexed_vertex_array(
|
||||||
bool is_closing = closed && is_last;
|
bool is_closing = closed && is_last;
|
||||||
|
|
||||||
Vectorf v = Vectorf::new_unscale(line.vector());
|
Vectorf v = Vectorf::new_unscale(line.vector());
|
||||||
v.scale(inv_len);
|
v *= inv_len;
|
||||||
|
|
||||||
Pointf a = Pointf::new_unscale(line.a);
|
Pointf a = Pointf::new_unscale(line.a);
|
||||||
Pointf b = Pointf::new_unscale(line.b);
|
Pointf b = Pointf::new_unscale(line.b);
|
||||||
|
@ -941,16 +941,16 @@ static void thick_lines_to_indexed_vertex_array(
|
||||||
double dist = 0.5 * width; // scaled
|
double dist = 0.5 * width; // scaled
|
||||||
double dx = dist * v.x();
|
double dx = dist * v.x();
|
||||||
double dy = dist * v.y();
|
double dy = dist * v.y();
|
||||||
a1.translate(+dy, -dx);
|
a1 += Vectorf(+dy, -dx);
|
||||||
a2.translate(-dy, +dx);
|
a2 += Vectorf(-dy, +dx);
|
||||||
b1.translate(+dy, -dx);
|
b1 += Vectorf(+dy, -dx);
|
||||||
b2.translate(-dy, +dx);
|
b2 += Vectorf(-dy, +dx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate new XY normals
|
// calculate new XY normals
|
||||||
Vector n = line.normal();
|
Vector n = line.normal();
|
||||||
Vectorf3 xy_right_normal = Vectorf3::new_unscale(n.x(), n.y(), 0);
|
Vectorf3 xy_right_normal = Vectorf3::new_unscale(n.x(), n.y(), 0);
|
||||||
xy_right_normal.scale(inv_len);
|
xy_right_normal *= inv_len;
|
||||||
|
|
||||||
int idx_a[4];
|
int idx_a[4];
|
||||||
int idx_b[4];
|
int idx_b[4];
|
||||||
|
@ -994,7 +994,7 @@ static void thick_lines_to_indexed_vertex_array(
|
||||||
} else {
|
} else {
|
||||||
// Continuing a previous segment.
|
// Continuing a previous segment.
|
||||||
// Share left / right vertices if possible.
|
// Share left / right vertices if possible.
|
||||||
double v_dot = dot(v_prev, v);
|
double v_dot = v_prev.dot(v);
|
||||||
bool sharp = v_dot < 0.707; // sin(45 degrees)
|
bool sharp = v_dot < 0.707; // sin(45 degrees)
|
||||||
if (sharp) {
|
if (sharp) {
|
||||||
if (!bottom_z_different)
|
if (!bottom_z_different)
|
||||||
|
@ -1023,8 +1023,8 @@ static void thick_lines_to_indexed_vertex_array(
|
||||||
Geometry::ray_ray_intersection(b1_prev, v_prev, a1, v, intersection);
|
Geometry::ray_ray_intersection(b1_prev, v_prev, a1, v, intersection);
|
||||||
a1 = intersection;
|
a1 = intersection;
|
||||||
a2 = 2. * a - intersection;
|
a2 = 2. * a - intersection;
|
||||||
assert(length(a1.vector_to(a)) < width);
|
assert((a - a1).norm() < width);
|
||||||
assert(length(a2.vector_to(a)) < width);
|
assert((a - a2).norm() < width);
|
||||||
float *n_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6;
|
float *n_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6;
|
||||||
float *p_left_prev = n_left_prev + 3;
|
float *p_left_prev = n_left_prev + 3;
|
||||||
float *n_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6;
|
float *n_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6;
|
||||||
|
@ -1035,7 +1035,7 @@ static void thick_lines_to_indexed_vertex_array(
|
||||||
p_right_prev[1] = float(a1.y());
|
p_right_prev[1] = float(a1.y());
|
||||||
xy_right_normal.x() += n_right_prev[0];
|
xy_right_normal.x() += n_right_prev[0];
|
||||||
xy_right_normal.y() += n_right_prev[1];
|
xy_right_normal.y() += n_right_prev[1];
|
||||||
xy_right_normal.scale(1. / length(xy_right_normal));
|
xy_right_normal *= 1. / xy_right_normal.norm();
|
||||||
n_left_prev [0] = float(-xy_right_normal.x());
|
n_left_prev [0] = float(-xy_right_normal.x());
|
||||||
n_left_prev [1] = float(-xy_right_normal.y());
|
n_left_prev [1] = float(-xy_right_normal.y());
|
||||||
n_right_prev[0] = float( xy_right_normal.x());
|
n_right_prev[0] = float( xy_right_normal.x());
|
||||||
|
@ -1044,7 +1044,7 @@ static void thick_lines_to_indexed_vertex_array(
|
||||||
idx_a[RIGHT] = idx_prev[RIGHT];
|
idx_a[RIGHT] = idx_prev[RIGHT];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cross(v_prev, v) > 0.) {
|
else if (cross2(v_prev, v) > 0.) {
|
||||||
// Right turn. Fill in the right turn wedge.
|
// Right turn. Fill in the right turn wedge.
|
||||||
volume.push_triangle(idx_prev[RIGHT], idx_a [RIGHT], idx_prev[TOP] );
|
volume.push_triangle(idx_prev[RIGHT], idx_a [RIGHT], idx_prev[TOP] );
|
||||||
volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a [RIGHT] );
|
volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a [RIGHT] );
|
||||||
|
@ -1172,7 +1172,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
|
||||||
double height = heights[i];
|
double height = heights[i];
|
||||||
double width = widths[i];
|
double width = widths[i];
|
||||||
|
|
||||||
Vectorf3 unit_v = normalize(Vectorf3::new_unscale(line.vector()));
|
Vectorf3 unit_v = Vectorf3::new_unscale(line.vector()).normalized();
|
||||||
|
|
||||||
Vectorf3 n_top;
|
Vectorf3 n_top;
|
||||||
Vectorf3 n_right;
|
Vectorf3 n_right;
|
||||||
|
@ -1187,8 +1187,8 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// generic segment
|
// generic segment
|
||||||
n_right = normalize(cross(unit_v, unit_positive_z));
|
n_right = unit_v.cross(unit_positive_z).normalized();
|
||||||
n_top = normalize(cross(n_right, unit_v));
|
n_top = n_right.cross(unit_v).normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vectorf3 rl_displacement = 0.5 * width * n_right;
|
Vectorf3 rl_displacement = 0.5 * width * n_right;
|
||||||
|
@ -1247,9 +1247,9 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
|
||||||
{
|
{
|
||||||
// Continuing a previous segment.
|
// Continuing a previous segment.
|
||||||
// Share left / right vertices if possible.
|
// Share left / right vertices if possible.
|
||||||
double v_dot = dot(unit_v_prev, unit_v);
|
double v_dot = unit_v_prev.dot(unit_v);
|
||||||
bool is_sharp = v_dot < 0.707; // sin(45 degrees)
|
bool is_sharp = v_dot < 0.707; // sin(45 degrees)
|
||||||
bool is_right_turn = dot(n_top_prev, cross(unit_v_prev, unit_v)) > 0.0;
|
bool is_right_turn = n_top_prev.dot(unit_v_prev.cross(unit_v)) > 0.0;
|
||||||
|
|
||||||
if (is_sharp)
|
if (is_sharp)
|
||||||
{
|
{
|
||||||
|
@ -1272,7 +1272,7 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
|
||||||
// At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc.
|
// At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc.
|
||||||
|
|
||||||
// averages normals
|
// averages normals
|
||||||
Vectorf3 average_n_right = normalize(0.5 * (n_right + n_right_prev));
|
Vectorf3 average_n_right = 0.5 * (n_right + n_right_prev).normalized();
|
||||||
Vectorf3 average_n_left = -average_n_right;
|
Vectorf3 average_n_left = -average_n_right;
|
||||||
Vectorf3 average_rl_displacement = 0.5 * width * average_n_right;
|
Vectorf3 average_rl_displacement = 0.5 * width * average_n_right;
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points)
|
||||||
double avg_dist = 0;
|
double avg_dist = 0;
|
||||||
for (auto pt: polygon.points)
|
for (auto pt: polygon.points)
|
||||||
{
|
{
|
||||||
double distance = center.distance_to(pt);
|
double distance = (pt - center).cast<double>().norm();
|
||||||
vertex_distances.push_back(distance);
|
vertex_distances.push_back(distance);
|
||||||
avg_dist += distance;
|
avg_dist += distance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1177,7 +1177,7 @@ void GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Poin
|
||||||
// we currently use circular icons for gizmo, so we check the radius
|
// we currently use circular icons for gizmo, so we check the radius
|
||||||
if (it->second->get_state() != GLGizmoBase::On)
|
if (it->second->get_state() != GLGizmoBase::On)
|
||||||
{
|
{
|
||||||
bool inside = length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size;
|
bool inside = (mouse_pos - Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size;
|
||||||
it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
|
it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
|
||||||
}
|
}
|
||||||
top_y += (tex_size + OverlayGapY);
|
top_y += (tex_size + OverlayGapY);
|
||||||
|
@ -1201,7 +1201,7 @@ void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Poi
|
||||||
float half_tex_size = 0.5f * tex_size;
|
float half_tex_size = 0.5f * tex_size;
|
||||||
|
|
||||||
// we currently use circular icons for gizmo, so we check the radius
|
// we currently use circular icons for gizmo, so we check the radius
|
||||||
if (length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size)
|
if ((mouse_pos - Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size)
|
||||||
{
|
{
|
||||||
if ((it->second->get_state() == GLGizmoBase::On))
|
if ((it->second->get_state() == GLGizmoBase::On))
|
||||||
{
|
{
|
||||||
|
@ -1267,7 +1267,7 @@ bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const
|
||||||
float half_tex_size = 0.5f * tex_size;
|
float half_tex_size = 0.5f * tex_size;
|
||||||
|
|
||||||
// we currently use circular icons for gizmo, so we check the radius
|
// we currently use circular icons for gizmo, so we check the radius
|
||||||
if (length(Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size).vector_to(mouse_pos)) < half_tex_size)
|
if ((mouse_pos - Pointf(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
top_y += (tex_size + OverlayGapY);
|
top_y += (tex_size + OverlayGapY);
|
||||||
|
@ -3114,7 +3114,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
m_mouse.drag.start_position_3D = pos3d;
|
m_mouse.drag.start_position_3D = pos3d;
|
||||||
// Remember the shift to to the object center.The object center will later be used
|
// Remember the shift to to the object center.The object center will later be used
|
||||||
// to limit the object placement close to the bed.
|
// to limit the object placement close to the bed.
|
||||||
m_mouse.drag.volume_center_offset = pos3d.vector_to(volume_bbox.center());
|
m_mouse.drag.volume_center_offset = volume_bbox.center() - pos3d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (evt.RightDown())
|
else if (evt.RightDown())
|
||||||
|
@ -3136,7 +3136,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
Pointf3 cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D.z());
|
Pointf3 cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D.z());
|
||||||
|
|
||||||
// Clip the new position, so the object center remains close to the bed.
|
// Clip the new position, so the object center remains close to the bed.
|
||||||
cur_pos.translate(m_mouse.drag.volume_center_offset);
|
cur_pos += m_mouse.drag.volume_center_offset;
|
||||||
Point cur_pos2(scale_(cur_pos.x()), scale_(cur_pos.y()));
|
Point cur_pos2(scale_(cur_pos.x()), scale_(cur_pos.y()));
|
||||||
if (!m_bed.contains(cur_pos2))
|
if (!m_bed.contains(cur_pos2))
|
||||||
{
|
{
|
||||||
|
@ -3144,10 +3144,10 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
cur_pos.x() = unscale(ip.x());
|
cur_pos.x() = unscale(ip.x());
|
||||||
cur_pos.y() = unscale(ip.y());
|
cur_pos.y() = unscale(ip.y());
|
||||||
}
|
}
|
||||||
cur_pos.translate(m_mouse.drag.volume_center_offset.negative());
|
cur_pos -= m_mouse.drag.volume_center_offset;
|
||||||
|
|
||||||
// Calculate the translation vector.
|
// Calculate the translation vector.
|
||||||
Vectorf3 vector = m_mouse.drag.start_position_3D.vector_to(cur_pos);
|
Vectorf3 vector = cur_pos - m_mouse.drag.start_position_3D;
|
||||||
// Get the volume being dragged.
|
// Get the volume being dragged.
|
||||||
GLVolume* volume = m_volumes.volumes[m_mouse.drag.move_volume_idx];
|
GLVolume* volume = m_volumes.volumes[m_mouse.drag.move_volume_idx];
|
||||||
// Get all volumes belonging to the same group, if any.
|
// Get all volumes belonging to the same group, if any.
|
||||||
|
@ -3169,11 +3169,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
|
|
||||||
// Apply new temporary volume origin and ignore Z.
|
// Apply new temporary volume origin and ignore Z.
|
||||||
for (GLVolume* v : volumes)
|
for (GLVolume* v : volumes)
|
||||||
{
|
v->set_origin(v->get_origin() + Vectorf3(vector.x(), vector.y(), 0.0));
|
||||||
Pointf3 origin = v->get_origin();
|
|
||||||
origin.translate(vector.x(), vector.y(), 0.0);
|
|
||||||
v->set_origin(origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mouse.drag.start_position_3D = cur_pos;
|
m_mouse.drag.start_position_3D = cur_pos;
|
||||||
m_gizmos.refresh();
|
m_gizmos.refresh();
|
||||||
|
@ -3275,9 +3271,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
float z = 0.0f;
|
float z = 0.0f;
|
||||||
const Pointf3& cur_pos = _mouse_to_3d(pos, &z);
|
const Pointf3& cur_pos = _mouse_to_3d(pos, &z);
|
||||||
Pointf3 orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
|
Pointf3 orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
|
||||||
Pointf3 camera_target = m_camera.target;
|
m_camera.target += orig - cur_pos;
|
||||||
camera_target.translate(orig.vector_to(cur_pos).negative());
|
|
||||||
m_camera.target = camera_target;
|
|
||||||
|
|
||||||
m_on_viewport_changed_callback.call();
|
m_on_viewport_changed_callback.call();
|
||||||
|
|
||||||
|
@ -3571,11 +3565,11 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co
|
||||||
{
|
{
|
||||||
// project vertex on the plane perpendicular to camera forward axis
|
// project vertex on the plane perpendicular to camera forward axis
|
||||||
Pointf3 pos(v.x() - bb_center.x(), v.y() - bb_center.y(), v.z() - bb_center.z());
|
Pointf3 pos(v.x() - bb_center.x(), v.y() - bb_center.y(), v.z() - bb_center.z());
|
||||||
Pointf3 proj_on_plane = pos - dot(pos, forward) * forward;
|
Pointf3 proj_on_plane = pos - pos.dot(forward) * forward;
|
||||||
|
|
||||||
// calculates vertex coordinate along camera xy axes
|
// calculates vertex coordinate along camera xy axes
|
||||||
coordf_t x_on_plane = dot(proj_on_plane, right);
|
coordf_t x_on_plane = proj_on_plane.dot(right);
|
||||||
coordf_t y_on_plane = dot(proj_on_plane, up);
|
coordf_t y_on_plane = proj_on_plane.dot(up);
|
||||||
|
|
||||||
max_x = std::max(max_x, margin_factor * std::abs(x_on_plane));
|
max_x = std::max(max_x, margin_factor * std::abs(x_on_plane));
|
||||||
max_y = std::max(max_y, margin_factor * std::abs(y_on_plane));
|
max_y = std::max(max_y, margin_factor * std::abs(y_on_plane));
|
||||||
|
@ -3653,7 +3647,7 @@ void GLCanvas3D::_camera_tranform() const
|
||||||
::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch
|
::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch
|
||||||
::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw
|
::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw
|
||||||
|
|
||||||
Pointf3 neg_target = m_camera.target.negative();
|
Pointf3 neg_target = - m_camera.target;
|
||||||
::glTranslatef((GLfloat)neg_target.x(), (GLfloat)neg_target.y(), (GLfloat)neg_target.z());
|
::glTranslatef((GLfloat)neg_target.x(), (GLfloat)neg_target.y(), (GLfloat)neg_target.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -235,13 +235,13 @@ void GLGizmoRotate::on_set_state()
|
||||||
void GLGizmoRotate::on_update(const Pointf& mouse_pos)
|
void GLGizmoRotate::on_update(const Pointf& mouse_pos)
|
||||||
{
|
{
|
||||||
Vectorf orig_dir(1.0, 0.0);
|
Vectorf orig_dir(1.0, 0.0);
|
||||||
Vectorf new_dir = normalize(mouse_pos - m_center);
|
Vectorf new_dir = (mouse_pos - m_center).normalized();
|
||||||
coordf_t theta = ::acos(clamp(-1.0, 1.0, dot(new_dir, orig_dir)));
|
coordf_t theta = ::acos(clamp(-1.0, 1.0, new_dir.dot(orig_dir)));
|
||||||
if (cross(orig_dir, new_dir) < 0.0)
|
if (cross2(orig_dir, new_dir) < 0.0)
|
||||||
theta = 2.0 * (coordf_t)PI - theta;
|
theta = 2.0 * (coordf_t)PI - theta;
|
||||||
|
|
||||||
// snap
|
// snap
|
||||||
if (length(m_center.vector_to(mouse_pos)) < 2.0 * (double)m_radius / 3.0)
|
if ((mouse_pos - m_center).norm() < 2.0 * (double)m_radius / 3.0)
|
||||||
{
|
{
|
||||||
coordf_t step = 2.0 * (coordf_t)PI / (coordf_t)SnapRegionsCount;
|
coordf_t step = 2.0 * (coordf_t)PI / (coordf_t)SnapRegionsCount;
|
||||||
theta = step * (coordf_t)std::round(theta / step);
|
theta = step * (coordf_t)std::round(theta / step);
|
||||||
|
@ -444,8 +444,8 @@ void GLGizmoScale::on_update(const Pointf& mouse_pos)
|
||||||
{
|
{
|
||||||
Pointf center(0.5 * (m_grabbers[1].center.x() + m_grabbers[0].center.x()), 0.5 * (m_grabbers[3].center.y() + m_grabbers[0].center.y()));
|
Pointf center(0.5 * (m_grabbers[1].center.x() + m_grabbers[0].center.x()), 0.5 * (m_grabbers[3].center.y() + m_grabbers[0].center.y()));
|
||||||
|
|
||||||
coordf_t orig_len = length(m_starting_drag_position - center);
|
coordf_t orig_len = (m_starting_drag_position - center).norm();
|
||||||
coordf_t new_len = length(mouse_pos - center);
|
coordf_t new_len = (mouse_pos - center).norm();
|
||||||
coordf_t ratio = (orig_len != 0.0) ? new_len / orig_len : 1.0;
|
coordf_t ratio = (orig_len != 0.0) ? new_len / orig_len : 1.0;
|
||||||
|
|
||||||
m_scale = m_starting_scale * (float)ratio;
|
m_scale = m_starting_scale * (float)ratio;
|
||||||
|
|
|
@ -894,10 +894,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
|
||||||
const std::vector<double> &init_matrix = (config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values;
|
const std::vector<double> &init_matrix = (config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values;
|
||||||
const std::vector<double> &init_extruders = (config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values;
|
const std::vector<double> &init_extruders = (config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values;
|
||||||
|
|
||||||
#pragma warning(push)
|
WipingDialog dlg(parent,cast<float>(init_matrix),cast<float>(init_extruders));
|
||||||
#pragma warning(disable:4244) // disable Visual Studio's warning: conversion from 'double' to 'float', possible loss of data
|
|
||||||
WipingDialog dlg(parent,std::vector<float>(init_matrix.begin(),init_matrix.end()),std::vector<float>(init_extruders.begin(),init_extruders.end()));
|
|
||||||
#pragma warning(pop)
|
|
||||||
|
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
if (dlg.ShowModal() == wxID_OK) {
|
||||||
std::vector<float> matrix = dlg.get_matrix();
|
std::vector<float> matrix = dlg.get_matrix();
|
||||||
|
|
|
@ -261,7 +261,7 @@ std::vector<float> Chart::get_ramming_speed(float sampling) const {
|
||||||
std::vector<std::pair<float,float>> Chart::get_buttons() const {
|
std::vector<std::pair<float,float>> Chart::get_buttons() const {
|
||||||
std::vector<std::pair<float, float>> buttons_out;
|
std::vector<std::pair<float, float>> buttons_out;
|
||||||
for (const auto& button : m_buttons)
|
for (const auto& button : m_buttons)
|
||||||
buttons_out.push_back(std::make_pair(button.get_pos().m_x,button.get_pos().m_y));
|
buttons_out.push_back(std::make_pair(float(button.get_pos().m_x),float(button.get_pos().m_y)));
|
||||||
return buttons_out;
|
return buttons_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ extern "C" {
|
||||||
#undef realloc
|
#undef realloc
|
||||||
#undef free
|
#undef free
|
||||||
#undef Zero
|
#undef Zero
|
||||||
|
#undef Packet
|
||||||
#undef select
|
#undef select
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,11 +58,7 @@
|
||||||
Clone<Pointf3> origin() const
|
Clone<Pointf3> origin() const
|
||||||
%code%{ RETVAL = THIS->get_origin(); %};
|
%code%{ RETVAL = THIS->get_origin(); %};
|
||||||
void translate(double x, double y, double z)
|
void translate(double x, double y, double z)
|
||||||
%code%{
|
%code%{ THIS->set_origin(THIS->get_origin() + Pointf3(x, y, z)); %};
|
||||||
Pointf3 o = THIS->get_origin();
|
|
||||||
o.translate(x, y, z);
|
|
||||||
THIS->set_origin(o);
|
|
||||||
%};
|
|
||||||
Clone<BoundingBoxf3> bounding_box() const
|
Clone<BoundingBoxf3> bounding_box() const
|
||||||
%code%{ RETVAL = THIS->bounding_box; %};
|
%code%{ RETVAL = THIS->bounding_box; %};
|
||||||
Clone<BoundingBoxf3> transformed_bounding_box() const;
|
Clone<BoundingBoxf3> transformed_bounding_box() const;
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
bool parallel_to_line(Line* line)
|
bool parallel_to_line(Line* line)
|
||||||
%code{% RETVAL = THIS->parallel_to(*line); %};
|
%code{% RETVAL = THIS->parallel_to(*line); %};
|
||||||
Clone<Point> midpoint();
|
Clone<Point> midpoint();
|
||||||
Clone<Point> point_at(double distance);
|
|
||||||
Clone<Point> intersection_infinite(Line* other)
|
Clone<Point> intersection_infinite(Line* other)
|
||||||
%code{%
|
%code{%
|
||||||
Point p;
|
Point p;
|
||||||
|
@ -37,8 +36,8 @@
|
||||||
if (!res) CONFESS("Intersection failed");
|
if (!res) CONFESS("Intersection failed");
|
||||||
RETVAL = p;
|
RETVAL = p;
|
||||||
%};
|
%};
|
||||||
Clone<Polyline> as_polyline()
|
Polyline* as_polyline()
|
||||||
%code{% RETVAL = Polyline(*THIS); %};
|
%code{% RETVAL = new Polyline(THIS->a, THIS->b); %};
|
||||||
Clone<Point> normal();
|
Clone<Point> normal();
|
||||||
Clone<Point> vector();
|
Clone<Point> vector();
|
||||||
double ccw(Point* point)
|
double ccw(Point* point)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
%{
|
%{
|
||||||
#include <xsinit.h>
|
#include <xsinit.h>
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
|
#include "libslic3r/Line.hpp"
|
||||||
#include "libslic3r/Polygon.hpp"
|
#include "libslic3r/Polygon.hpp"
|
||||||
#include "libslic3r/Polyline.hpp"
|
#include "libslic3r/Polyline.hpp"
|
||||||
%}
|
%}
|
||||||
|
@ -12,8 +13,10 @@
|
||||||
~Point();
|
~Point();
|
||||||
Clone<Point> clone()
|
Clone<Point> clone()
|
||||||
%code{% RETVAL=THIS; %};
|
%code{% RETVAL=THIS; %};
|
||||||
void scale(double factor);
|
void scale(double factor)
|
||||||
void translate(double x, double y);
|
%code{% *THIS *= factor; %};
|
||||||
|
void translate(double x, double y)
|
||||||
|
%code{% *THIS += Point(x, y); %};
|
||||||
SV* arrayref()
|
SV* arrayref()
|
||||||
%code{% RETVAL = to_SV_pureperl(THIS); %};
|
%code{% RETVAL = to_SV_pureperl(THIS); %};
|
||||||
SV* pp()
|
SV* pp()
|
||||||
|
@ -30,23 +33,23 @@
|
||||||
Clone<Point> nearest_point(Points points)
|
Clone<Point> nearest_point(Points points)
|
||||||
%code{% Point p; THIS->nearest_point(points, &p); RETVAL = p; %};
|
%code{% Point p; THIS->nearest_point(points, &p); RETVAL = p; %};
|
||||||
double distance_to(Point* point)
|
double distance_to(Point* point)
|
||||||
%code{% RETVAL = THIS->distance_to(*point); %};
|
%code{% RETVAL = (*point - *THIS).cast<double>().norm(); %};
|
||||||
double distance_to_line(Line* line)
|
double distance_to_line(Line* line)
|
||||||
%code{% RETVAL = THIS->distance_to(*line); %};
|
%code{% RETVAL = line->distance_to(*THIS); %};
|
||||||
double perp_distance_to_line(Line* line)
|
double perp_distance_to_line(Line* line)
|
||||||
%code{% RETVAL = THIS->perp_distance_to(*line); %};
|
%code{% RETVAL = line->perp_distance_to(*THIS); %};
|
||||||
double ccw(Point* p1, Point* p2)
|
double ccw(Point* p1, Point* p2)
|
||||||
%code{% RETVAL = THIS->ccw(*p1, *p2); %};
|
%code{% RETVAL = THIS->ccw(*p1, *p2); %};
|
||||||
double ccw_angle(Point* p1, Point* p2)
|
double ccw_angle(Point* p1, Point* p2)
|
||||||
%code{% RETVAL = THIS->ccw_angle(*p1, *p2); %};
|
%code{% RETVAL = THIS->ccw_angle(*p1, *p2); %};
|
||||||
Clone<Point> projection_onto_polygon(Polygon* polygon)
|
Point* projection_onto_polygon(Polygon* polygon)
|
||||||
%code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
|
%code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
|
||||||
Clone<Point> projection_onto_polyline(Polyline* polyline)
|
Point* projection_onto_polyline(Polyline* polyline)
|
||||||
%code{% RETVAL = new Point(THIS->projection_onto(*polyline)); %};
|
%code{% RETVAL = new Point(THIS->projection_onto(*polyline)); %};
|
||||||
Clone<Point> projection_onto_line(Line* line)
|
Point* projection_onto_line(Line* line)
|
||||||
%code{% RETVAL = new Point(THIS->projection_onto(*line)); %};
|
%code{% RETVAL = new Point(THIS->projection_onto(*line)); %};
|
||||||
Clone<Point> negative()
|
Point* negative()
|
||||||
%code{% RETVAL = new Point(THIS->negative()); %};
|
%code{% RETVAL = new Point(- *THIS); %};
|
||||||
bool coincides_with_epsilon(Point* point)
|
bool coincides_with_epsilon(Point* point)
|
||||||
%code{% RETVAL = (*THIS) == *point; %};
|
%code{% RETVAL = (*THIS) == *point; %};
|
||||||
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld", THIS->x(), THIS->y()); RETVAL = buf; %};
|
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld", THIS->x(), THIS->y()); RETVAL = buf; %};
|
||||||
|
@ -107,14 +110,16 @@ Point::coincides_with(point_sv)
|
||||||
%code{% THIS->x() = val; %};
|
%code{% THIS->x() = val; %};
|
||||||
void set_y(double val)
|
void set_y(double val)
|
||||||
%code{% THIS->y() = val; %};
|
%code{% THIS->y() = val; %};
|
||||||
void translate(double x, double y);
|
void translate(double x, double y)
|
||||||
void scale(double factor);
|
%code{% *THIS += Pointf(x, y); %};
|
||||||
|
void scale(double factor)
|
||||||
|
%code{% *THIS *= factor; %};
|
||||||
void rotate(double angle, Pointf* center)
|
void rotate(double angle, Pointf* center)
|
||||||
%code{% THIS->rotate(angle, *center); %};
|
%code{% THIS->rotate(angle, *center); %};
|
||||||
Clone<Pointf> negative()
|
Pointf* negative()
|
||||||
%code{% RETVAL = THIS->negative(); %};
|
%code{% RETVAL = new Pointf(- *THIS); %};
|
||||||
Clone<Pointf> vector_to(Pointf* point)
|
Pointf* vector_to(Pointf* point)
|
||||||
%code{% RETVAL = THIS->vector_to(*point); %};
|
%code{% RETVAL = new Pointf(*point - *THIS); %};
|
||||||
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf", THIS->x(), THIS->y()); RETVAL = buf; %};
|
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf", THIS->x(), THIS->y()); RETVAL = buf; %};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,13 +140,15 @@ Point::coincides_with(point_sv)
|
||||||
%code{% THIS->y() = val; %};
|
%code{% THIS->y() = val; %};
|
||||||
void set_z(double val)
|
void set_z(double val)
|
||||||
%code{% THIS->z() = val; %};
|
%code{% THIS->z() = val; %};
|
||||||
void translate(double x, double y, double z);
|
void translate(double x, double y, double z)
|
||||||
void scale(double factor);
|
%code{% *THIS += Pointf3(x, y, z); %};
|
||||||
|
void scale(double factor)
|
||||||
|
%code{% *THIS *= factor; %};
|
||||||
double distance_to(Pointf3* point)
|
double distance_to(Pointf3* point)
|
||||||
%code{% RETVAL = THIS->distance_to(*point); %};
|
%code{% RETVAL = (*point - *THIS).norm(); %};
|
||||||
Clone<Pointf3> negative()
|
Pointf3* negative()
|
||||||
%code{% RETVAL = THIS->negative(); %};
|
%code{% RETVAL = new Pointf3(- *THIS); %};
|
||||||
Clone<Pointf3> vector_to(Pointf3* point)
|
Pointf3* vector_to(Pointf3* point)
|
||||||
%code{% RETVAL = THIS->vector_to(*point); %};
|
%code{% RETVAL = new Pointf3(*point - *THIS); %};
|
||||||
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf", THIS->x(), THIS->y(), THIS->z()); RETVAL = buf; %};
|
std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf", THIS->x(), THIS->y(), THIS->z()); RETVAL = buf; %};
|
||||||
};
|
};
|
||||||
|
|
|
@ -176,15 +176,6 @@ _constant()
|
||||||
void set_step_started(PrintStep step)
|
void set_step_started(PrintStep step)
|
||||||
%code%{ THIS->state.set_started(step); %};
|
%code%{ THIS->state.set_started(step); %};
|
||||||
|
|
||||||
void clear_filament_stats()
|
|
||||||
%code%{
|
|
||||||
THIS->filament_stats.clear();
|
|
||||||
%};
|
|
||||||
void set_filament_stats(int extruder_id, float length)
|
|
||||||
%code%{
|
|
||||||
THIS->filament_stats.insert(std::pair<size_t,float>(extruder_id, 0));
|
|
||||||
THIS->filament_stats[extruder_id] += length;
|
|
||||||
%};
|
|
||||||
SV* filament_stats()
|
SV* filament_stats()
|
||||||
%code%{
|
%code%{
|
||||||
HV* hv = newHV();
|
HV* hv = newHV();
|
||||||
|
|
|
@ -181,7 +181,7 @@ TriangleMesh::slice(z)
|
||||||
std::vector<double> z
|
std::vector<double> z
|
||||||
CODE:
|
CODE:
|
||||||
// convert doubles to floats
|
// convert doubles to floats
|
||||||
std::vector<float> z_f(z.begin(), z.end());
|
std::vector<float> z_f = cast<float>(z);
|
||||||
|
|
||||||
std::vector<ExPolygons> layers;
|
std::vector<ExPolygons> layers;
|
||||||
TriangleMeshSlicer mslicer(THIS);
|
TriangleMeshSlicer mslicer(THIS);
|
||||||
|
|
Loading…
Add table
Reference in a new issue