Bugfix: lack of strong type checking when passing arrayref objects to XS caused random lack of infill. Now added strong type checking for all XS entities. Also fixes a potential issue with bridges caused by the same error. #1652

Conflicts:

	lib/Slic3r/Layer/Region.pm
This commit is contained in:
Alessandro Ranellucci 2014-01-12 00:54:10 +01:00
parent e68cbede6e
commit a51743a8c1
9 changed files with 31 additions and 5 deletions

View File

@ -118,7 +118,7 @@ sub fill_surface {
# clip paths again to prevent connection segments from crossing the expolygon boundaries
@paths = @{intersection_pl(
\@paths,
[ @{$surface->expolygon->offset_ex(scaled_epsilon)} ],
[ map @$_, @{$surface->expolygon->offset_ex(scaled_epsilon)} ],
)};
}

View File

@ -132,7 +132,7 @@ sub make_perimeters {
# make sure we don't infill narrow parts that are already gap-filled
# (we only consider this surface's gaps to reduce the diff() complexity)
@last = @{diff(\@last, \@last_gaps)};
@last = @{diff(\@last, [ map @$_, @last_gaps ])};
# create one more offset to be used as boundary for fill
# we offset by half the perimeter spacing (to get to the actual infill boundary)
@ -420,7 +420,7 @@ sub _detect_bridge_direction {
my $perimeter_flow = $self->flow(FLOW_ROLE_PERIMETER);
my $infill_flow = $self->flow(FLOW_ROLE_INFILL);
my $grown = $expolygon->offset_ex(+$perimeter_flow->scaled_width);
my $grown = $expolygon->offset(+$perimeter_flow->scaled_width);
my @lower = @{$lower_layer->slices}; # expolygons
# detect what edges lie on lower slices
@ -428,7 +428,7 @@ sub _detect_bridge_direction {
foreach my $lower (@lower) {
# turn bridge contour and holes into polylines and then clip them
# with each lower slice's contour
my @clipped = @{intersection_pl([ map $_->split_at_first_point, map @$_, @$grown ], [$lower->contour])};
my @clipped = @{intersection_pl([ map $_->split_at_first_point, @$grown ], [$lower->contour])};
if (@clipped == 2) {
# If the split_at_first_point() call above happens to split the polygon inside the clipping area
# we would get two consecutive polylines instead of a single one, so we use this ugly hack to
@ -479,7 +479,7 @@ sub _detect_bridge_direction {
# detect anchors as intersection between our bridge expolygon and the lower slices
my $anchors = intersection_ex(
[ @$grown ],
$grown,
[ map @$_, @lower ],
1, # safety offset required to avoid Clipper from detecting empty intersection while Boost actually found some @edges
);

View File

@ -180,6 +180,8 @@ void
ExPolygon::from_SV_check(SV* expoly_sv)
{
if (sv_isobject(expoly_sv) && (SvTYPE(SvRV(expoly_sv)) == SVt_PVMG)) {
if (!sv_isa(expoly_sv, "Slic3r::ExPolygon") && !sv_isa(expoly_sv, "Slic3r::ExPolygon::Ref"))
CONFESS("Not a valid Slic3r::ExPolygon object");
// a XS ExPolygon was supplied
*this = *(ExPolygon *)SvIV((SV*)SvRV( expoly_sv ));
} else {

View File

@ -88,6 +88,8 @@ void
Line::from_SV_check(SV* line_sv)
{
if (sv_isobject(line_sv) && (SvTYPE(SvRV(line_sv)) == SVt_PVMG)) {
if (!sv_isa(line_sv, "Slic3r::Line") && !sv_isa(line_sv, "Slic3r::Line::Ref"))
CONFESS("Not a valid Slic3r::Line object");
*this = *(Line*)SvIV((SV*)SvRV( line_sv ));
} else {
this->from_SV(line_sv);

View File

@ -169,6 +169,8 @@ void
Point::from_SV_check(SV* point_sv)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
if (!sv_isa(point_sv, "Slic3r::Point") && !sv_isa(point_sv, "Slic3r::Point::Ref"))
CONFESS("Not a valid Slic3r::Point object");
*this = *(Point*)SvIV((SV*)SvRV( point_sv ));
} else {
this->from_SV(point_sv);

View File

@ -166,6 +166,15 @@ Polygon::to_SV_clone_ref() const {
sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(*this) );
return sv;
}
void
Polygon::from_SV_check(SV* poly_sv)
{
if (sv_isobject(poly_sv) && !sv_isa(poly_sv, "Slic3r::Polygon") && !sv_isa(poly_sv, "Slic3r::Polygon::Ref"))
CONFESS("Not a valid Slic3r::Polygon object");
MultiPoint::from_SV_check(poly_sv);
}
#endif
}

View File

@ -32,6 +32,7 @@ class Polygon : public MultiPoint {
void simplify(double tolerance, Polygons &polygons) const;
#ifdef SLIC3RXS
void from_SV_check(SV* poly_sv);
SV* to_SV_ref();
SV* to_SV_clone_ref() const;
#endif

View File

@ -110,6 +110,15 @@ Polyline::to_SV_clone_ref() const
sv_setref_pv( sv, "Slic3r::Polyline", new Polyline(*this) );
return sv;
}
void
Polyline::from_SV_check(SV* poly_sv)
{
if (!sv_isa(poly_sv, "Slic3r::Polyline") && !sv_isa(poly_sv, "Slic3r::Polyline::Ref"))
CONFESS("Not a valid Slic3r::Polyline object");
MultiPoint::from_SV_check(poly_sv);
}
#endif
}

View File

@ -20,6 +20,7 @@ class Polyline : public MultiPoint {
void simplify(double tolerance);
#ifdef SLIC3RXS
void from_SV_check(SV* poly_sv);
SV* to_SV_ref();
SV* to_SV_clone_ref() const;
#endif