From ae112136223fda9096daa7491e0a6005e83bbc56 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Sat, 30 Mar 2024 07:45:51 -0700 Subject: [PATCH] Handle small holes in DRC Connection width test If there is a small hole (smaller than the conn width), we can loop around in a circle checking all points and not move past the mimimum distance. To avoid this, if we detect a loop, we exit the substantial checker. This should return with true because a large hole will return true and we are only checking to see if there is a minimum amount of copper between two open areas (cherry picked from commit c841d0df6d80ee5e00d54936563007a453cb6eae) --- .../drc_test_provider_connection_width.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/pcbnew/drc/drc_test_provider_connection_width.cpp b/pcbnew/drc/drc_test_provider_connection_width.cpp index ab9eacef3a..d2210d7252 100644 --- a/pcbnew/drc/drc_test_provider_connection_width.cpp +++ b/pcbnew/drc/drc_test_provider_connection_width.cpp @@ -335,13 +335,13 @@ private: // a new fracture point, then we know that we are proceeding // in the wrong direction from the fracture and should // fall through to the next point - if( same_point( aPt, nz ) + if( same_point( aPt, nz ) && same_point( aPt->next, nz->prev ) && aPt->y == aPt->next->y ) { return nz->next; } - if( same_point( aPt, pz ) + if( same_point( aPt, pz ) && same_point( aPt->next, pz->prev ) && aPt->y == aPt->next->y ) { return pz->next; @@ -399,14 +399,16 @@ private: const Vertex* p0 = aA; const Vertex* p = getNextOutlineVertex( p0 ); - while( !same_point( p, aB ) && checked < total_pts && !( x_change && y_change ) ) + while( !same_point( p, aB ) // We've reached the other inflection point + && !same_point( p, aA ) // We've gone around in a circle + && checked < total_pts // Fail-safe for invalid lists + && !( x_change && y_change ) ) // We've found a substantial change in both directions { double diff_x = std::abs( p->x - p0->x ); double diff_y = std::abs( p->y - p0->y ); - // Floating point zeros can have a negative sign, so we need to - // ensure that only substantive diversions count for a direction - // change + // Check for a substantial change in the x or y direction + // This is measured by the set value of the minimum connection width if( diff_x > m_limit ) x_change = true; @@ -420,7 +422,7 @@ private: wxCHECK_MSG( checked < total_pts, false, wxT( "Invalid polygon detected. Missing points to check" ) ); - if( !x_change || !y_change ) + if( !same_point( p, aA ) && ( !x_change || !y_change ) ) return false; p = getPrevOutlineVertex( p0 ); @@ -429,7 +431,10 @@ private: y_change = false; checked = 0; - while( !same_point( p, aB ) && checked < total_pts && !( x_change && y_change ) ) + while( !same_point( p, aB ) // We've reached the other inflection point + && !same_point( p, aA ) // We've gone around in a circle + && checked < total_pts // Fail-safe for invalid lists + && !( x_change && y_change ) ) // We've found a substantial change in both directions { double diff_x = std::abs( p->x - p0->x ); double diff_y = std::abs( p->y - p0->y ); @@ -450,7 +455,7 @@ private: wxCHECK_MSG( checked < total_pts, false, wxT( "Invalid polygon detected. Missing points to check" ) ); - return ( x_change && y_change ); + return ( same_point( p, aA ) || ( x_change && y_change ) ); } /**