|
|
@ -265,7 +265,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, |
|
|
|
if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false ) |
|
|
|
{ |
|
|
|
wxString str; |
|
|
|
str.Printf( wxT( "Area %8.8X of net \"%s\" is self-intersecting and will be clipped.\n" ), |
|
|
|
str.Printf( wxT( |
|
|
|
"Area %8.8X of net \"%s\" is self-intersecting and will be clipped.\n" ), |
|
|
|
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() ); |
|
|
|
str += wxT( "This may result in splitting the area.\n" ); |
|
|
|
str += wxT( "If the area is complex, this may take a few seconds." ); |
|
|
@ -517,7 +518,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) |
|
|
|
|
|
|
|
// If a contour is inside an other contour, no segments intersects, but the zones can be combined
|
|
|
|
// test a corner inside an outline (only one corner is enought)
|
|
|
|
/* for( int ic2 = 0; ic2 < poly2->GetNumCorners(); ic2++ )
|
|
|
|
for( int ic2 = 0; ic2 < poly2->GetNumCorners(); ic2++ ) |
|
|
|
{ |
|
|
|
int x = poly2->GetX( ic2 ); |
|
|
|
int y = poly2->GetY( ic2 ); |
|
|
@ -526,6 +527,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for( int ic1 = 0; ic1 < poly1->GetNumCorners(); ic1++ ) |
|
|
|
{ |
|
|
|
int x = poly1->GetX( ic1 ); |
|
|
@ -535,7 +537,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
*/ } |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
@ -637,7 +639,8 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ |
|
|
|
|
|
|
|
if( !bInt ) |
|
|
|
{ |
|
|
|
/* if( bArcInt ) return 0;
|
|
|
|
if( bArcInt ) |
|
|
|
return 0; |
|
|
|
|
|
|
|
// If a contour is inside an other contour, no segments intersects, but the zones can be combined
|
|
|
|
// test a corner inside an outline (only one corner is enought)
|
|
|
@ -650,6 +653,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for( int ic1 = 0; ic1 < poly1->GetNumCorners(); ic1++ ) |
|
|
|
{ |
|
|
|
int x = poly1->GetX( ic1 ); |
|
|
@ -660,7 +664,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
*/ return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if( bArcInt ) |
|
|
|
return 2; |
|
|
@ -777,8 +781,8 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 // Currently not used: work in progress
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function Is_Area_Inside_Area |
|
|
|
* Test a given area to see if it is inside an other area, or an other area is inside the given area |
|
|
@ -788,14 +792,15 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi |
|
|
|
*/ |
|
|
|
ZONE_CONTAINER* BOARD::Is_Area_Inside_Area( ZONE_CONTAINER* Area_Ref ) |
|
|
|
{ |
|
|
|
|
|
|
|
int corners_inside_count; |
|
|
|
|
|
|
|
for( int ia = 0; ia < GetAreaCount(); ia++ ) |
|
|
|
{ |
|
|
|
ZONE_CONTAINER* Area_To_Test = GetArea( ia ); |
|
|
|
|
|
|
|
if( Area_Ref == Area_To_Test ) |
|
|
|
continue; |
|
|
|
|
|
|
|
// test for same layer
|
|
|
|
if( Area_Ref->GetLayer() != Area_To_Test->GetLayer() ) |
|
|
|
continue; |
|
|
@ -809,6 +814,7 @@ ZONE_CONTAINER* BOARD::Is_Area_Inside_Area( ZONE_CONTAINER* Area_Ref) |
|
|
|
if( Area_To_Test->m_Poly->TestPointInside( x, y ) ) |
|
|
|
corners_inside_count--; |
|
|
|
} |
|
|
|
|
|
|
|
if( corners_inside_count == 0 ) |
|
|
|
return Area_Ref; |
|
|
|
|
|
|
@ -821,13 +827,15 @@ ZONE_CONTAINER* BOARD::Is_Area_Inside_Area( ZONE_CONTAINER* Area_Ref) |
|
|
|
if( Area_Ref->m_Poly->TestPointInside( x, y ) ) |
|
|
|
corners_inside_count--; |
|
|
|
} |
|
|
|
|
|
|
|
if( corners_inside_count == 0 ) |
|
|
|
return Area_Ref; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
@ -859,11 +867,13 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E |
|
|
|
|
|
|
|
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() ) |
|
|
|
if( Area_Ref->GetNet() == Area_To_Test->GetNet() && Area_Ref->GetNet() > 0 ) |
|
|
|
continue; |
|
|
|
|
|
|
|
// test for some corners of Area_Ref inside Area_To_Test
|
|
|
@ -950,21 +960,15 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E |
|
|
|
} |
|
|
|
int bstyle = Area_To_Test->m_Poly->GetSideStyle( ic2 ); |
|
|
|
int x, y; |
|
|
|
int d = ::GetClearanceBetweenSegments( bx1, |
|
|
|
by1, |
|
|
|
bx2, |
|
|
|
by2, |
|
|
|
bstyle, |
|
|
|
int d = ::GetClearanceBetweenSegments( |
|
|
|
bx1, by1, bx2, by2, bstyle, |
|
|
|
0, |
|
|
|
ax1, |
|
|
|
ay1, |
|
|
|
ax2, |
|
|
|
ay2, |
|
|
|
astyle, |
|
|
|
ax1, ay1, ax2, |
|
|
|
ay2, astyle, |
|
|
|
0, |
|
|
|
g_DesignSettings.m_TrackClearence, |
|
|
|
&x, |
|
|
|
&y ); |
|
|
|
g_DesignSettings. |
|
|
|
m_TrackClearence, |
|
|
|
&x, &y ); |
|
|
|
if( d < g_DesignSettings.m_TrackClearence ) |
|
|
|
{ |
|
|
|
// COPPERAREA_COPPERAREA error : intersect or too close
|
|
|
@ -972,7 +976,8 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E |
|
|
|
{ |
|
|
|
wxString msg1 = Area_Ref->MenuText( this ); |
|
|
|
wxString msg2 = Area_To_Test->MenuText( this ); |
|
|
|
MARKER* marker = new MARKER( COPPERAREA_CLOSE_TO_COPPERAREA, wxPoint( x, y ), |
|
|
|
MARKER* marker = new MARKER( COPPERAREA_CLOSE_TO_COPPERAREA, |
|
|
|
wxPoint( x, y ), |
|
|
|
msg1, wxPoint( x, y ), |
|
|
|
msg2, wxPoint( x, y ) ); |
|
|
|
Add( marker ); |
|
|
@ -989,3 +994,90 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E |
|
|
|
return nerrors; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function doEdgeZoneDrc |
|
|
|
* tests the current EDGE_ZONE segment and returns the result and displays the error |
|
|
|
* in the status panel only if one exists. |
|
|
|
* Test Edge inside other areas |
|
|
|
* Test Edge too close other areas |
|
|
|
* @param aEdge The current segment to test. |
|
|
|
* @return bool - false if DRC error or true if OK |
|
|
|
*/ |
|
|
|
|
|
|
|
bool DRC::doEdgeZoneDrc( const EDGE_ZONE* aEdge ) |
|
|
|
{ |
|
|
|
wxString str; |
|
|
|
|
|
|
|
// iterate through all areas
|
|
|
|
for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ ) |
|
|
|
{ |
|
|
|
ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ia2 ); |
|
|
|
|
|
|
|
// test for same layer
|
|
|
|
if( Area_To_Test->GetLayer() != aEdge->GetLayer() ) |
|
|
|
continue; |
|
|
|
|
|
|
|
// Test for same net
|
|
|
|
if( (aEdge->GetNet() == Area_To_Test->GetNet()) && (aEdge->GetNet() > 0) ) |
|
|
|
continue; |
|
|
|
|
|
|
|
// test for ending line inside Area_To_Test
|
|
|
|
int x = aEdge->m_End.x; |
|
|
|
int y = aEdge->m_End.y; |
|
|
|
if( Area_To_Test->m_Poly->TestPointInside( x, y ) ) |
|
|
|
{ |
|
|
|
// COPPERAREA_COPPERAREA error: corner inside copper area
|
|
|
|
m_currentMarker = fillMarker( aEdge, wxPoint( x, y ), |
|
|
|
COPPERAREA_INSIDE_COPPERAREA, |
|
|
|
m_currentMarker ); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// now test spacing between areas
|
|
|
|
int astyle = CPolyLine::STRAIGHT; |
|
|
|
int ax1 = aEdge->m_Start.x; |
|
|
|
int ay1 = aEdge->m_Start.y; |
|
|
|
int ax2 = aEdge->m_End.x; |
|
|
|
int ay2 = aEdge->m_End.y; |
|
|
|
for( int icont2 = 0; icont2 < Area_To_Test->m_Poly->GetNumContours(); icont2++ ) |
|
|
|
{ |
|
|
|
int ic_start2 = Area_To_Test->m_Poly->GetContourStart( icont2 ); |
|
|
|
int ic_end2 = Area_To_Test->m_Poly->GetContourEnd( icont2 ); |
|
|
|
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ ) |
|
|
|
{ |
|
|
|
int bx1 = Area_To_Test->m_Poly->GetX( ic2 ); |
|
|
|
int by1 = Area_To_Test->m_Poly->GetY( ic2 ); |
|
|
|
int bx2, by2; |
|
|
|
if( ic2 == ic_end2 ) |
|
|
|
{ |
|
|
|
bx2 = Area_To_Test->m_Poly->GetX( ic_start2 ); |
|
|
|
by2 = Area_To_Test->m_Poly->GetY( ic_start2 ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
bx2 = Area_To_Test->m_Poly->GetX( ic2 + 1 ); |
|
|
|
by2 = Area_To_Test->m_Poly->GetY( ic2 + 1 ); |
|
|
|
} |
|
|
|
int bstyle = Area_To_Test->m_Poly->GetSideStyle( ic2 ); |
|
|
|
int x, y; |
|
|
|
int d = ::GetClearanceBetweenSegments( bx1, by1, bx2, by2, bstyle, |
|
|
|
0, |
|
|
|
ax1, ay1, ax2, ay2, astyle, |
|
|
|
0, |
|
|
|
g_DesignSettings.m_ZoneClearence, |
|
|
|
&x, &y ); |
|
|
|
if( d < g_DesignSettings.m_ZoneClearence ) |
|
|
|
{ |
|
|
|
// COPPERAREA_COPPERAREA error : edge intersect or too close
|
|
|
|
m_currentMarker = fillMarker( aEdge, wxPoint( x, y ), |
|
|
|
COPPERAREA_CLOSE_TO_COPPERAREA, |
|
|
|
m_currentMarker ); |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |