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;
}
Example #4
0
/**
 * 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;
}