Ported diff_ex, intersection_ex, union_ex, xor_ex

This commit is contained in:
Alessandro Ranellucci 2013-07-17 00:29:09 +02:00
parent f7ada2b5db
commit bf8c799685
9 changed files with 72 additions and 48 deletions

View file

@ -70,7 +70,7 @@ sub make_fill {
@groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @groups; @groups = sort { defined $a->[0]->bridge_angle ? -1 : 0 } @groups;
foreach my $group (@groups) { foreach my $group (@groups) {
my $union = union_ex([ map $_->p, @$group ], undef, 1); my $union = union_ex([ map $_->p, @$group ], 1);
# subtract surfaces having a defined bridge_angle from any other # subtract surfaces having a defined bridge_angle from any other
if (@surfaces_with_bridge_angle && !defined $group->[0]->bridge_angle) { if (@surfaces_with_bridge_angle && !defined $group->[0]->bridge_angle) {
@ -120,7 +120,6 @@ sub make_fill {
(map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces), (map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces),
(@$collapsed), (@$collapsed),
], ],
undef,
1, 1,
)}; )};
} }

View file

@ -105,7 +105,7 @@ sub change_layer {
); );
if ($self->config->avoid_crossing_perimeters) { if ($self->config->avoid_crossing_perimeters) {
$self->layer_mp(Slic3r::GCode::MotionPlanner->new( $self->layer_mp(Slic3r::GCode::MotionPlanner->new(
islands => union_ex([ map @$_, @{$layer->slices} ], undef, 1), islands => union_ex([ map @$_, @{$layer->slices} ], 1),
)); ));
} }

View file

@ -57,18 +57,6 @@ sub diff {
]; ];
} }
sub union_ex {
my ($polygons, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$polygons = $polygons->arrayref if ref $polygons eq 'Slic3r::ExPolygon';
$clipper->add_subject_polygons($safety_offset ? _convert(safety_offset($polygons)) : _convert($polygons));
return [
map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_UNION, $jointype, $jointype) },
];
}
sub union_pt { sub union_pt {
my ($polygons, $jointype, $safety_offset) = @_; my ($polygons, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype; $jointype = PFT_NONZERO unless defined $jointype;
@ -77,18 +65,6 @@ sub union_pt {
return $clipper->pt_execute(CT_UNION, $jointype, $jointype); return $clipper->pt_execute(CT_UNION, $jointype, $jointype);
} }
sub intersection_ex {
my ($subject, $clip, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons($safety_offset ? _convert(safety_offset($clip)) : _convert($clip));
return [
map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_INTERSECTION, $jointype, $jointype) },
];
}
sub intersection { sub intersection {
my ($subject, $clip, $jointype, $safety_offset) = @_; my ($subject, $clip, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype; $jointype = PFT_NONZERO unless defined $jointype;
@ -101,18 +77,6 @@ sub intersection {
]; ];
} }
sub xor_ex {
my ($subject, $clip, $jointype) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons(_convert($clip));
return [
map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_XOR, $jointype, $jointype) },
];
}
sub collapse_ex { sub collapse_ex {
my ($polygons, $width) = @_; my ($polygons, $width) = @_;
return offset2_ex($polygons, -$width/2, +$width/2); return offset2_ex($polygons, -$width/2, +$width/2);

View file

@ -418,13 +418,11 @@ sub process_external_surfaces {
@top = @{intersection_ex( @top = @{intersection_ex(
[ Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin) ], [ Slic3r::Geometry::Clipper::offset([ map $_->p, @top ], +$margin) ],
[ map $_->p, @fill_boundaries ], [ map $_->p, @fill_boundaries ],
undef,
1, # to ensure adjacent expolygons are unified 1, # to ensure adjacent expolygons are unified
)}; )};
@bottom = @{intersection_ex( @bottom = @{intersection_ex(
[ Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin) ], [ Slic3r::Geometry::Clipper::offset([ map $_->p, @bottom ], +$margin) ],
[ map $_->p, @fill_boundaries ], [ map $_->p, @fill_boundaries ],
undef,
1, # to ensure adjacent expolygons are unified 1, # to ensure adjacent expolygons are unified
)}; )};
@ -526,7 +524,6 @@ sub _detect_bridges {
my $anchors = intersection_ex( my $anchors = intersection_ex(
[ $surface->p ], [ $surface->p ],
[ map @$_, @lower ], [ map @$_, @lower ],
undef,
1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges 1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges
); );

View file

@ -610,7 +610,7 @@ sub discover_horizontal_shells {
my $new_internal_solid = intersection_ex( my $new_internal_solid = intersection_ex(
[ map @$_, @$solid ], [ map @$_, @$solid ],
[ map $_->p, grep { ($_->surface_type == S_TYPE_INTERNAL) || ($_->surface_type == S_TYPE_INTERNALSOLID) } @neighbor_fill_surfaces ], [ map $_->p, grep { ($_->surface_type == S_TYPE_INTERNAL) || ($_->surface_type == S_TYPE_INTERNALSOLID) } @neighbor_fill_surfaces ],
undef, 1, 1,
); );
next if !@$new_internal_solid; next if !@$new_internal_solid;

View file

@ -139,8 +139,8 @@ offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const float d
delete output2; delete output2;
} }
void inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject,
diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset) Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset)
{ {
// read input // read input
ClipperLib::Polygons* input_subject = new ClipperLib::Polygons(); ClipperLib::Polygons* input_subject = new ClipperLib::Polygons();
@ -150,7 +150,11 @@ diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &r
// perform safety offset // perform safety offset
if (safety_offset) { if (safety_offset) {
// SafetyOffset(*input_clip); if (clipType == ClipperLib::ctUnion) {
// SafetyOffset(*input_subject);
} else {
// SafetyOffset(*input_clip);
}
} }
// init Clipper // init Clipper
@ -165,13 +169,35 @@ diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &r
// perform operation // perform operation
ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree(); ClipperLib::PolyTree* polytree = new ClipperLib::PolyTree();
clipper.Execute(ClipperLib::ctDifference, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero); clipper.Execute(clipType, *polytree, ClipperLib::pftNonZero, ClipperLib::pftNonZero);
// convert into ExPolygons // convert into ExPolygons
PolyTreeToExPolygons(*polytree, retval); PolyTreeToExPolygons(*polytree, retval);
delete polytree; delete polytree;
} }
void
diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset)
{
_clipper_ex(ClipperLib::ctDifference, subject, clip, retval, safety_offset);
}
void intersection_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval,
bool safety_offset)
{
_clipper_ex(ClipperLib::ctIntersection, subject, clip, retval, safety_offset);
}
void xor_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval,
bool safety_offset)
{
_clipper_ex(ClipperLib::ctXor, subject, clip, retval, safety_offset);
}
void union_ex(Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool safety_offset)
{
Slic3r::Polygons p;
_clipper_ex(ClipperLib::ctUnion, subject, p, retval, safety_offset);
}
} }

View file

@ -30,7 +30,15 @@ void offset2_ex(Slic3r::Polygons &polygons, Slic3r::ExPolygons &retval, const fl
const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter, const float delta2, double scale = 100000, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3); double miterLimit = 3);
void diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset); inline void _clipper_ex(ClipperLib::ClipType clipType, Slic3r::Polygons &subject,
Slic3r::Polygons &clip, Slic3r::ExPolygons &retval,
bool safety_offset);
void diff_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval, bool safety_offset = false);
void intersection_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval,
bool safety_offset = false);
void xor_ex(Slic3r::Polygons &subject, Slic3r::Polygons &clip, Slic3r::ExPolygons &retval,
bool safety_offset = false);
void union_ex(Slic3r::Polygons &subject, Slic3r::ExPolygons &retval, bool safety_offset = false);
} }

View file

@ -45,4 +45,33 @@ diff_ex(subject, clip, safety_offset = false)
OUTPUT: OUTPUT:
RETVAL RETVAL
ExPolygons
intersection_ex(subject, clip, safety_offset = false)
Polygons subject
Polygons clip
bool safety_offset
CODE:
intersection_ex(subject, clip, RETVAL, safety_offset);
OUTPUT:
RETVAL
ExPolygons
xor_ex(subject, clip, safety_offset = false)
Polygons subject
Polygons clip
bool safety_offset
CODE:
xor_ex(subject, clip, RETVAL, safety_offset);
OUTPUT:
RETVAL
ExPolygons
union_ex(subject, safety_offset = false)
Polygons subject
bool safety_offset
CODE:
union_ex(subject, RETVAL, safety_offset);
OUTPUT:
RETVAL
%} %}

View file

@ -14,6 +14,7 @@ SurfaceCollection* O_OBJECT
ExtrusionRole T_UV ExtrusionRole T_UV
SurfaceType T_UV SurfaceType T_UV
ClipperLib::JoinType T_UV ClipperLib::JoinType T_UV
ClipperLib::PolyFillType T_UV
Lines T_ARRAYREF Lines T_ARRAYREF
Polygons T_ARRAYREF Polygons T_ARRAYREF