bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) { for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; if( area_to_test->GetNetCode() != area2->GetNetCode() ) continue; if( area_to_test == area2 ) continue; // see if areas are on same layer if( area_to_test->GetLayer() != area2->GetLayer() ) continue; // test for different priorities if( area_to_test->GetPriority() != area2->GetPriority() ) continue; // test for different types if( area_to_test->GetIsKeepout() != area2->GetIsKeepout() ) continue; if( TestAreaIntersection( area_to_test, area2 ) ) return true; } return false; }
bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, bool aUseLocalFlags ) { if( m_ZoneDescriptorList.size() <= 1 ) return false; bool modified = false; // Loop through all combinations for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ ) { ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; if( curr_area->GetNetCode() != aNetCode ) continue; // legal polygon BOX2I b1 = curr_area->Outline()->BBox(); bool mod_ia1 = false; for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- ) { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; if( area2->GetNetCode() != aNetCode ) continue; if( curr_area->GetPriority() != area2->GetPriority() ) continue; if( curr_area->GetIsKeepout() != area2->GetIsKeepout() ) continue; if( curr_area->GetLayer() != area2->GetLayer() ) continue; BOX2I b2 = area2->Outline()->BBox(); if( b1.Intersects( b2 ) ) { // check area2 against curr_area if( curr_area->GetLocalFlags() || area2->GetLocalFlags() || aUseLocalFlags == false ) { bool ret = TestAreaIntersection( curr_area, area2 ); if( ret ) ret = CombineAreas( aDeletedList, curr_area, area2 ); if( ret ) { mod_ia1 = true; modified = true; } } } } if( mod_ia1 ) ia1--; // if modified, we need to check it again } return modified; }
bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) { for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; if( area_to_test->GetNetCode() != area2->GetNetCode() ) continue; if( area_to_test == area2 ) continue; // see if areas are on same layers if( area_to_test->GetLayerSet() != area2->GetLayerSet() ) continue; // test for different priorities if( area_to_test->GetPriority() != area2->GetPriority() ) continue; // test for different types if( area_to_test->GetIsKeepout() != area2->GetIsKeepout() ) continue; // Keepout area-specific tests if( area_to_test->GetIsKeepout() ) { if( area_to_test->GetDoNotAllowCopperPour() != area2->GetDoNotAllowCopperPour() ) continue; if( area_to_test->GetDoNotAllowTracks() != area2->GetDoNotAllowTracks() ) continue; if( area_to_test->GetDoNotAllowVias() != area2->GetDoNotAllowVias() ) continue; } // Filled zone specific tests else { if( area_to_test->GetClearance() != area2->GetClearance() ) continue; if( area_to_test->GetThermalReliefGap() != area2->GetThermalReliefGap() ) continue; if( area_to_test->GetThermalReliefCopperBridge() != area2->GetThermalReliefCopperBridge() ) continue; if( area_to_test->GetArcSegmentCount() != area2->GetArcSegmentCount() ) continue; if( area_to_test->GetZoneClearance() != area2->GetZoneClearance() ) continue; if( area_to_test->GetPadConnection() != area2->GetPadConnection() ) continue; if( area_to_test->GetMinThickness() != area2->GetMinThickness() ) continue; if( area_to_test->GetCornerSmoothingType() != area2->GetCornerSmoothingType() ) continue; if( area_to_test->GetCornerRadius() != area2->GetCornerRadius() ) continue; } if( TestAreaIntersection( area_to_test, area2 ) ) return true; } return false; }
/** * Function CombineAllAreasInNet * Checks all copper areas in net for intersections, combining them if found * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in * undo commands can be NULL * @param aNetCode = net to consider * @param bMessageBox : if true display warning message box * @param bUseUtility : if true, don't check areas if both utility flags are 0 * Sets utility flag = 1 for any areas modified * If an area has self-intersecting arcs, doesn't try to combine it */ int BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, bool bMessageBox, bool bUseUtility ) { if( m_ZoneDescriptorList.size() <= 1 ) return 0; // start by testing all area polygons to set utility2 flags for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) if( m_ZoneDescriptorList[ia]->GetNet() == aNetCode ) TestAreaPolygon( m_ZoneDescriptorList[ia] ); // now loop through all combinations for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ ) { ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; if( curr_area->GetNet() != aNetCode ) continue; // legal polygon CRect b1 = curr_area->m_Poly->GetCornerBounds(); bool mod_ia1 = false; for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- ) { ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; if( area2->GetNet() != aNetCode ) continue; if( curr_area->GetPriority() != area2->GetPriority() ) continue; if( curr_area->GetLayer() == area2->GetLayer() && curr_area->utility2 != -1 && area2->utility2 != -1 ) { CRect b2 = area2->m_Poly->GetCornerBounds(); if( !( b1.left > b2.right || b1.right < b2.left || b1.bottom > b2.top || b1.top < b2.bottom ) ) { // check area2 against curr_area if( curr_area->utility || area2->utility || bUseUtility == false ) { int ret = TestAreaIntersection( curr_area, area2 ); if( ret == 1 ) ret = CombineAreas( aDeletedList, curr_area, area2 ); if( ret == 1 ) { mod_ia1 = true; } else if( ret == 2 ) { if( bMessageBox && bDontShowIntersectionArcsWarning == false ) { wxString str; str.Printf( wxT( "Areas %d and %d of net \"%s\" intersect, but some of the intersecting sides are arcs.\n" ), ia1 + 1, ia2 + 1, GetChars( curr_area->m_Netname ) ); str += wxT( "Therefore, these areas can't be combined." ); wxMessageBox( str ); } } } } } } if( mod_ia1 ) ia1--; // if modified, we need to check it again } return 0; }