mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 09:17:52 -06:00
Ported diff_ex, intersection_ex, union_ex, xor_ex
This commit is contained in:
parent
f7ada2b5db
commit
bf8c799685
9 changed files with 72 additions and 48 deletions
|
@ -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,
|
||||||
)};
|
)};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue