Thermal reliefs: fix a corner case that wrongly removes a stub in a thermal shape.

This was due to the stub removal tests if a stub end is outside a solid area to remove it.
There is a corner case: is the stub end is exactly on a solid area outline extra segment
created by Fracture() used in calculations.

The stub removal tests are now made before fracturing.

Fixes: lp:1819317
https://bugs.launchpad.net/kicad/+bug/1819317
(cherry picked from commit b9944e2c06)
This commit is contained in:
jean-pierre charras 2019-03-10 17:57:26 +01:00 committed by Seth Hillbrand
parent de22148b44
commit 5424223949
1 changed files with 18 additions and 11 deletions

View File

@ -750,21 +750,18 @@ void ZONE_FILLER::computeRawFilledAreas( const ZONE_CONTAINER* aZone,
if( s_DumpZonesWhenFilling )
dumper->Write( &solidAreas, "solid-areas-minus-holes" );
SHAPE_POLY_SET areas_fractured = solidAreas;
areas_fractured.Fracture( SHAPE_POLY_SET::PM_FAST );
if( s_DumpZonesWhenFilling )
dumper->Write( &areas_fractured, "areas_fractured" );
aFinalPolys = areas_fractured;
SHAPE_POLY_SET thermalHoles;
// Test thermal stubs connections and add polygons to remove unconnected stubs.
// (this is a refinement for thermal relief shapes)
// Note: we are using not fractured solid area polygons, to avoid a side effect of extra segments
// created by Fracture(): if a tested point used in buildUnconnectedThermalStubsPolygonList
// is on a extra segment, the tested point is seen outside the solid area, but it is inside.
// This is not a bug, just the fact when a point is on a polygon outline, it is hard to say
// if it is inside or outside the polygon.
SHAPE_POLY_SET thermalHoles;
if( aZone->GetNetCode() > 0 )
{
buildUnconnectedThermalStubsPolygonList( thermalHoles, aZone, aFinalPolys,
buildUnconnectedThermalStubsPolygonList( thermalHoles, aZone, solidAreas,
correctionFactor, s_thermalRot );
}
@ -790,6 +787,16 @@ void ZONE_FILLER::computeRawFilledAreas( const ZONE_CONTAINER* aZone,
aFinalPolys = th_fractured;
}
else
{
SHAPE_POLY_SET areas_fractured = solidAreas;
areas_fractured.Fracture( SHAPE_POLY_SET::PM_FAST );
if( s_DumpZonesWhenFilling )
dumper->Write( &areas_fractured, "areas_fractured" );
aFinalPolys = areas_fractured;
}
aRawPolys = aFinalPolys;