From fb7f98b51df990d239c2bb5a06492b0a5585fade Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 22 Sep 2020 22:05:24 +0100 Subject: [PATCH] Implement visual zone dumping and fix the default fill algo setting. --- pcbnew/class_zone.cpp | 13 +++++++-- pcbnew/class_zone.h | 1 + pcbnew/pcb_painter.cpp | 6 +++- pcbnew/zone_filler.cpp | 64 +++++++++++++++++++++++------------------- pcbnew/zone_filler.h | 2 ++ 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 00e4170aca..144cdcc914 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -36,7 +36,7 @@ #include #include #include - +#include "zone_filler.h" ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent, bool aInModule ) : BOARD_CONNECTED_ITEM( aParent, aInModule ? PCB_MODULE_ZONE_AREA_T : PCB_ZONE_AREA_T ), @@ -67,7 +67,7 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent, bool aInModule ) m_cornerRadius = 0; SetLocalFlags( 0 ); // flags tempoarry used in zone calculations m_Poly = new SHAPE_POLY_SET(); // Outlines - m_fillVersion = 6; // set the "old" way to build filled polygon areas (before 6.0.x) + m_fillVersion = 5; // set the "old" way to build filled polygon areas (before 6.0.x) m_islandRemovalMode = ISLAND_REMOVAL_MODE::ALWAYS; aParent->GetZoneSettings().ExportSetting( *this ); @@ -363,6 +363,15 @@ void ZONE_CONTAINER::SetCornerRadius( unsigned int aRadius ) } +bool ZONE_CONTAINER::GetFilledPolysUseThickness( PCB_LAYER_ID aLayer ) const +{ + if( ZONE_FILLER::s_DumpZonesWhenFilling && LSET::InternalCuMask().Contains( aLayer ) ) + return false; + + return GetFilledPolysUseThickness(); +} + + bool ZONE_CONTAINER::HitTest( const wxPoint& aPosition, int aAccuracy ) const { // Normally accuracy is zoom-relative, but for the generic HitTest we just use diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index e74e36cd24..e2dedb934e 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -680,6 +680,7 @@ public: unsigned int GetCornerRadius() const { return m_cornerRadius; } bool GetFilledPolysUseThickness() const { return m_fillVersion == 5; } + bool GetFilledPolysUseThickness( PCB_LAYER_ID aLayer ) const; int GetFillVersion() const { return m_fillVersion; } void SetFillVersion( int aVersion ) { m_fillVersion = aVersion; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 61f459f58c..cc7675bd63 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -1260,7 +1260,11 @@ void PCB_PAINTER::draw( const ZONE_CONTAINER* aZone, int aLayer ) return; // Set up drawing options - int outline_thickness = aZone->GetFilledPolysUseThickness() ? aZone->GetMinThickness() : 0; + int outline_thickness = 0; + + if( aZone->GetFilledPolysUseThickness( layer ) ) + outline_thickness = aZone->GetMinThickness(); + m_gal->SetStrokeColor( color ); m_gal->SetFillColor( color ); m_gal->SetLineWidth( outline_thickness ); diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index e756d3a6bb..470e6c7d25 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,6 @@ #include "zone_filler.h" static const double s_RoundPadThermalSpokeAngle = 450; // in deci-degrees -static const bool s_DumpZonesWhenFilling = false; ZONE_FILLER::ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit ) : @@ -324,6 +322,9 @@ bool ZONE_FILLER::Fill( std::vector& aZones, bool aCheck, wxWin { for( PCB_LAYER_ID layer : zone.m_zone->GetLayerSet().Seq() ) { + if( s_DumpZonesWhenFilling && LSET::InternalCuMask().Contains( layer ) ) + continue; + if( !zone.m_islands.count( layer ) ) continue; @@ -362,6 +363,9 @@ bool ZONE_FILLER::Fill( std::vector& aZones, bool aCheck, wxWin { for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) { + if( s_DumpZonesWhenFilling && LSET::InternalCuMask().Contains( layer ) ) + continue; + SHAPE_POLY_SET poly = zone->GetFilledPolysList( layer ); for( int ii = 0; ii < poly.OutlineCount(); ii++ ) @@ -893,6 +897,18 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, PCB_LA } +#define DUMP_POLYS_TO_COPPER_LAYER( a, b, c ) \ + { if( s_DumpZonesWhenFilling && dumpLayer == b ) \ + { \ + m_board->SetLayerName( b, c ); \ + a.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); \ + a.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); \ + aRawPolys = a; \ + aFinalPolys = a; \ + return; \ + } \ + } + /** * 1 - Creates the main zone outline using a correction to shrink the resulting area by * m_ZoneMinThickness / 2. The result is areas with a margin of m_ZoneMinThickness / 2 @@ -909,6 +925,11 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I SHAPE_POLY_SET& aRawPolys, SHAPE_POLY_SET& aFinalPolys ) { + PCB_LAYER_ID dumpLayer = aLayer; + + if( s_DumpZonesWhenFilling && LSET::InternalCuMask().Contains( aLayer ) ) + aLayer = F_Cu; + m_maxError = m_board->GetDesignSettings().m_MaxError; // Features which are min_width should survive pruning; features that are *less* than @@ -928,30 +949,20 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I std::deque thermalSpokes; SHAPE_POLY_SET clearanceHoles; - std::unique_ptr dumper( new SHAPE_FILE_IO( - s_DumpZonesWhenFilling ? "zones_dump.txt" : "", SHAPE_FILE_IO::IOM_APPEND ) ); - aRawPolys = aSmoothedOutline; - - if( s_DumpZonesWhenFilling ) - dumper->BeginGroup( "clipper-zone" ); + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In1_Cu, "smoothed-outline" ); if( m_progressReporter && m_progressReporter->IsCancelled() ) return; knockoutThermalReliefs( aZone, aLayer, aRawPolys ); - - if( s_DumpZonesWhenFilling ) - dumper->Write( &aRawPolys, "solid-areas-minus-thermal-reliefs" ); + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In2_Cu, "minus-thermal-reliefs" ); if( m_progressReporter && m_progressReporter->IsCancelled() ) return; buildCopperItemClearances( aZone, aLayer, clearanceHoles ); - if( s_DumpZonesWhenFilling ) - dumper->Write( &aRawPolys, "clearance holes" ); - if( m_progressReporter && m_progressReporter->IsCancelled() ) return; @@ -965,12 +976,16 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I static const bool USE_BBOX_CACHES = true; SHAPE_POLY_SET testAreas = aRawPolys; testAreas.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST ); + DUMP_POLYS_TO_COPPER_LAYER( testAreas, In3_Cu, "minus-clearance-holes" ); // Prune features that don't meet minimum-width criteria if( half_min_width - epsilon > epsilon ) { testAreas.Deflate( half_min_width - epsilon, numSegs, cornerStrategy ); + DUMP_POLYS_TO_COPPER_LAYER( testAreas, In4_Cu, "spoke-test-deflated" ); + testAreas.Inflate( half_min_width - epsilon, numSegs, cornerStrategy ); + DUMP_POLYS_TO_COPPER_LAYER( testAreas, In5_Cu, "spoke-test-reinflated" ); } if( m_progressReporter && m_progressReporter->IsCancelled() ) @@ -1011,23 +1026,19 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I } } - if( m_progressReporter && m_progressReporter->IsCancelled() ) - return; - - if( s_DumpZonesWhenFilling ) - dumper->Write( &aRawPolys, "solid-areas-with-thermal-spokes" ); + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In6_Cu, "plus-spokes" ); if( m_progressReporter && m_progressReporter->IsCancelled() ) return; aRawPolys.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST ); + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In7_Cu, "trimmed-spokes" ); // Prune features that don't meet minimum-width criteria if( half_min_width - epsilon > epsilon ) aRawPolys.Deflate( half_min_width - epsilon, numSegs, cornerStrategy ); - if( s_DumpZonesWhenFilling ) - dumper->Write( &aRawPolys, "solid-areas-before-hatching" ); + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In8_Cu, "deflated" ); if( m_progressReporter && m_progressReporter->IsCancelled() ) return; @@ -1036,8 +1047,7 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN ) addHatchFillTypeOnZone( aZone, aLayer, aRawPolys ); - if( s_DumpZonesWhenFilling ) - dumper->Write( &aRawPolys, "solid-areas-after-hatching" ); + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In9_Cu, "after-hatching" ); if( m_progressReporter && m_progressReporter->IsCancelled() ) return; @@ -1053,6 +1063,8 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I aRawPolys.Inflate( half_min_width - epsilon, numSegs, cornerStrategy ); } + DUMP_POLYS_TO_COPPER_LAYER( aRawPolys, In10_Cu, "after-reinflating" ); + // Ensure additive changes (thermal stubs and particularly inflating acute corners) do not // add copper outside the zone boundary or inside the clearance holes aRawPolys.BooleanIntersection( aSmoothedOutline, SHAPE_POLY_SET::PM_FAST ); @@ -1060,13 +1072,7 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone, PCB_LAYER_I aRawPolys.Fracture( SHAPE_POLY_SET::PM_FAST ); - if( s_DumpZonesWhenFilling ) - dumper->Write( &aRawPolys, "areas_fractured" ); - aFinalPolys = aRawPolys; - - if( s_DumpZonesWhenFilling ) - dumper->EndGroup(); } diff --git a/pcbnew/zone_filler.h b/pcbnew/zone_filler.h index b74ca75137..233c948fa6 100644 --- a/pcbnew/zone_filler.h +++ b/pcbnew/zone_filler.h @@ -47,6 +47,8 @@ public: bool Fill( std::vector& aZones, bool aCheck = false, wxWindow* aParent = nullptr ); + static const bool s_DumpZonesWhenFilling = true; + private: void addKnockout( D_PAD* aPad, PCB_LAYER_ID aLayer, int aGap, SHAPE_POLY_SET& aHoles );