int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine, bool aCreate_Markers ) { int nerrors = 0; // iterate through all areas for( int ia = 0; ia < GetAreaCount(); ia++ ) { ZONE_CONTAINER* Area_Ref = GetArea( ia ); SHAPE_POLY_SET* refSmoothedPoly = Area_Ref->GetSmoothedPoly(); if( !Area_Ref->IsOnCopperLayer() ) continue; // When testing only a single area, skip all others if( aArea_To_Examine && (aArea_To_Examine != Area_Ref) ) continue; for( int ia2 = 0; ia2 < GetAreaCount(); ia2++ ) { ZONE_CONTAINER* area_to_test = GetArea( ia2 ); SHAPE_POLY_SET* testSmoothedPoly = area_to_test->GetSmoothedPoly(); if( Area_Ref == area_to_test ) continue; // test for same layer if( Area_Ref->GetLayer() != area_to_test->GetLayer() ) continue; // Test for same net if( Area_Ref->GetNetCode() == area_to_test->GetNetCode() && Area_Ref->GetNetCode() >= 0 ) continue; // test for different priorities if( Area_Ref->GetPriority() != area_to_test->GetPriority() ) continue; // test for different types if( Area_Ref->GetIsKeepout() != area_to_test->GetIsKeepout() ) continue; // Examine a candidate zone: compare area_to_test to Area_Ref // Get clearance used in zone to zone test. The policy used to // obtain that value is now part of the zone object itself by way of // ZONE_CONTAINER::GetClearance(). int zone2zoneClearance = Area_Ref->GetClearance( area_to_test ); // Keepout areas have no clearance, so set zone2zoneClearance to 1 // ( zone2zoneClearance = 0 can create problems in test functions) if( Area_Ref->GetIsKeepout() ) zone2zoneClearance = 1; // test for some corners of Area_Ref inside area_to_test for( auto iterator = refSmoothedPoly->IterateWithHoles(); iterator; iterator++ ) { VECTOR2I currentVertex = *iterator; if( testSmoothedPoly->Contains( currentVertex ) ) { // COPPERAREA_COPPERAREA error: copper area ref corner inside copper area if( aCreate_Markers ) { int x = currentVertex.x; int y = currentVertex.y; wxString msg1 = Area_Ref->GetSelectMenuText(); wxString msg2 = area_to_test->GetSelectMenuText(); MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA, wxPoint( x, y ), msg1, wxPoint( x, y ), msg2, wxPoint( x, y ) ); Add( marker ); } nerrors++; } } // test for some corners of area_to_test inside Area_Ref for( auto iterator = testSmoothedPoly->IterateWithHoles(); iterator; iterator++ ) { VECTOR2I currentVertex = *iterator; if( refSmoothedPoly->Contains( currentVertex ) ) { // COPPERAREA_COPPERAREA error: copper area corner inside copper area ref if( aCreate_Markers ) { int x = currentVertex.x; int y = currentVertex.y; wxString msg1 = area_to_test->GetSelectMenuText(); wxString msg2 = Area_Ref->GetSelectMenuText(); MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA, wxPoint( x, y ), msg1, wxPoint( x, y ), msg2, wxPoint( x, y ) ); Add( marker ); } nerrors++; } } // Iterate through all the segments of refSmoothedPoly for( auto refIt = refSmoothedPoly->IterateSegmentsWithHoles(); refIt; refIt++ ) { // Build ref segment SEG refSegment = *refIt; // Iterate through all the segments in testSmoothedPoly for( auto testIt = testSmoothedPoly->IterateSegmentsWithHoles(); testIt; testIt++ ) { // Build test segment SEG testSegment = *testIt; int x, y; int ax1, ay1, ax2, ay2; ax1 = refSegment.A.x; ay1 = refSegment.A.y; ax2 = refSegment.B.x; ay2 = refSegment.B.y; int bx1, by1, bx2, by2; bx1 = testSegment.A.x; by1 = testSegment.A.y; bx2 = testSegment.B.x; by2 = testSegment.B.y; int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0, ax1, ay1, ax2, ay2, 0, zone2zoneClearance, &x, &y ); if( d < zone2zoneClearance ) { // COPPERAREA_COPPERAREA error : intersect or too close if( aCreate_Markers ) { wxString msg1 = Area_Ref->GetSelectMenuText(); wxString msg2 = area_to_test->GetSelectMenuText(); MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_CLOSE_TO_COPPERAREA, wxPoint( x, y ), msg1, wxPoint( x, y ), msg2, wxPoint( x, y ) ); Add( marker ); } nerrors++; } } } } } return nerrors; }