From 96a34e5b57ee1bee4a19e1da2fdabc887aff21d3 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Wed, 26 Jul 2023 12:36:13 -0700 Subject: [PATCH] Consolidate Maximum clearance calculation We were calculating the same thing in three locations and we missed adding the clearance from the footprints in, resulting in bad fills and missed drc errors (see QA addition) --- pcbnew/board.cpp | 21 + pcbnew/board.h | 7 + pcbnew/drc/drc_cache_generator.cpp | 23 +- pcbnew/footprint.cpp | 2 +- pcbnew/pad.cpp | 2 +- pcbnew/router/pns_kicad_iface.cpp | 2 +- pcbnew/zone_filler.cpp | 10 +- qa/data/pcbnew/fill_bad.kicad_pcb | 248 +++++++++ qa/data/pcbnew/fill_bad.kicad_pro | 528 +++++++++++++++++++ qa/data/pcbnew/issue6039.kicad_pro | 10 +- qa/tests/pcbnew/drc/test_drc_regressions.cpp | 3 +- qa/tests/pcbnew/test_zone_filler.cpp | 3 +- 12 files changed, 819 insertions(+), 40 deletions(-) create mode 100644 qa/data/pcbnew/fill_bad.kicad_pcb create mode 100644 qa/data/pcbnew/fill_bad.kicad_pro diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index 03be3a7e4e..75f9dd00cb 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -742,6 +742,27 @@ void BOARD::SetZoneSettings( const ZONE_SETTINGS& aSettings ) GetDesignSettings().SetDefaultZoneSettings( aSettings ); } +int BOARD::GetMaxClearanceValue() const +{ + int worstClearance = m_designSettings->GetBiggestClearanceValue(); + + for( ZONE* zone : m_zones ) + worstClearance = std::max( worstClearance, zone->GetLocalClearance() ); + + for( FOOTPRINT* footprint : m_footprints ) + { + worstClearance = std::max( worstClearance, footprint->GetLocalClearance() ); + + for( PAD* pad : footprint->Pads() ) + worstClearance = std::max( worstClearance, pad->GetLocalClearance() ); + + for( ZONE* zone : footprint->Zones() ) + worstClearance = std::max( worstClearance, zone->GetLocalClearance() ); + } + + return worstClearance; +} + void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector& aZones ) { diff --git a/pcbnew/board.h b/pcbnew/board.h index a39fe0d011..d5453608aa 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -1086,6 +1086,13 @@ public: FOOTPRINT* GetFootprint( const VECTOR2I& aPosition, PCB_LAYER_ID aActiveLayer, bool aVisibleOnly, bool aIgnoreLocked = false ) const; + /** + * Returns the maximum clearance value for any object on the board. This considers + * the clearances from board design settings as well as embedded clearances in footprints, + * pads and zones. Includes electrical, physical, hole and edge clearances. + */ + int GetMaxClearanceValue() const; + /** * Map all nets in the given board to nets with the same name (if any) in the destination * board. This allows us to share layouts which came from the same hierarchical sheet in diff --git a/pcbnew/drc/drc_cache_generator.cpp b/pcbnew/drc/drc_cache_generator.cpp index c4185e1ba2..18ec5b6a7f 100644 --- a/pcbnew/drc/drc_cache_generator.cpp +++ b/pcbnew/drc/drc_cache_generator.cpp @@ -35,22 +35,18 @@ bool DRC_CACHE_GENERATOR::Run() { m_board = m_drcEngine->GetBoard(); - int& m_largestClearance = m_board->m_DRCMaxClearance; - int& m_largestPhysicalClearance = m_board->m_DRCMaxPhysicalClearance; + int& largestClearance = m_board->m_DRCMaxClearance; + int& largestPhysicalClearance = m_board->m_DRCMaxPhysicalClearance; DRC_CONSTRAINT worstConstraint; LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() ); - if( m_drcEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, worstConstraint ) ) - m_largestClearance = worstConstraint.GetValue().Min(); - - if( m_drcEngine->QueryWorstConstraint( HOLE_CLEARANCE_CONSTRAINT, worstConstraint ) ) - m_largestClearance = std::max( m_largestClearance, worstConstraint.GetValue().Min() ); + largestClearance = std::max( largestClearance, m_board->GetMaxClearanceValue() ); if( m_drcEngine->QueryWorstConstraint( PHYSICAL_CLEARANCE_CONSTRAINT, worstConstraint ) ) - m_largestPhysicalClearance = worstConstraint.GetValue().Min(); + largestPhysicalClearance = worstConstraint.GetValue().Min(); if( m_drcEngine->QueryWorstConstraint( PHYSICAL_HOLE_CLEARANCE_CONSTRAINT, worstConstraint ) ) - m_largestPhysicalClearance = std::max( m_largestPhysicalClearance, worstConstraint.GetValue().Min() ); + largestPhysicalClearance = std::max( largestPhysicalClearance, worstConstraint.GetValue().Min() ); std::set allZones; @@ -65,16 +61,12 @@ bool DRC_CACHE_GENERATOR::Run() if( ( zone->GetLayerSet() & boardCopperLayers ).any() ) { m_board->m_DRCCopperZones.push_back( zone ); - m_largestClearance = std::max( m_largestClearance, zone->GetLocalClearance() ); } } } for( FOOTPRINT* footprint : m_board->Footprints() ) { - for( PAD* pad : footprint->Pads() ) - m_largestClearance = std::max( m_largestClearance, pad->GetLocalClearance() ); - for( ZONE* zone : footprint->Zones() ) { allZones.insert( zone ); @@ -84,10 +76,7 @@ bool DRC_CACHE_GENERATOR::Run() m_board->m_DRCZones.push_back( zone ); if( ( zone->GetLayerSet() & boardCopperLayers ).any() ) - { m_board->m_DRCCopperZones.push_back( zone ); - m_largestClearance = std::max( m_largestClearance, zone->GetLocalClearance() ); - } } } } @@ -124,7 +113,7 @@ bool DRC_CACHE_GENERATOR::Run() for( PCB_LAYER_ID layer : copperLayers.Seq() ) { if( IsCopperLayer( layer ) ) - m_board->m_CopperItemRTreeCache->Insert( item, layer, m_largestClearance ); + m_board->m_CopperItemRTreeCache->Insert( item, layer, largestClearance ); } return true; diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 1837b0fcb1..93e69145a3 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -1684,7 +1684,7 @@ const BOX2I FOOTPRINT::ViewBBox() const // Inflate in case clearance lines are drawn around pads, etc. if( const BOARD* board = GetBoard() ) { - int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue(); + int biggest_clearance = board->GetMaxClearanceValue(); area.Inflate( biggest_clearance ); } diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index cd6afec863..d8e0daa686 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -1449,7 +1449,7 @@ const BOX2I PAD::ViewBBox() const if( PCBNEW_SETTINGS* cfg = dynamic_cast( Kiface().KifaceSettings() ) ) { if( cfg && cfg->m_Display.m_PadClearance && GetBoard() ) - clearance = GetBoard()->GetDesignSettings().GetBiggestClearanceValue(); + clearance = GetBoard()->GetMaxClearanceValue(); } // Look for the biggest possible bounding box diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index 1de0d74bb8..edcf3fe4e2 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -1519,7 +1519,7 @@ void PNS_KICAD_IFACE_BASE::SyncWorld( PNS::NODE *aWorld ) return; } - int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue(); + int worstClearance = m_board->GetMaxClearanceValue(); m_world = aWorld; diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index eb76dd6889..5e477c2961 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -100,7 +100,7 @@ bool ZONE_FILLER::Fill( std::vector& aZones, bool aCheck, wxWindow* aPare BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - m_worstClearance = bds.GetBiggestClearanceValue(); + m_worstClearance = m_board->GetMaxClearanceValue(); if( m_progressReporter ) { @@ -118,10 +118,7 @@ bool ZONE_FILLER::Fill( std::vector& aZones, bool aCheck, wxWindow* aPare // make them thread-safe. // for( ZONE* zone : m_board->Zones() ) - { zone->CacheBoundingBox(); - m_worstClearance = std::max( m_worstClearance, zone->GetLocalClearance() ); - } for( FOOTPRINT* footprint : m_board->Footprints() ) { @@ -132,15 +129,10 @@ bool ZONE_FILLER::Fill( std::vector& aZones, bool aCheck, wxWindow* aPare pad->BuildEffectiveShapes( UNDEFINED_LAYER ); pad->BuildEffectivePolygon(); } - - m_worstClearance = std::max( m_worstClearance, pad->GetLocalClearance() ); } for( ZONE* zone : footprint->Zones() ) - { zone->CacheBoundingBox(); - m_worstClearance = std::max( m_worstClearance, zone->GetLocalClearance() ); - } // Rules may depend on insideCourtyard() or other expressions footprint->BuildCourtyardCaches(); diff --git a/qa/data/pcbnew/fill_bad.kicad_pcb b/qa/data/pcbnew/fill_bad.kicad_pcb new file mode 100644 index 0000000000..69ed798312 --- /dev/null +++ b/qa/data/pcbnew/fill_bad.kicad_pcb @@ -0,0 +1,248 @@ +(kicad_pcb (version 20230620) (generator pcbnew) + + (general + (thickness 0.8) + ) + + (paper "A4") + (layers + (0 "F.Cu" signal) + (1 "In1.Cu" signal) + (2 "In2.Cu" signal) + (31 "B.Cu" signal) + (32 "B.Adhes" user "B.Adhesive") + (33 "F.Adhes" user "F.Adhesive") + (34 "B.Paste" user) + (35 "F.Paste" user) + (36 "B.SilkS" user "B.Silkscreen") + (37 "F.SilkS" user "F.Silkscreen") + (38 "B.Mask" user) + (39 "F.Mask" user) + (40 "Dwgs.User" user "User.Drawings") + (41 "Cmts.User" user "User.Comments") + (42 "Eco1.User" user "User.Eco1") + (43 "Eco2.User" user "User.Eco2") + (44 "Edge.Cuts" user) + (45 "Margin" user) + (46 "B.CrtYd" user "B.Courtyard") + (47 "F.CrtYd" user "F.Courtyard") + (48 "B.Fab" user) + (49 "F.Fab" user) + ) + + (setup + (stackup + (layer "F.SilkS" (type "Top Silk Screen")) + (layer "F.Paste" (type "Top Solder Paste")) + (layer "F.Mask" (type "Top Solder Mask") (thickness 0.01)) + (layer "F.Cu" (type "copper") (thickness 0.035)) + (layer "dielectric 1" (type "prepreg") (thickness 0.1) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02)) + (layer "In1.Cu" (type "copper") (thickness 0.035)) + (layer "dielectric 2" (type "core") (thickness 0.44) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02)) + (layer "In2.Cu" (type "copper") (thickness 0.035)) + (layer "dielectric 3" (type "prepreg") (thickness 0.1) (material "FR4") (epsilon_r 4.5) (loss_tangent 0.02)) + (layer "B.Cu" (type "copper") (thickness 0.035)) + (layer "B.Mask" (type "Bottom Solder Mask") (thickness 0.01)) + (layer "B.Paste" (type "Bottom Solder Paste")) + (layer "B.SilkS" (type "Bottom Silk Screen")) + (copper_finish "None") + (dielectric_constraints no) + ) + (pad_to_mask_clearance 0) + (pcbplotparams + (layerselection 0x00310fc_ffffffff) + (plot_on_all_layers_selection 0x0000000_00000000) + (disableapertmacros false) + (usegerberextensions true) + (usegerberattributes false) + (usegerberadvancedattributes false) + (creategerberjobfile false) + (dashed_line_dash_ratio 12.000000) + (dashed_line_gap_ratio 3.000000) + (svgprecision 6) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (pdf_front_fp_property_popups true) + (pdf_back_fp_property_popups true) + (dxfpolygonmode true) + (dxfimperialunits false) + (dxfusepcbnewfont true) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue false) + (plotinvisibletext false) + (sketchpadsonfab false) + (subtractmaskfromsilk true) + (outputformat 1) + (mirror false) + (drillshape 0) + (scaleselection 1) + (outputdirectory "production") + ) + ) + + (property "PROJECT_ID" "726") + (property "PROJECT_NAME" "sbm-swappable-battery-module") + (property "PROJECT_NUMBER" "1743") + (property "PROJECT_VERSION" "V1.0.0") + + (net 0 "") + (net 1 "A") + (net 2 "B") + + (footprint "lib:SolderWirePad_1x01_SMD_2.9x7.8mm" (layer "F.Cu") + (tstamp 985a7dcf-c008-45a3-beea-302b347528bd) + (at 43.415695 32.455979) + (descr "Wire Pad, Square, SMD Pad, 2.9mm x 7.8mm,") + (tags "MesurementPoint Square SMDPad 2.9mmx7.8mm ") + (property "Reference" "J2" (at 0 -5 0) (layer "F.SilkS") hide (tstamp ac0323d0-f9d1-415d-8ab0-4f2b542b7105) + (effects (font (size 1 1) (thickness 0.15))) + ) + (property "Value" "CELL2" (at 0 2.54 0) (layer "F.Fab") (tstamp ee4ebfd6-b470-4619-8a05-587482ca9107) + (effects (font (size 1 1) (thickness 0.15))) + ) + (property "Footprint" "" (at 0 0 0 unlocked) (layer "F.Fab") hide (tstamp 132e5ecd-832a-43a1-bd36-f8d2f08d9111) + (effects (font (size 1.27 1.27))) + ) + (property "Datasheet" "" (at 0 0 0 unlocked) (layer "F.Fab") hide (tstamp de9c06cd-cc8f-480e-88b8-0b8b0e8513d3) + (effects (font (size 1.27 1.27))) + ) + (property "Description" "Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)" (at 0 0 0 unlocked) (layer "F.Fab") hide (tstamp 96b75f7f-efa2-4720-b13b-389d9d633236) + (effects (font (size 1.27 1.27))) + ) + (path "/91b6036e-0932-4b4d-be06-d288cef86586") + (sheetfile "prj.kicad_sch") + (clearance 1) + (attr exclude_from_pos_files exclude_from_bom) + (fp_line (start -1.8 -4.25) (end -1.8 4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp cbf60708-41dc-406e-93fd-3eef2d09e171)) + (fp_line (start -1.8 -4.25) (end 1.8 -4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 9ab144db-ea9d-4b42-b580-0b5c3609563a)) + (fp_line (start -1.8 4.25) (end 1.8 4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d825f37d-1d08-4e80-a724-6f49cb22d11d)) + (fp_line (start 1.8 4.25) (end 1.8 -4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e2990c39-af71-4866-856c-0e69ec4b057c)) + (fp_line (start -0.63 1.27) (end -0.63 -1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3717a07f-2ca1-438e-8252-f4f0e7118a61)) + (fp_line (start 0.63 -1.27) (end 0.63 1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3eb3e3dc-a49f-4bdc-b602-89cabfabd598)) + (fp_line (start 0.63 1.27) (end -0.63 1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 1260bb2d-354e-4a5b-8a86-af46d5621096)) + (fp_text user "${REFERENCE}" (at 0 0 0) (layer "F.Fab") (tstamp 7506a551-abf0-4da1-b5ba-412716d0cda2) + (effects (font (size 1 1) (thickness 0.15))) + ) + (pad "1" smd roundrect (at 0 0) (size 2.6 7.5) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.1) + (net 2 "B") (pinfunction "Pin_1") (pintype "passive") + (tstamp 01d6b91f-b519-4000-9ea0-db5a3aad940e) + ) + ) + + (footprint "lib:SolderWirePad_1x01_SMD_2.9x7.8mm" (layer "F.Cu") + (tstamp a6236385-3cd5-4b9e-b0ab-d5b0da6d6f5f) + (at 36.750695 25.759979 -90) + (descr "Wire Pad, Square, SMD Pad, 2.9mm x 7.8mm,") + (tags "MesurementPoint Square SMDPad 2.9mmx7.8mm ") + (property "Reference" "J1" (at 0 -5 90) (layer "F.SilkS") hide (tstamp 4cc314e5-52bd-4cbf-bfa6-75b6e1d965d6) + (effects (font (size 1 1) (thickness 0.15))) + ) + (property "Value" "CELL3" (at 0 2.54 90) (layer "F.Fab") (tstamp 3f2e07ef-e2e7-46a1-8808-6cad1c39ee0d) + (effects (font (size 1 1) (thickness 0.15))) + ) + (property "Footprint" "" (at 0 0 -90 unlocked) (layer "F.Fab") hide (tstamp 00cc72aa-5cbb-4759-9109-da5bedbf8875) + (effects (font (size 1.27 1.27))) + ) + (property "Datasheet" "" (at 0 0 -90 unlocked) (layer "F.Fab") hide (tstamp 61a02f88-4556-4f60-acb1-8e258fd9e93b) + (effects (font (size 1.27 1.27))) + ) + (property "Description" "Generic connector, single row, 01x01, script generated (kicad-library-utils/schlib/autogen/connector/)" (at 0 0 -90 unlocked) (layer "F.Fab") hide (tstamp 0b01f958-4be9-4ed1-b246-813a8218eab6) + (effects (font (size 1.27 1.27))) + ) + (property "exclude_from_bom" "" (at 0 0 0) (layer "F.Fab") hide (tstamp 39446602-4c58-47e6-bb20-782f536cdd9e) + (effects (font (size 1 1) (thickness 0.15))) + ) + (path "/5ad82b76-2335-44e8-a6b4-714733473d51") + (sheetfile "prj.kicad_sch") + (clearance 1) + (attr exclude_from_pos_files exclude_from_bom) + (fp_line (start -1.8 4.25) (end 1.8 4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 57a45e4d-441c-4e4e-a353-f1fe755abc3e)) + (fp_line (start 1.8 4.25) (end 1.8 -4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d4b8af1c-7a09-401a-a2ae-3eac5d829e3e)) + (fp_line (start -1.8 -4.25) (end -1.8 4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 8695f857-504f-488c-b70e-52ba78f15ba0)) + (fp_line (start -1.8 -4.25) (end 1.8 -4.25) + (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 14150567-0f61-4d40-86d9-e9cfdfc67e54)) + (fp_line (start -0.63 1.27) (end -0.63 -1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 77292bf1-0b86-4fe3-b82f-c8342f27593e)) + (fp_line (start 0.63 1.27) (end -0.63 1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 7a6ad48d-b38f-4800-8a23-0b89bcebdc52)) + (fp_line (start 0.63 -1.27) (end 0.63 1.27) + (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 2ff8271a-3b16-46cc-9ce0-2706191c79ef)) + (pad "1" smd roundrect (at 0 0 270) (size 2.6 7.5) (layers "F.Cu" "F.Mask") (roundrect_rratio 0.1) + (net 1 "A") (pinfunction "Pin_1") (pintype "passive") + (tstamp 346be68c-a951-4598-9dfa-9f55a97eec49) + ) + ) + + (gr_rect (start 30.638641 20.033393) (end 47.301417 38.344136) + (stroke (width 0.15) (type default)) (fill none) (layer "Edge.Cuts") (tstamp 95593e1f-5d4b-498b-a07b-44ed17522f54)) + + (zone (net 1) (net_name "A") (layer "F.Cu") (tstamp 529fe1ce-df30-480a-99f3-dacacf3a1338) (hatch edge 0.5) + (priority 1) + (connect_pads yes (clearance 0.127)) + (min_thickness 0.127) (filled_areas_thickness no) + (fill yes (thermal_gap 0.5) (thermal_bridge_width 0.5) (smoothing fillet) (radius 0.127)) + (polygon + (pts + (xy 32.425429 21.365684) + (xy 32.287681 28.387628) + (xy 42.897681 28.367628) + (xy 43.035429 21.345684) + ) + ) + (filled_polygon + (layer "F.Cu") + (pts + (xy 42.913717 21.3481) + (xy 42.953588 21.358856) + (xy 42.981891 21.375396) + (xy 43.00477 21.398683) + (xy 43.020809 21.42728) + (xy 43.030854 21.467328) + (xy 43.03272 21.483759) + (xy 42.900278 28.235242) + (xy 42.897893 28.251158) + (xy 42.886857 28.289852) + (xy 42.870555 28.317294) + (xy 42.847837 28.339613) + (xy 42.820109 28.355427) + (xy 42.781224 28.365775) + (xy 42.765269 28.367877) + (xy 32.425782 28.387367) + (xy 32.409386 28.38521) + (xy 32.384958 28.37862) + (xy 32.369522 28.374456) + (xy 32.341218 28.357915) + (xy 32.318339 28.334628) + (xy 32.3023 28.306032) + (xy 32.292254 28.265981) + (xy 32.290389 28.249556) + (xy 32.422832 21.498062) + (xy 32.425214 21.482162) + (xy 32.436253 21.443456) + (xy 32.452552 21.416019) + (xy 32.475274 21.393696) + (xy 32.502997 21.377885) + (xy 32.541891 21.367535) + (xy 32.557834 21.365434) + (xy 42.897332 21.345944) + ) + ) + ) +) diff --git a/qa/data/pcbnew/fill_bad.kicad_pro b/qa/data/pcbnew/fill_bad.kicad_pro new file mode 100644 index 0000000000..fb7cfdded3 --- /dev/null +++ b/qa/data/pcbnew/fill_bad.kicad_pro @@ -0,0 +1,528 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "board_outline_line_width": 0.15, + "copper_line_width": 0.19999999999999998, + "copper_text_italic": false, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "copper_text_upright": false, + "courtyard_line_width": 0.049999999999999996, + "dimension_precision": 4, + "dimension_units": 3, + "dimensions": { + "arrow_length": 1270000, + "extension_offset": 500000, + "keep_text_aligned": true, + "suppress_zeroes": false, + "text_position": 0, + "units_format": 1 + }, + "fab_line_width": 0.09999999999999999, + "fab_text_italic": false, + "fab_text_size_h": 1.0, + "fab_text_size_v": 1.0, + "fab_text_thickness": 0.15, + "fab_text_upright": false, + "other_line_width": 0.09999999999999999, + "other_text_italic": false, + "other_text_size_h": 1.0, + "other_text_size_v": 1.0, + "other_text_thickness": 0.15, + "other_text_upright": false, + "pads": { + "drill": 0.762, + "height": 1.524, + "width": 1.524 + }, + "silk_line_width": 0.15, + "silk_text_italic": false, + "silk_text_size_h": 0.5, + "silk_text_size_v": 0.5, + "silk_text_thickness": 0.125, + "silk_text_upright": false, + "zones": { + "45_degree_only": false, + "min_clearance": 0.127 + } + }, + "diff_pair_dimensions": [ + { + "gap": 0.0, + "via_gap": 0.0, + "width": 0.0 + } + ], + "drc_exclusions": [], + "meta": { + "filename": "board_design_settings.json", + "version": 2 + }, + "rule_severities": { + "annular_width": "error", + "clearance": "error", + "connection_width": "warning", + "copper_edge_clearance": "error", + "copper_sliver": "warning", + "courtyards_overlap": "error", + "diff_pair_gap_out_of_range": "error", + "diff_pair_uncoupled_length_too_long": "error", + "drill_out_of_range": "error", + "duplicate_footprints": "warning", + "extra_footprint": "warning", + "footprint": "error", + "footprint_type_mismatch": "error", + "hole_clearance": "error", + "hole_near_hole": "error", + "invalid_outline": "error", + "isolated_copper": "warning", + "item_on_disabled_layer": "error", + "items_not_allowed": "error", + "length_out_of_range": "error", + "lib_footprint_issues": "ignore", + "lib_footprint_mismatch": "warning", + "malformed_courtyard": "error", + "microvia_drill_out_of_range": "error", + "missing_courtyard": "error", + "missing_footprint": "warning", + "net_conflict": "warning", + "npth_inside_courtyard": "warning", + "padstack": "error", + "pth_inside_courtyard": "warning", + "shorting_items": "error", + "silk_edge_clearance": "warning", + "silk_over_copper": "warning", + "silk_overlap": "warning", + "skew_out_of_range": "error", + "solder_mask_bridge": "error", + "starved_thermal": "error", + "text_height": "warning", + "text_thickness": "warning", + "through_hole_pad_without_hole": "error", + "too_many_vias": "error", + "track_dangling": "warning", + "track_width": "error", + "tracks_crossing": "error", + "unconnected_items": "error", + "unresolved_variable": "error", + "via_dangling": "warning", + "zones_intersect": "error" + }, + "rule_severitieslegacy_courtyards_overlap": true, + "rule_severitieslegacy_no_courtyard_defined": false, + "rules": { + "allow_blind_buried_vias": false, + "allow_microvias": false, + "max_error": 0.005, + "min_clearance": 0.127, + "min_connection": 0.0, + "min_copper_edge_clearance": 0.254, + "min_hole_clearance": 0.254, + "min_hole_to_hole": 0.25, + "min_microvia_diameter": 0.19999999999999998, + "min_microvia_drill": 0.09999999999999999, + "min_resolved_spokes": 2, + "min_silk_clearance": 0.0, + "min_text_height": 0.7999999999999999, + "min_text_thickness": 0.08, + "min_through_hole_diameter": 0.19999999999999998, + "min_track_width": 0.127, + "min_via_annular_width": 0.127, + "min_via_diameter": 0.45399999999999996, + "solder_mask_to_copper_clearance": 0.0, + "use_height_for_length_calcs": true + }, + "teardrop_options": [ + { + "td_onpadsmd": true, + "td_onroundshapesonly": false, + "td_ontrackend": false, + "td_onviapad": true + } + ], + "teardrop_parameters": [ + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_round_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_rect_shape", + "td_width_to_size_filter_ratio": 0.9 + }, + { + "td_allow_use_two_tracks": true, + "td_curve_segcount": 0, + "td_height_ratio": 1.0, + "td_length_ratio": 0.5, + "td_maxheight": 2.0, + "td_maxlen": 1.0, + "td_on_pad_in_zone": false, + "td_target_name": "td_track_end", + "td_width_to_size_filter_ratio": 0.9 + } + ], + "track_widths": [ + 0.0, + 0.25, + 0.32, + 0.5, + 0.75, + 1.0, + 1.5, + 2.0, + 2.5 + ], + "via_dimensions": [ + { + "diameter": 0.0, + "drill": 0.0 + }, + { + "diameter": 0.454, + "drill": 0.2 + } + ], + "zones_allow_external_fillets": true, + "zones_use_no_outline": true + }, + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "conflicting_netclasses": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "endpoint_off_grid": "warning", + "extra_units": "error", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "lib_symbol_issues": "warning", + "missing_bidi_pin": "warning", + "missing_input_pin": "warning", + "missing_power_pin": "error", + "missing_unit": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "error", + "power_pin_not_driven": "error", + "similar_labels": "warning", + "simulation_model_issue": "ignore", + "unannotated": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "fill_bad.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12, + "clearance": 0.127, + "diff_pair_gap": 0.127, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.21, + "line_style": 0, + "microvia_diameter": 0.2, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.127, + "via_diameter": 0.454, + "via_drill": 0.2, + "wire_width": 6 + } + ], + "meta": { + "version": 3 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "plot": "", + "pos_files": "", + "specctra_dsn": "", + "step": "p-1743-sbm-swappable-battery-module.step", + "svg": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 60.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.25, + "pin_symbol_size": 0.0, + "text_offset_ratio": 0.08 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "ngspice": { + "fix_include_paths": true, + "fix_passive_vals": false, + "meta": { + "version": 0 + }, + "model_mode": 0, + "workbook_filename": "" + }, + "page_layout_descr_file": "${KICAD_USER_TEMPLATE_DIR}/UXV_Technologies.kicad_wks", + "plot_directory": "", + "spice_adjust_passive_values": false, + "spice_current_sheet_as_root": false, + "spice_external_command": "spice \"%I\"", + "spice_model_current_sheet_as_root": true, + "spice_save_all_currents": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "e67d5971-86c9-4966-a671-2c2aab2d5789", + "" + ] + ], + "text_variables": { + "PROJECT_ID": "726", + "PROJECT_NAME": "sbm-swappable-battery-module", + "PROJECT_NUMBER": "1743", + "PROJECT_VERSION": "V1.0.0" + } +} diff --git a/qa/data/pcbnew/issue6039.kicad_pro b/qa/data/pcbnew/issue6039.kicad_pro index f364a20fb4..2a30c45658 100644 --- a/qa/data/pcbnew/issue6039.kicad_pro +++ b/qa/data/pcbnew/issue6039.kicad_pro @@ -56,15 +56,7 @@ "width": 0.0 } ], - "drc_exclusions": [ - "clearance|87150000|140800000|713a642e-4662-4581-a311-4a183ae3a0a4|0e2e2e70-712c-4a91-9883-5badae873369", - "courtyards_overlap|102580000|139229999|00000000-0000-0000-0000-00005db27222|00000000-0000-0000-0000-00005e4ffe1e", - "courtyards_overlap|102580000|142700000|00000000-0000-0000-0000-00005db270f4|00000000-0000-0000-0000-00005e4ffe1e", - "courtyards_overlap|116660000|142900000|00000000-0000-0000-0000-00005db26ea8|00000000-0000-0000-0000-00005db2741b", - "courtyards_overlap|126820000|142900000|00000000-0000-0000-0000-00005db272bc|00000000-0000-0000-0000-00005db2741b", - "courtyards_overlap|144725000|118017468|00000000-0000-0000-0000-00005d888938|00000000-0000-0000-0000-00005e2b4dc2", - "courtyards_overlap|86925000|140617468|00000000-0000-0000-0000-00005db273cf|00000000-0000-0000-0000-00005e2b4dc5" - ], + "drc_exclusions": [], "meta": { "version": 2 }, diff --git a/qa/tests/pcbnew/drc/test_drc_regressions.cpp b/qa/tests/pcbnew/drc/test_drc_regressions.cpp index 7996ca2f58..df93e29675 100644 --- a/qa/tests/pcbnew/drc/test_drc_regressions.cpp +++ b/qa/tests/pcbnew/drc/test_drc_regressions.cpp @@ -137,7 +137,8 @@ BOOST_FIXTURE_TEST_CASE( DRCFalseNegativeRegressions, DRC_REGRESSION_TEST_FIXTUR { "issue12109", 8 }, // Pads fail annular width test { "issue14334", 2 }, // Thermal spoke to otherwise unconnected island { "reverse_via", 3 }, // Via/track ordering - { "intersectingzones", 1 } // zones are too close to each other + { "intersectingzones", 1 }, // zones are too close to each other + { "fill_bad", 1 } // zone max BBox was too small }; for( const std::pair& entry : tests ) diff --git a/qa/tests/pcbnew/test_zone_filler.cpp b/qa/tests/pcbnew/test_zone_filler.cpp index 56b96849a7..93641a13e0 100644 --- a/qa/tests/pcbnew/test_zone_filler.cpp +++ b/qa/tests/pcbnew/test_zone_filler.cpp @@ -176,7 +176,8 @@ BOOST_FIXTURE_TEST_CASE( RegressionZoneFillTests, ZONE_FILL_TEST_FIXTURE ) "issue6260", "issue6284", "issue7086", - "issue14294" // Bad Clipper2 fill + "issue14294", // Bad Clipper2 fill + "fill_bad" // Missing zone clearance expansion }; for( const wxString& relPath : tests )