Skip to content

Commit

Permalink
Detect bridge direction also when lower slices have narrow gaps. slic…
Browse files Browse the repository at this point in the history
  • Loading branch information
alranel committed May 10, 2017
1 parent 893cab7 commit f74a915
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 14 deletions.
26 changes: 22 additions & 4 deletions t/bridges.t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use Test::More tests => 18;
use Test::More tests => 20;
use strict;
use warnings;

Expand Down Expand Up @@ -99,6 +99,24 @@ use Slic3r::Test;
'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 {
my ($lower, $bridge, $expected, $tolerance, $expected_coverage, $extrusion_width) = @_;

Expand All @@ -121,9 +139,9 @@ sub check_angle {
# our epsilon is equal to the steps used by the bridge detection algorithm
###use XXX; YYY [ rad2deg($result), $expected ];
# returned value must be non-negative, check for that too
my $delta=rad2deg($result) - $expected;
$delta-=180 if $delta>=180 - epsilon;
return defined $result && $result>=0 && abs($delta) < $tolerance;
my $delta = rad2deg($result) - $expected;
$delta -= 180 if $delta >= 180 - epsilon;
return defined $result && $result >= 0 && abs($delta) < $tolerance;
}

{
Expand Down
33 changes: 29 additions & 4 deletions xs/src/libslic3r/BridgeDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ namespace Slic3r {

BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices,
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)
{
/* outset our bridge by an arbitrary amout; we'll use this outer margin
for detecting anchors */
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
// into polylines and then clipping them with each lower slice's contour
this->_edges = intersection_pl(grown, this->lower_slices.contours());
Expand All @@ -34,6 +44,10 @@ BridgeDetector::BridgeDetector(const ExPolygon &_expolygon, const ExPolygonColle
svg.draw(this->_anchors, "yellow");
svg.draw(this->_edges, "black", scale_(0.2));
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
}
Expand Down Expand Up @@ -133,6 +147,13 @@ BridgeDetector::detect_angle()
));
}
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
Expand All @@ -159,12 +180,16 @@ BridgeDetector::detect_angle()
return true;
}

Polygons
BridgeDetector::coverage() const
{
if (this->angle == -1) return Polygons();
return this->coverage(this->angle);
}

Polygons
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.
ExPolygon expolygon = this->expolygon;
expolygon.rotate(PI/2.0 - angle, Point(0,0));
Expand Down
3 changes: 2 additions & 1 deletion xs/src/libslic3r/BridgeDetector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class BridgeDetector {

BridgeDetector(const ExPolygon &_expolygon, const ExPolygonCollection &_lower_slices, coord_t _extrusion_width);
bool detect_angle();
Polygons coverage(double angle = -1) const;
Polygons coverage() const;
Polygons coverage(double angle) const;
Polylines unsupported_edges(double angle = -1) const;

private:
Expand Down
7 changes: 2 additions & 5 deletions xs/src/libslic3r/Fill/Fill.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#define DEBUG
#undef NDEBUG
#include <cassert>
#include <math.h>
#include <stdio.h>

#include "../ClipperUtils.hpp"
#include "../Geometry.hpp"
#include "../Surface.hpp"
#include "../PrintConfig.hpp"

Expand Down Expand Up @@ -96,10 +95,8 @@ Fill::_infill_direction(const Surface &surface) const

if (surface.bridge_angle >= 0) {
// use bridge angle
//FIXME Vojtech: Add a debugf?
// Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle);
#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
out_angle = surface.bridge_angle;
} else if (this->layer_id != size_t(-1)) {
Expand Down

0 comments on commit f74a915

Please sign in to comment.