Beispiel #1
0
int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
                                                      bool            aCreate_Markers )
{
    wxString    str;
    int         nerrors = 0;

    // iterate through all areas
    for( int ia = 0; ia < GetAreaCount(); ia++ )
    {
        ZONE_CONTAINER* Area_Ref = GetArea( ia );
        CPolyLine*      refSmoothedPoly = Area_Ref->GetSmoothedPoly();

        if( !Area_Ref->IsOnCopperLayer() )
            continue;

        // If testing only a single area, then 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 );
            CPolyLine*      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->GetNet() == Area_To_Test->GetNet() && Area_Ref->GetNet() >= 0 )
                continue;

            // test for different priorities
            if( Area_Ref->GetPriority() != Area_To_Test->GetPriority() )
                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 );

            // test for some corners of Area_Ref inside Area_To_Test
            for( int ic = 0; ic < refSmoothedPoly->GetNumCorners(); ic++ )
            {
                int x = refSmoothedPoly->GetX( ic );
                int y = refSmoothedPoly->GetY( ic );

                if( testSmoothedPoly->TestPointInside( x, y ) )
                {
                    // COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
                    if( aCreate_Markers )
                    {
                        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( int ic2 = 0; ic2 < testSmoothedPoly->GetNumCorners(); ic2++ )
            {
                int x = testSmoothedPoly->GetX( ic2 );
                int y = testSmoothedPoly->GetY( ic2 );

                if( refSmoothedPoly->TestPointInside( x, y ) )
                {
                    // COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
                    if( aCreate_Markers )
                    {
                        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++;
                }
            }

            // now test spacing between areas
            for( int icont = 0; icont < refSmoothedPoly->GetNumContours(); icont++ )
            {
                int ic_start = refSmoothedPoly->GetContourStart( icont );
                int ic_end   = refSmoothedPoly->GetContourEnd( icont );

                for( int ic = ic_start; ic<=ic_end; ic++ )
                {
                    int ax1 = refSmoothedPoly->GetX( ic );
                    int ay1 = refSmoothedPoly->GetY( ic );
                    int ax2, ay2;

                    if( ic == ic_end )
                    {
                        ax2 = refSmoothedPoly->GetX( ic_start );
                        ay2 = refSmoothedPoly->GetY( ic_start );
                    }
                    else
                    {
                        ax2 = refSmoothedPoly->GetX( ic + 1 );
                        ay2 = refSmoothedPoly->GetY( ic + 1 );
                    }

                    int astyle = refSmoothedPoly->GetSideStyle( ic );

                    for( int icont2 = 0; icont2 < testSmoothedPoly->GetNumContours(); icont2++ )
                    {
                        int ic_start2 = testSmoothedPoly->GetContourStart( icont2 );
                        int ic_end2   = testSmoothedPoly->GetContourEnd( icont2 );

                        for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
                        {
                            int bx1 = testSmoothedPoly->GetX( ic2 );
                            int by1 = testSmoothedPoly->GetY( ic2 );
                            int bx2, by2;

                            if( ic2 == ic_end2 )
                            {
                                bx2 = testSmoothedPoly->GetX( ic_start2 );
                                by2 = testSmoothedPoly->GetY( ic_start2 );
                            }
                            else
                            {
                                bx2 = testSmoothedPoly->GetX( ic2 + 1 );
                                by2 = testSmoothedPoly->GetY( ic2 + 1 );
                            }

                            int bstyle = testSmoothedPoly->GetSideStyle( ic2 );
                            int x, y;

                            int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, bstyle,
                                                                 0,
                                                                 ax1, ay1, ax2,
                                                                 ay2, astyle,
                                                                 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;
}
Beispiel #2
0
/**
 * Function TestAreaPolygon
 * Test an area for self-intersection.
 *
 * @param CurrArea = copper area to test
 * @return :
 * -1 if arcs intersect other sides
 *  0 if no intersecting sides
 *  1 if intersecting sides, but no intersecting arcs
 * Also sets utility2 flag of area with return value
 */
int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea )
{
    CPolyLine*         p = CurrArea->m_Poly;

    // first, check for sides intersecting other sides, especially arcs
    bool               bInt    = false;
    bool               bArcInt = false;
    int                n_cont  = p->GetNumContours();

    // make bounding rect for each contour
    std::vector<CRect> cr;
    cr.reserve( n_cont );

    for( int icont = 0; icont<n_cont; icont++ )
        cr.push_back( p->GetCornerBounds( icont ) );

    for( int icont = 0; icont<n_cont; icont++ )
    {
        int is_start = p->GetContourStart( icont );
        int is_end   = p->GetContourEnd( icont );

        for( int is = is_start; is<=is_end; is++ )
        {
            int is_prev = is - 1;

            if( is_prev < is_start )
                is_prev = is_end;

            int is_next = is + 1;

            if( is_next > is_end )
                is_next = is_start;

            int style = p->GetSideStyle( is );
            int x1i   = p->GetX( is );
            int y1i   = p->GetY( is );
            int x1f   = p->GetX( is_next );
            int y1f   = p->GetY( is_next );

            // check for intersection with any other sides
            for( int icont2 = icont; icont2<n_cont; icont2++ )
            {
                if( cr[icont].left > cr[icont2].right
                    || cr[icont].bottom > cr[icont2].top
                    || cr[icont2].left > cr[icont].right
                    || cr[icont2].bottom > cr[icont].top )
                {
                    // rectangles don't overlap, do nothing
                }
                else
                {
                    int is2_start = p->GetContourStart( icont2 );
                    int is2_end   = p->GetContourEnd( icont2 );

                    for( int is2 = is2_start; is2<=is2_end; is2++ )
                    {
                        int is2_prev = is2 - 1;

                        if( is2_prev < is2_start )
                            is2_prev = is2_end;

                        int is2_next = is2 + 1;

                        if( is2_next > is2_end )
                            is2_next = is2_start;

                        if( icont != icont2
                           || (is2 != is && is2 != is_prev && is2 != is_next && is != is2_prev
                               && is !=
                               is2_next ) )
                        {
                            int style2 = p->GetSideStyle( is2 );
                            int x2i    = p->GetX( is2 );
                            int y2i    = p->GetY( is2 );
                            int x2f    = p->GetX( is2_next );
                            int y2f    = p->GetY( is2_next );
                            int ret    = FindSegmentIntersections( x1i, y1i, x1f, y1f, style,
                                                                   x2i, y2i, x2f, y2f, style2 );
                            if( ret )
                            {
                                // intersection between non-adjacent sides
                                bInt = true;

                                if( style != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT )
                                {
                                    bArcInt = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                if( bArcInt )
                    break;
            }

            if( bArcInt )
                break;
        }

        if( bArcInt )
            break;
    }

    if( bArcInt )
        CurrArea->utility2 = -1;
    else if( bInt )
        CurrArea->utility2 = 1;
    else
        CurrArea->utility2 = 0;

    return CurrArea->utility2;
}