From b9944e2c06f5c56294051ddd360066e80773ced3 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 10 Mar 2019 17:57:26 +0100 Subject: [PATCH] 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 --- pcbnew/zone_filler.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 3c76d3bb03..a7253746be 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -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;