From e1c51ed19220139f62ebb0237370a7b46c5147c0 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 29 Sep 2023 21:54:59 +0100 Subject: [PATCH] A few performance improvements from profiling. Most of them are very small; the removal of the Fracture() in DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() is the only significant one. --- .../sch_plugins/kicad/sch_sexpr_parser.cpp | 2 +- pcbnew/drc/drc_cache_generator.cpp | 5 +- .../drc_test_provider_copper_clearance.cpp | 109 +++++++++--------- pcbnew/pcb_edit_frame.cpp | 6 +- 4 files changed, 63 insertions(+), 59 deletions(-) diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index 1995d4482d..92cac3b605 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -85,7 +85,7 @@ SCH_SEXPR_PARSER::SCH_SEXPR_PARSER( LINE_READER* aLineReader, PROGRESS_REPORTER* void SCH_SEXPR_PARSER::checkpoint() { - const unsigned PROGRESS_DELTA = 250; + const unsigned PROGRESS_DELTA = 500; if( m_progressReporter ) { diff --git a/pcbnew/drc/drc_cache_generator.cpp b/pcbnew/drc/drc_cache_generator.cpp index 1e3286b577..9a0e1e8224 100644 --- a/pcbnew/drc/drc_cache_generator.cpp +++ b/pcbnew/drc/drc_cache_generator.cpp @@ -81,8 +81,9 @@ bool DRC_CACHE_GENERATOR::Run() } } - // This is the number of tests between 2 calls to the progress bar - size_t progressDelta = 200; + // This is the number of tests between 2 calls to the progress bar. + // Note that zones are -not- done here, so it's reasonably fast. + size_t progressDelta = 500; size_t count = 0; size_t ii = 0; diff --git a/pcbnew/drc/drc_test_provider_copper_clearance.cpp b/pcbnew/drc/drc_test_provider_copper_clearance.cpp index 63ea7c622f..621276a99c 100644 --- a/pcbnew/drc/drc_test_provider_copper_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_copper_clearance.cpp @@ -1144,70 +1144,73 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() poly_segments.resize( m_board->m_DRCCopperZones.size() ); - // Contains the index for zoneA, zoneB, the conflict point, the actual clearance, the required clearance, and the layer + // Contains the index for zoneA, zoneB, the conflict point, the actual clearance, the + // required clearance, and the layer using report_data = std::tuple; const int invalid_zone = -1; std::vector> futures; thread_pool& tp = GetKiCadThreadPool(); - auto checkZones = [testClearance, testIntersects, &poly_segments, &cancelled, invalid_zone] - ( int zoneA, int zoneB, - int zone2zoneClearance, PCB_LAYER_ID layer ) -> report_data - { - // Iterate through all the segments of refSmoothedPoly - std::map conflictPoints; - - std::vector& refSegments = poly_segments[zoneA][layer]; - std::vector& testSegments = poly_segments[zoneB][layer]; - bool reported = false; - auto invalid_result = std::make_tuple( invalid_zone, invalid_zone, VECTOR2I(), 0, 0, F_Cu ); - - for( SEG& refSegment : refSegments ) - { - int ax1 = refSegment.A.x; - int ay1 = refSegment.A.y; - int ax2 = refSegment.B.x; - int ay2 = refSegment.B.y; - - // Iterate through all the segments in smoothed_polys[ia2] - for( SEG& testSegment : testSegments ) + auto checkZones = + [testClearance, testIntersects, &poly_segments, &cancelled, invalid_zone] + ( int zoneA, int zoneB, int clearance, PCB_LAYER_ID layer ) -> report_data { - // Build test segment - VECTOR2I pt; + // Iterate through all the segments of refSmoothedPoly + std::map conflictPoints; - int bx1 = testSegment.A.x; - int by1 = testSegment.A.y; - int bx2 = testSegment.B.x; - int by2 = testSegment.B.y; + std::vector& refSegments = poly_segments[zoneA][layer]; + std::vector& testSegments = poly_segments[zoneB][layer]; + bool reported = false; + auto invalid_result = std::make_tuple( invalid_zone, invalid_zone, VECTOR2I(), + 0, 0, F_Cu ); - // We have ensured that the A segment starts before the B segment, so if the - // A segment ends before the B segment starts, we can skip to the next A - if( ax2 < bx1 ) - break; - - int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0, - ax1, ay1, ax2, ay2, 0, - zone2zoneClearance, &pt.x, &pt.y ); - - if( d < zone2zoneClearance ) + for( SEG& refSegment : refSegments ) { - if( d == 0 && testIntersects ) - reported = true; - else if( testClearance ) - reported = true; + int ax1 = refSegment.A.x; + int ay1 = refSegment.A.y; + int ax2 = refSegment.B.x; + int ay2 = refSegment.B.y; - if( reported ) - return std::make_tuple( zoneA, zoneB, pt, d, zone2zoneClearance, layer ); + // Iterate through all the segments in smoothed_polys[ia2] + for( SEG& testSegment : testSegments ) + { + // Build test segment + VECTOR2I pt; + + int bx1 = testSegment.A.x; + int by1 = testSegment.A.y; + int bx2 = testSegment.B.x; + int by2 = testSegment.B.y; + + // We have ensured that the 'A' segment starts before the 'B' segment, + // so if the 'A' segment ends before the 'B' segment starts, we can skip + // to the next 'A' + if( ax2 < bx1 ) + break; + + int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0, + ax1, ay1, ax2, ay2, 0, + clearance, &pt.x, &pt.y ); + + if( d < clearance ) + { + if( d == 0 && testIntersects ) + reported = true; + else if( testClearance ) + reported = true; + + if( reported ) + return std::make_tuple( zoneA, zoneB, pt, d, clearance, layer ); + } + + if( cancelled ) + return invalid_result; + } } - if( cancelled ) - return invalid_result; - } - } - - return invalid_result; - }; + return invalid_result; + }; for( int layer_id = F_Cu; layer_id <= B_Cu; ++layer_id ) { @@ -1222,11 +1225,9 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones() { if( m_board->m_DRCCopperZones[ii]->IsOnLayer( layer ) ) { - SHAPE_POLY_SET poly = - *m_board->m_DRCCopperZones[ii]->GetFilledPolysList( layer ); + SHAPE_POLY_SET poly = *m_board->m_DRCCopperZones[ii]->GetFilledPolysList( layer ); std::vector& poly_segs = poly_segments[ii][layer]; - poly.Fracture( SHAPE_POLY_SET::PM_FAST ); poly.BuildBBoxCaches(); poly_segs.reserve( poly.FullPointCount() ); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 055408810c..b248a4807b 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -1859,7 +1859,9 @@ int PCB_EDIT_FRAME::TestStandalone() bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist, const wxString& aAnnotateMessage ) { - if( TestStandalone() == 0 ) + int standalone = TestStandalone(); + + if( standalone == 0 ) { DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in " "stand-alone mode. In order to create or update PCBs from " @@ -1868,7 +1870,7 @@ bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist, return false; // Not in standalone mode } - if( TestStandalone() < 0 ) // Problem with Eeschema or the schematic + if( standalone < 0 ) // Problem with Eeschema or the schematic return false; Raise(); // Show