mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-12 06:58:58 +08:00
Detect bridge direction also when lower slices have narrow gaps. #3929
This commit is contained in:
parent
893cab7523
commit
f74a91532d
20
t/bridges.t
20
t/bridges.t
@ -1,4 +1,4 @@
|
|||||||
use Test::More tests => 18;
|
use Test::More tests => 20;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
@ -99,6 +99,24 @@ use Slic3r::Test;
|
|||||||
'correct bridge angle for rectangle';
|
'correct bridge angle for rectangle';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
# GH #3929: This test case checks that narrow gaps in lower slices don't prevent correct
|
||||||
|
# direction detection.
|
||||||
|
my $bridge = Slic3r::ExPolygon->new(
|
||||||
|
Slic3r::Polygon->new([10099996,45867519],[3762370,45867519],[3762370,2132479],[10099996,2132479]),
|
||||||
|
);
|
||||||
|
my $lower = [
|
||||||
|
Slic3r::ExPolygon->new(
|
||||||
|
Slic3r::Polygon->new([13534103,210089],[13629884,235753],[14249999,401901],[14269611,421510],[14272931,424830],[14287518,439411],[14484206,636101],[15348099,1500000],[15360812,1547449],[15365467,1564815],[15388623,1651235],[15391897,1663454],[15393088,1667906],[15399044,1690134],[15457593,1908648],[15750000,2999999],[15750000,45000000],[15742825,45026783],[15741540,45031580],[15735900,45052628],[15663980,45321047],[15348099,46500000],[15151410,46696691],[14287518,47560587],[14267907,47580196],[14264587,47583515],[14249999,47598100],[14211041,47608539],[14204785,47610215],[14176024,47617916],[14105602,47636784],[14097768,47638884],[14048000,47652220],[13871472,47699515],[12750000,48000000],[10446106,48000000],[10446124,47990347],[10446124,9652],[10446106,0],[12750000,0]),
|
||||||
|
Slic3r::Polygon->new([10251886,5013],[10251886,47994988],[10251907,48000000],[10100006,48000000],[10100006,0],[10251907,0]),
|
||||||
|
Slic3r::Polygon->new([3762360,17017],[3762360,47982984],[3762397,48000000],[1249999,48000000],[536029,47808700],[456599,47787419],[73471,47684764],[0,47665076],[0,23124327],[119299,22907322],[159278,22834601],[196290,22690451],[239412,22522516],[303787,22271780],[639274,20965103],[639274,19034896],[616959,18947983],[607651,18911729],[559146,18722807],[494769,18472073],[159278,17165397],[38931,16946491],[0,16875676],[0,334922],[128529,300484],[1250000,0],[3762397,0]),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
ok check_angle($lower, $bridge, 0, undef, $bridge->area, 500000),
|
||||||
|
'correct bridge angle when lower slices have narrow gap';
|
||||||
|
}
|
||||||
|
|
||||||
sub check_angle {
|
sub check_angle {
|
||||||
my ($lower, $bridge, $expected, $tolerance, $expected_coverage, $extrusion_width) = @_;
|
my ($lower, $bridge, $expected, $tolerance, $expected_coverage, $extrusion_width) = @_;
|
||||||
|
|
||||||
|
@ -7,13 +7,23 @@ namespace Slic3r {
|
|||||||
|
|
||||||
BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices,
|
BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices,
|
||||||
coord_t _extrusion_width)
|
coord_t _extrusion_width)
|
||||||
: expolygon(_expolygon), lower_slices(_lower_slices), extrusion_width(_extrusion_width),
|
: expolygon(_expolygon), extrusion_width(_extrusion_width),
|
||||||
resolution(PI/36.0), angle(-1)
|
resolution(PI/36.0), angle(-1)
|
||||||
{
|
{
|
||||||
/* outset our bridge by an arbitrary amout; we'll use this outer margin
|
/* outset our bridge by an arbitrary amout; we'll use this outer margin
|
||||||
for detecting anchors */
|
for detecting anchors */
|
||||||
Polygons grown = offset(this->expolygon, this->extrusion_width);
|
Polygons grown = offset(this->expolygon, this->extrusion_width);
|
||||||
|
|
||||||
|
// remove narrow gaps from lower slices
|
||||||
|
// (this is only needed as long as we use clipped test lines for angle detection
|
||||||
|
// and we check their endpoints: when endpoint fall in the gap we'd get false
|
||||||
|
// negatives)
|
||||||
|
this->lower_slices.expolygons = offset2_ex(
|
||||||
|
_lower_slices,
|
||||||
|
+this->extrusion_width/2,
|
||||||
|
-this->extrusion_width/2
|
||||||
|
);
|
||||||
|
|
||||||
// detect what edges lie on lower slices by turning bridge contour and holes
|
// detect what edges lie on lower slices by turning bridge contour and holes
|
||||||
// into polylines and then clipping them with each lower slice's contour
|
// into polylines and then clipping them with each lower slice's contour
|
||||||
this->_edges = intersection_pl(grown, this->lower_slices.contours());
|
this->_edges = intersection_pl(grown, this->lower_slices.contours());
|
||||||
@ -34,6 +44,10 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
|
|||||||
svg.draw(this->_anchors, "yellow");
|
svg.draw(this->_anchors, "yellow");
|
||||||
svg.draw(this->_edges, "black", scale_(0.2));
|
svg.draw(this->_edges, "black", scale_(0.2));
|
||||||
svg.Close();
|
svg.Close();
|
||||||
|
|
||||||
|
std::cout << "expolygon: " << this->expolygon.dump_perl() << std::endl;
|
||||||
|
for (const ExPolygon &e : this->lower_slices.expolygons)
|
||||||
|
std::cout << "lower: " << e.dump_perl() << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -133,6 +147,13 @@ BridgeDetector::detect_angle()
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (candidate.coverage > 0) have_coverage = true;
|
if (candidate.coverage > 0) have_coverage = true;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
std::cout << "angle = " << Slic3r::Geometry::rad2deg(candidate.angle)
|
||||||
|
<< "; coverage = " << candidate.coverage
|
||||||
|
<< "; max_length = " << candidate.max_length
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no direction produced coverage, then there's no bridge direction
|
// if no direction produced coverage, then there's no bridge direction
|
||||||
@ -159,12 +180,16 @@ BridgeDetector::detect_angle()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Polygons
|
||||||
|
BridgeDetector::coverage() const
|
||||||
|
{
|
||||||
|
if (this->angle == -1) return Polygons();
|
||||||
|
return this->coverage(this->angle);
|
||||||
|
}
|
||||||
|
|
||||||
Polygons
|
Polygons
|
||||||
BridgeDetector::coverage(double angle) const
|
BridgeDetector::coverage(double angle) const
|
||||||
{
|
{
|
||||||
if (angle == -1) angle = this->angle;
|
|
||||||
if (angle == -1) return Polygons();
|
|
||||||
|
|
||||||
// Clone our expolygon and rotate it so that we work with vertical lines.
|
// Clone our expolygon and rotate it so that we work with vertical lines.
|
||||||
ExPolygon expolygon = this->expolygon;
|
ExPolygon expolygon = this->expolygon;
|
||||||
expolygon.rotate(PI/2.0 - angle, Point(0,0));
|
expolygon.rotate(PI/2.0 - angle, Point(0,0));
|
||||||
|
@ -23,7 +23,8 @@ public:
|
|||||||
|
|
||||||
BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
|
BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
|
||||||
bool detect_angle();
|
bool detect_angle();
|
||||||
Polygons coverage(double angle = -1) const;
|
Polygons coverage() const;
|
||||||
|
Polygons coverage(double angle) const;
|
||||||
Polylines unsupported_edges(double angle = -1) const;
|
Polylines unsupported_edges(double angle = -1) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#define DEBUG
|
|
||||||
#undef NDEBUG
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "../ClipperUtils.hpp"
|
#include "../ClipperUtils.hpp"
|
||||||
|
#include "../Geometry.hpp"
|
||||||
#include "../Surface.hpp"
|
#include "../Surface.hpp"
|
||||||
#include "../PrintConfig.hpp"
|
#include "../PrintConfig.hpp"
|
||||||
|
|
||||||
@ -96,10 +95,8 @@ Fill::_infill_direction(const Surface &surface) const
|
|||||||
|
|
||||||
if (surface.bridge_angle >= 0) {
|
if (surface.bridge_angle >= 0) {
|
||||||
// use bridge angle
|
// use bridge angle
|
||||||
//FIXME Vojtech: Add a debugf?
|
|
||||||
// Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle);
|
|
||||||
#ifdef SLIC3R_DEBUG
|
#ifdef SLIC3R_DEBUG
|
||||||
printf("Filling bridge with angle %f\n", surface.bridge_angle);
|
printf("Filling bridge with angle %f\n", Slic3r::Geometry::rad2deg(surface.bridge_angle));
|
||||||
#endif
|
#endif
|
||||||
out_angle = surface.bridge_angle;
|
out_angle = surface.bridge_angle;
|
||||||
} else if (this->layer_id != size_t(-1)) {
|
} else if (this->layer_id != size_t(-1)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user