Commit f63492f5 authored by raburton's avatar raburton

set eol-style native on new file

parent ffd3a713
/****************************************************************************/ /****************************************************************************/
/* functions to test, merges and cut polygons used as copper areas outlines */ /* functions to test, merges and cut polygons used as copper areas outlines */
/****************************************************************************/ /****************************************************************************/
#include <vector> #include <vector>
#include "fctsys.h" #include "fctsys.h"
#include "common.h" #include "common.h"
#include "pcbnew.h" #include "pcbnew.h"
using namespace std; using namespace std;
#undef ASSERT #undef ASSERT
#define ASSERT wxASSERT #define ASSERT wxASSERT
bool bDontShowSelfIntersectionArcsWarning; bool bDontShowSelfIntersectionArcsWarning;
bool bDontShowSelfIntersectionWarning; bool bDontShowSelfIntersectionWarning;
bool bDontShowIntersectionArcsWarning; bool bDontShowIntersectionArcsWarning;
bool bDontShowIntersectionWarning; bool bDontShowIntersectionWarning;
#define poly m_Poly #define poly m_Poly
// carea: describes a copper area // carea: describes a copper area
#define carea ZONE_CONTAINER #define carea ZONE_CONTAINER
/** /**
* Function AddArea * Function AddArea
* add empty copper area to net * add empty copper area to net
* @return pointer to the new area * @return pointer to the new area
*/ */
ZONE_CONTAINER* BOARD::AddArea( int netcode, int layer, int x, int y, int hatch ) ZONE_CONTAINER* BOARD::AddArea( int netcode, int layer, int x, int y, int hatch )
{ {
ZONE_CONTAINER* new_area = InsertArea( netcode, m_ZoneDescriptorList.size( ZONE_CONTAINER* new_area = InsertArea( netcode, m_ZoneDescriptorList.size(
) - 1, layer, x, y, hatch ); ) - 1, layer, x, y, hatch );
return new_area; return new_area;
} }
/** /**
* remove copper area from net * remove copper area from net
* @param area = area to remove * @param area = area to remove
* @return 0 * @return 0
*/ */
int BOARD::RemoveArea( ZONE_CONTAINER* area_to_remove ) int BOARD::RemoveArea( ZONE_CONTAINER* area_to_remove )
{ {
Delete( area_to_remove ); Delete( area_to_remove );
return 0; return 0;
} }
/** /**
* Function InsertArea * Function InsertArea
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea] * add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
* @return pointer to the new area * @return pointer to the new area
*/ */
ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch ) ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch )
{ {
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
new_area->SetNet( netcode ); new_area->SetNet( netcode );
new_area->SetLayer( layer ); new_area->SetLayer( layer );
new_area->m_TimeStamp = GetTimeStamp(); new_area->m_TimeStamp = GetTimeStamp();
if( iarea < (int) ( m_ZoneDescriptorList.size() - 1) ) if( iarea < (int) ( m_ZoneDescriptorList.size() - 1) )
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area ); m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
else else
m_ZoneDescriptorList.push_back( new_area ); m_ZoneDescriptorList.push_back( new_area );
new_area->poly->Start( layer, 1, 10 * NM_PER_MIL, x, y, new_area->poly->Start( layer, 1, 10 * NM_PER_MIL, x, y,
hatch ); hatch );
return new_area; return new_area;
} }
/** /**
* Function CompleteArea * Function CompleteArea
* complete copper area contour by adding a line from last to first corner * complete copper area contour by adding a line from last to first corner
* if there is only 1 or 2 corners, remove (delete) the area * if there is only 1 or 2 corners, remove (delete) the area
* @param area_to_complete = area to complete or remove * @param area_to_complete = area to complete or remove
* @param style = style of last corner * @param style = style of last corner
* @return 1 if Ok, 0 if area removed * @return 1 if Ok, 0 if area removed
*/ */
int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style ) int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style )
{ {
if( area_to_complete->poly->GetNumCorners() > 2 ) if( area_to_complete->poly->GetNumCorners() > 2 )
{ {
area_to_complete->poly->Close( style ); area_to_complete->poly->Close( style );
return 1; return 1;
} }
else else
{ {
RemoveArea( area_to_complete ); RemoveArea( area_to_complete );
} }
return 0; return 0;
} }
/** /**
* Function TestAreaPolygon * Function TestAreaPolygon
* Test an area for self-intersection. * Test an area for self-intersection.
* *
* @param CurrArea = copper area to test * @param CurrArea = copper area to test
* @return : * @return :
* -1 if arcs intersect other sides * -1 if arcs intersect other sides
* 0 if no intersecting sides * 0 if no intersecting sides
* 1 if intersecting sides, but no intersecting arcs * 1 if intersecting sides, but no intersecting arcs
* Also sets utility2 flag of area with return value * Also sets utility2 flag of area with return value
*/ */
int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea )
{ {
CPolyLine* p = CurrArea->poly; CPolyLine* p = CurrArea->poly;
// first, check for sides intersecting other sides, especially arcs // first, check for sides intersecting other sides, especially arcs
bool bInt = false; bool bInt = false;
bool bArcInt = false; bool bArcInt = false;
int n_cont = p->GetNumContours(); int n_cont = p->GetNumContours();
// make bounding rect for each contour // make bounding rect for each contour
std::vector<CRect> cr; std::vector<CRect> cr;
cr.reserve( n_cont ); cr.reserve( n_cont );
for( int icont = 0; icont<n_cont; icont++ ) for( int icont = 0; icont<n_cont; icont++ )
cr.push_back( p->GetCornerBounds( icont ) ); cr.push_back( p->GetCornerBounds( icont ) );
for( int icont = 0; icont<n_cont; icont++ ) for( int icont = 0; icont<n_cont; icont++ )
{ {
int is_start = p->GetContourStart( icont ); int is_start = p->GetContourStart( icont );
int is_end = p->GetContourEnd( icont ); int is_end = p->GetContourEnd( icont );
for( int is = is_start; is<=is_end; is++ ) for( int is = is_start; is<=is_end; is++ )
{ {
int is_prev = is - 1; int is_prev = is - 1;
if( is_prev < is_start ) if( is_prev < is_start )
is_prev = is_end; is_prev = is_end;
int is_next = is + 1; int is_next = is + 1;
if( is_next > is_end ) if( is_next > is_end )
is_next = is_start; is_next = is_start;
int style = p->GetSideStyle( is ); int style = p->GetSideStyle( is );
int x1i = p->GetX( is ); int x1i = p->GetX( is );
int y1i = p->GetY( is ); int y1i = p->GetY( is );
int x1f = p->GetX( is_next ); int x1f = p->GetX( is_next );
int y1f = p->GetY( is_next ); int y1f = p->GetY( is_next );
// check for intersection with any other sides // check for intersection with any other sides
for( int icont2 = icont; icont2<n_cont; icont2++ ) for( int icont2 = icont; icont2<n_cont; icont2++ )
{ {
if( cr[icont].left > cr[icont2].right if( cr[icont].left > cr[icont2].right
|| cr[icont].bottom > cr[icont2].top || cr[icont].bottom > cr[icont2].top
|| cr[icont2].left > cr[icont].right || cr[icont2].left > cr[icont].right
|| cr[icont2].bottom > cr[icont].top ) || cr[icont2].bottom > cr[icont].top )
{ {
// rectangles don't overlap, do nothing // rectangles don't overlap, do nothing
} }
else else
{ {
int is2_start = p->GetContourStart( icont2 ); int is2_start = p->GetContourStart( icont2 );
int is2_end = p->GetContourEnd( icont2 ); int is2_end = p->GetContourEnd( icont2 );
for( int is2 = is2_start; is2<=is2_end; is2++ ) for( int is2 = is2_start; is2<=is2_end; is2++ )
{ {
int is2_prev = is2 - 1; int is2_prev = is2 - 1;
if( is2_prev < is2_start ) if( is2_prev < is2_start )
is2_prev = is2_end; is2_prev = is2_end;
int is2_next = is2 + 1; int is2_next = is2 + 1;
if( is2_next > is2_end ) if( is2_next > is2_end )
is2_next = is2_start; is2_next = is2_start;
if( icont != icont2 if( icont != icont2
|| (is2 != is && is2 != is_prev && is2 != is_next && is != is2_prev || (is2 != is && is2 != is_prev && is2 != is_next && is != is2_prev
&& is != && is !=
is2_next ) ) is2_next ) )
{ {
int style2 = p->GetSideStyle( is2 ); int style2 = p->GetSideStyle( is2 );
int x2i = p->GetX( is2 ); int x2i = p->GetX( is2 );
int y2i = p->GetY( is2 ); int y2i = p->GetY( is2 );
int x2f = p->GetX( is2_next ); int x2f = p->GetX( is2_next );
int y2f = p->GetY( is2_next ); int y2f = p->GetY( is2_next );
int ret = FindSegmentIntersections( x1i, int ret = FindSegmentIntersections( x1i,
y1i, y1i,
x1f, x1f,
y1f, y1f,
style, style,
x2i, x2i,
y2i, y2i,
x2f, x2f,
y2f, y2f,
style2 ); style2 );
if( ret ) if( ret )
{ {
// intersection between non-adjacent sides // intersection between non-adjacent sides
bInt = TRUE; bInt = TRUE;
if( style != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT ) if( style != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT )
{ {
bArcInt = TRUE; bArcInt = TRUE;
break; break;
} }
} }
} }
} }
} }
if( bArcInt ) if( bArcInt )
break; break;
} }
if( bArcInt ) if( bArcInt )
break; break;
} }
if( bArcInt ) if( bArcInt )
break; break;
} }
if( bArcInt ) if( bArcInt )
CurrArea->utility2 = -1; CurrArea->utility2 = -1;
else if( bInt ) else if( bInt )
CurrArea->utility2 = 1; CurrArea->utility2 = 1;
else else
CurrArea->utility2 = 0; CurrArea->utility2 = 0;
return CurrArea->utility2; return CurrArea->utility2;
} }
/** /**
* Function ClipAreaPolygon * Function ClipAreaPolygon
* Process an area that has been modified, by clipping its polygon against itself. * Process an area that has been modified, by clipping its polygon against itself.
* This may change the number and order of copper areas in the net. * This may change the number and order of copper areas in the net.
* @param bMessageBoxInt == TRUE, shows message when clipping occurs. * @param bMessageBoxInt == TRUE, shows message when clipping occurs.
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs. * @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
* @return: * @return:
* -1 if arcs intersect other sides, so polygon can't be clipped * -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides * 0 if no intersecting sides
* 1 if intersecting sides * 1 if intersecting sides
* Also sets areas->utility1 flags if areas are modified * Also sets areas->utility1 flags if areas are modified
*/ */
int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea, int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs ) bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs )
{ {
CPolyLine* p = CurrArea->poly; CPolyLine* p = CurrArea->poly;
int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag
if( test == -1 && !bRetainArcs ) if( test == -1 && !bRetainArcs )
test = 1; test = 1;
if( test == -1 ) if( test == -1 )
{ {
// arc intersections, don't clip unless bRetainArcs == false // arc intersections, don't clip unless bRetainArcs == false
if( bMessageBoxArc && bDontShowSelfIntersectionArcsWarning == false ) if( bMessageBoxArc && bDontShowSelfIntersectionArcsWarning == false )
{ {
wxString str; wxString str;
str.Printf( wxT( "Area %X of net \"%s\" has arcs intersecting other sides.\n" ), str.Printf( wxT( "Area %X of net \"%s\" has arcs intersecting other sides.\n" ),
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() ); CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
str += wxT( "This may cause problems with other editing operations,\n" ); str += wxT( "This may cause problems with other editing operations,\n" );
str += wxT( "such as adding cutouts. It can't be fixed automatically.\n" ); str += wxT( "such as adding cutouts. It can't be fixed automatically.\n" );
str += wxT( "Manual correction is recommended." ); str += wxT( "Manual correction is recommended." );
wxMessageBox( str ); wxMessageBox( str );
// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState; // bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState;
} }
return -1; // arcs intersect with other sides, error return -1; // arcs intersect with other sides, error
} }
// mark all areas as unmodified except this one // mark all areas as unmodified except this one
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
m_ZoneDescriptorList[ia]->utility = 0; m_ZoneDescriptorList[ia]->utility = 0;
CurrArea->utility = 1; CurrArea->utility = 1;
if( test == 1 ) if( test == 1 )
{ {
// non-arc intersections, clip the polygon // non-arc intersections, clip the polygon
if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false ) if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false )
{ {
wxString str; wxString str;
str.Printf( wxT( "Area %d of net \"%s\" is self-intersecting and will be clipped.\n" ), str.Printf( wxT( "Area %d of net \"%s\" is self-intersecting and will be clipped.\n" ),
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() ); CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
str += wxT( "This may result in splitting the area.\n" ); str += wxT( "This may result in splitting the area.\n" );
str += wxT( "If the area is complex, this may take a few seconds." ); str += wxT( "If the area is complex, this may take a few seconds." );
wxMessageBox( str ); wxMessageBox( str );
// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState; // bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
} }
} }
//** TODO test for cutouts outside of area //** TODO test for cutouts outside of area
//** if( test == 1 ) //** if( test == 1 )
{ {
std::vector<CPolyLine*> * pa = new std::vector<CPolyLine*>; std::vector<CPolyLine*> * pa = new std::vector<CPolyLine*>;
p->Undraw(); p->Undraw();
int n_poly = CurrArea->poly->NormalizeWithGpc( pa, bRetainArcs ); int n_poly = CurrArea->poly->NormalizeWithGpc( pa, bRetainArcs );
if( n_poly > 1 ) // i.e if clippinf has created some polygons, we must add these new copper areas if( n_poly > 1 ) // i.e if clippinf has created some polygons, we must add these new copper areas
{ {
for( int ip = 1; ip < n_poly; ip++ ) for( int ip = 1; ip < n_poly; ip++ )
{ {
// create new copper area and copy poly into it // create new copper area and copy poly into it
CPolyLine* new_p = (*pa)[ip - 1]; CPolyLine* new_p = (*pa)[ip - 1];
CurrArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 ); CurrArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 );
// remove the poly that was automatically created for the new area // remove the poly that was automatically created for the new area
// and replace it with a poly from NormalizeWithGpc // and replace it with a poly from NormalizeWithGpc
delete CurrArea->poly; delete CurrArea->poly;
CurrArea->poly = new_p; CurrArea->poly = new_p;
CurrArea->poly->Draw(); CurrArea->poly->Draw();
CurrArea->utility = 1; CurrArea->utility = 1;
} }
} }
p->Draw(); p->Draw();
delete pa; delete pa;
} }
return test; return test;
} }
/** /**
* Process an area that has been modified, by clipping its polygon against * Process an area that has been modified, by clipping its polygon against
* itself and the polygons for any other areas on the same net. * itself and the polygons for any other areas on the same net.
* This may change the number and order of copper areas in the net. * This may change the number and order of copper areas in the net.
* @param modified_area = area to test * @param modified_area = area to test
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs. * @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
* @return : * @return :
* -1 if arcs intersect other sides, so polygon can't be clipped * -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides * 0 if no intersecting sides
* 1 if intersecting sides, polygon clipped * 1 if intersecting sides, polygon clipped
*/ */
int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area, int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area,
bool bMessageBoxArc, bool bMessageBoxArc,
bool bMessageBoxInt ) bool bMessageBoxInt )
{ {
// clip polygon against itself // clip polygon against itself
int test = ClipAreaPolygon( modified_area, bMessageBoxArc, bMessageBoxInt ); int test = ClipAreaPolygon( modified_area, bMessageBoxArc, bMessageBoxInt );
if( test == -1 ) if( test == -1 )
return test; return test;
// now see if we need to clip against other areas // now see if we need to clip against other areas
bool bCheckAllAreas = false; bool bCheckAllAreas = false;
if( test == 1 ) if( test == 1 )
bCheckAllAreas = TRUE; bCheckAllAreas = TRUE;
else else
bCheckAllAreas = TestAreaIntersections( modified_area ); bCheckAllAreas = TestAreaIntersections( modified_area );
if( bCheckAllAreas ) if( bCheckAllAreas )
CombineAllAreasInNet( modified_area->GetNet(), bMessageBoxInt, TRUE ); CombineAllAreasInNet( modified_area->GetNet(), bMessageBoxInt, TRUE );
return test; return test;
} }
/** /**
* Function CombineAllAreasInNet * Function CombineAllAreasInNet
* Checks all copper areas in net for intersections, combining them if found * Checks all copper areas in net for intersections, combining them if found
* @param aNetCode = net to consider * @param aNetCode = net to consider
* @param bMessageBox : if true display warning message box * @param bMessageBox : if true display warning message box
* @param bUseUtility : if true, don't check areas if both utility flags are 0 * @param bUseUtility : if true, don't check areas if both utility flags are 0
* Sets utility flag = 1 for any areas modified * Sets utility flag = 1 for any areas modified
* If an area has self-intersecting arcs, doesn't try to combine it * If an area has self-intersecting arcs, doesn't try to combine it
*/ */
int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility ) int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility )
{ {
if( m_ZoneDescriptorList.size() > 1 ) if( m_ZoneDescriptorList.size() > 1 )
{ {
// start by testing all area polygons to set utility2 flags // start by testing all area polygons to set utility2 flags
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ ) for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
if( m_ZoneDescriptorList[ia]->GetNet() == aNetCode ) if( m_ZoneDescriptorList[ia]->GetNet() == aNetCode )
TestAreaPolygon( m_ZoneDescriptorList[ia] ); TestAreaPolygon( m_ZoneDescriptorList[ia] );
// now loop through all combinations // now loop through all combinations
for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ ) for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ )
{ {
ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1];
if( curr_area->GetNet() != aNetCode ) if( curr_area->GetNet() != aNetCode )
continue; continue;
// legal polygon // legal polygon
CRect b1 = curr_area->poly->GetCornerBounds(); CRect b1 = curr_area->poly->GetCornerBounds();
bool mod_ia1 = false; bool mod_ia1 = false;
for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- ) for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- )
{ {
ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];
if( curr_area->poly->GetLayer() == area2->poly->GetLayer() if( curr_area->poly->GetLayer() == area2->poly->GetLayer()
&& curr_area->utility2 != -1 && area2->utility2 != -1 ) && curr_area->utility2 != -1 && area2->utility2 != -1 )
{ {
CRect b2 = area2->poly->GetCornerBounds(); CRect b2 = area2->poly->GetCornerBounds();
if( !( b1.left > b2.right || b1.right < b2.left if( !( b1.left > b2.right || b1.right < b2.left
|| b1.bottom > b2.top || b1.top < b2.bottom ) ) || b1.bottom > b2.top || b1.top < b2.bottom ) )
{ {
// check ia2 against 1a1 // check ia2 against 1a1
if( curr_area->utility || area2->utility || bUseUtility == if( curr_area->utility || area2->utility || bUseUtility ==
false ) false )
{ {
int ret = TestAreaIntersection( curr_area, area2 ); int ret = TestAreaIntersection( curr_area, area2 );
if( ret == 1 ) if( ret == 1 )
ret = CombineAreas( curr_area, area2 ); ret = CombineAreas( curr_area, area2 );
if( ret == 1 ) if( ret == 1 )
{ {
if( bMessageBox && bDontShowIntersectionWarning == false ) if( bMessageBox && bDontShowIntersectionWarning == false )
{ {
wxString str; wxString str;
str.Printf( str.Printf(
wxT( wxT(
"Areas %d and %d of net \"%s\" intersect and will be combined.\n" ), "Areas %d and %d of net \"%s\" intersect and will be combined.\n" ),
ia1 + 1, ia1 + 1,
ia2 + 1, ia2 + 1,
curr_area->m_Netname.GetData() ); curr_area->m_Netname.GetData() );
str += wxT( str += wxT(
"If they are complex, this may take a few seconds." ); "If they are complex, this may take a few seconds." );
wxMessageBox( str ); wxMessageBox( str );
// bDontShowIntersectionWarning = dlg.bDontShowBoxState; // bDontShowIntersectionWarning = dlg.bDontShowBoxState;
} }
mod_ia1 = TRUE; mod_ia1 = TRUE;
} }
else if( ret == 2 ) else if( ret == 2 )
{ {
if( bMessageBox && bDontShowIntersectionArcsWarning == false ) if( bMessageBox && bDontShowIntersectionArcsWarning == false )
{ {
wxString str; wxString str;
str.Printf( str.Printf(
wxT( wxT(
"Areas %d and %d of net \"%s\" intersect, but some of the intersecting sides are arcs.\n" ), "Areas %d and %d of net \"%s\" intersect, but some of the intersecting sides are arcs.\n" ),
ia1 + 1, ia1 + 1,
ia2 + 1, ia2 + 1,
curr_area->m_Netname.GetData() ); curr_area->m_Netname.GetData() );
str += wxT( "Therefore, these areas can't be combined." ); str += wxT( "Therefore, these areas can't be combined." );
wxMessageBox( str ); wxMessageBox( str );
// bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState; // bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState;
} }
} }
} }
} }
} }
} }
if( mod_ia1 ) if( mod_ia1 )
ia1--; // if modified, we need to check it again ia1--; // if modified, we need to check it again
} }
} }
return 0; return 0;
} }
/** /**
* Function TestAreaIntersections * Function TestAreaIntersections
* Check for intersection of a given copper area with other areas in same net * Check for intersection of a given copper area with other areas in same net
* @param area_to_test = area to compare to all other areas in the same net * @param area_to_test = area to compare to all other areas in the same net
*/ */
bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
{ {
CPolyLine* poly1 = area_to_test->poly; CPolyLine* poly1 = area_to_test->poly;
for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ )
{ {
ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2]; ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];
if( area_to_test->GetNet() != area_to_test->GetNet() ) if( area_to_test->GetNet() != area_to_test->GetNet() )
continue; continue;
if( area_to_test != area2 ) if( area_to_test != area2 )
{ {
// see if areas are on same layer // see if areas are on same layer
if( area_to_test->GetLayer() != area2->GetLayer() ) if( area_to_test->GetLayer() != area2->GetLayer() )
continue; continue;
CPolyLine* poly2 = area2->poly; CPolyLine* poly2 = area2->poly;
// test bounding rects // test bounding rects
CRect b1 = poly1->GetCornerBounds(); CRect b1 = poly1->GetCornerBounds();
CRect b2 = poly2->GetCornerBounds(); CRect b2 = poly2->GetCornerBounds();
if( b1.bottom > b2.top if( b1.bottom > b2.top
|| b1.top < b2.bottom || b1.top < b2.bottom
|| b1.left > b2.right || b1.left > b2.right
|| b1.right < b2.left ) || b1.right < b2.left )
continue; continue;
// test for intersecting segments // test for intersecting segments
for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ ) for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ )
{ {
int is1 = poly1->GetContourStart( icont1 ); int is1 = poly1->GetContourStart( icont1 );
int ie1 = poly1->GetContourEnd( icont1 ); int ie1 = poly1->GetContourEnd( icont1 );
for( int ic1 = is1; ic1<=ie1; ic1++ ) for( int ic1 = is1; ic1<=ie1; ic1++ )
{ {
int xi1 = poly1->GetX( ic1 ); int xi1 = poly1->GetX( ic1 );
int yi1 = poly1->GetY( ic1 ); int yi1 = poly1->GetY( ic1 );
int xf1, yf1, style1; int xf1, yf1, style1;
if( ic1 < ie1 ) if( ic1 < ie1 )
{ {
xf1 = poly1->GetX( ic1 + 1 ); xf1 = poly1->GetX( ic1 + 1 );
yf1 = poly1->GetY( ic1 + 1 ); yf1 = poly1->GetY( ic1 + 1 );
} }
else else
{ {
xf1 = poly1->GetX( is1 ); xf1 = poly1->GetX( is1 );
yf1 = poly1->GetY( is1 ); yf1 = poly1->GetY( is1 );
} }
style1 = poly1->GetSideStyle( ic1 ); style1 = poly1->GetSideStyle( ic1 );
for( int icont2 = 0; icont2<poly2->GetNumContours(); icont2++ ) for( int icont2 = 0; icont2<poly2->GetNumContours(); icont2++ )
{ {
int is2 = poly2->GetContourStart( icont2 ); int is2 = poly2->GetContourStart( icont2 );
int ie2 = poly2->GetContourEnd( icont2 ); int ie2 = poly2->GetContourEnd( icont2 );
for( int ic2 = is2; ic2<=ie2; ic2++ ) for( int ic2 = is2; ic2<=ie2; ic2++ )
{ {
int xi2 = poly2->GetX( ic2 ); int xi2 = poly2->GetX( ic2 );
int yi2 = poly2->GetY( ic2 ); int yi2 = poly2->GetY( ic2 );
int xf2, yf2, style2; int xf2, yf2, style2;
if( ic2 < ie2 ) if( ic2 < ie2 )
{ {
xf2 = poly2->GetX( ic2 + 1 ); xf2 = poly2->GetX( ic2 + 1 );
yf2 = poly2->GetY( ic2 + 1 ); yf2 = poly2->GetY( ic2 + 1 );
} }
else else
{ {
xf2 = poly2->GetX( is2 ); xf2 = poly2->GetX( is2 );
yf2 = poly2->GetY( is2 ); yf2 = poly2->GetY( is2 );
} }
style2 = poly2->GetSideStyle( ic2 ); style2 = poly2->GetSideStyle( ic2 );
int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1, int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1,
xi2, yi2, xf2, yf2, style2 ); xi2, yi2, xf2, yf2, style2 );
if( n_int ) if( n_int )
return TRUE; return TRUE;
} }
} }
} }
} }
} }
} }
return false; return false;
} }
/** /**
* Function TestAreaIntersection * Function TestAreaIntersection
* Test for intersection of 2 copper areas * Test for intersection of 2 copper areas
* area_to_test must be after area_ref in m_ZoneDescriptorList * area_to_test must be after area_ref in m_ZoneDescriptorList
* @param area_ref = area reference * @param area_ref = area reference
* @param area_to_test = area to compare for intersection calculations * @param area_to_test = area to compare for intersection calculations
* @return : 0 if no intersection * @return : 0 if no intersection
* 1 if intersection * 1 if intersection
* 2 if arcs intersect * 2 if arcs intersect
*/ */
int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ) int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test )
{ {
// see if areas are on same layer // see if areas are on same layer
if( area_ref->GetLayer() != area_to_test->GetLayer() ) if( area_ref->GetLayer() != area_to_test->GetLayer() )
return 0; return 0;
CPolyLine* poly1 = area_ref->poly; CPolyLine* poly1 = area_ref->poly;
CPolyLine* poly2 = area_to_test->poly; CPolyLine* poly2 = area_to_test->poly;
// test bounding rects // test bounding rects
CRect b1 = poly1->GetCornerBounds(); CRect b1 = poly1->GetCornerBounds();
CRect b2 = poly2->GetCornerBounds(); CRect b2 = poly2->GetCornerBounds();
if( b1.bottom > b2.top if( b1.bottom > b2.top
|| b1.top < b2.bottom || b1.top < b2.bottom
|| b1.left > b2.right || b1.left > b2.right
|| b1.right < b2.left ) || b1.right < b2.left )
return 0; return 0;
// now test for intersecting segments // now test for intersecting segments
bool bInt = false; bool bInt = false;
bool bArcInt = false; bool bArcInt = false;
for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ ) for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ )
{ {
int is1 = poly1->GetContourStart( icont1 ); int is1 = poly1->GetContourStart( icont1 );
int ie1 = poly1->GetContourEnd( icont1 ); int ie1 = poly1->GetContourEnd( icont1 );
for( int ic1 = is1; ic1<=ie1; ic1++ ) for( int ic1 = is1; ic1<=ie1; ic1++ )
{ {
int xi1 = poly1->GetX( ic1 ); int xi1 = poly1->GetX( ic1 );
int yi1 = poly1->GetY( ic1 ); int yi1 = poly1->GetY( ic1 );
int xf1, yf1, style1; int xf1, yf1, style1;
if( ic1 < ie1 ) if( ic1 < ie1 )
{ {
xf1 = poly1->GetX( ic1 + 1 ); xf1 = poly1->GetX( ic1 + 1 );
yf1 = poly1->GetY( ic1 + 1 ); yf1 = poly1->GetY( ic1 + 1 );
} }
else else
{ {
xf1 = poly1->GetX( is1 ); xf1 = poly1->GetX( is1 );
yf1 = poly1->GetY( is1 ); yf1 = poly1->GetY( is1 );
} }
style1 = poly1->GetSideStyle( ic1 ); style1 = poly1->GetSideStyle( ic1 );
for( int icont2 = 0; icont2<poly2->GetNumContours(); icont2++ ) for( int icont2 = 0; icont2<poly2->GetNumContours(); icont2++ )
{ {
int is2 = poly2->GetContourStart( icont2 ); int is2 = poly2->GetContourStart( icont2 );
int ie2 = poly2->GetContourEnd( icont2 ); int ie2 = poly2->GetContourEnd( icont2 );
for( int ic2 = is2; ic2<=ie2; ic2++ ) for( int ic2 = is2; ic2<=ie2; ic2++ )
{ {
int xi2 = poly2->GetX( ic2 ); int xi2 = poly2->GetX( ic2 );
int yi2 = poly2->GetY( ic2 ); int yi2 = poly2->GetY( ic2 );
int xf2, yf2, style2; int xf2, yf2, style2;
if( ic2 < ie2 ) if( ic2 < ie2 )
{ {
xf2 = poly2->GetX( ic2 + 1 ); xf2 = poly2->GetX( ic2 + 1 );
yf2 = poly2->GetY( ic2 + 1 ); yf2 = poly2->GetY( ic2 + 1 );
} }
else else
{ {
xf2 = poly2->GetX( is2 ); xf2 = poly2->GetX( is2 );
yf2 = poly2->GetY( is2 ); yf2 = poly2->GetY( is2 );
} }
style2 = poly2->GetSideStyle( ic2 ); style2 = poly2->GetSideStyle( ic2 );
int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1, int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1,
xi2, yi2, xf2, yf2, style2 ); xi2, yi2, xf2, yf2, style2 );
if( n_int ) if( n_int )
{ {
bInt = TRUE; bInt = TRUE;
if( style1 != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT ) if( style1 != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT )
bArcInt = TRUE; bArcInt = TRUE;
break; break;
} }
} }
if( bArcInt ) if( bArcInt )
break; break;
} }
if( bArcInt ) if( bArcInt )
break; break;
} }
if( bArcInt ) if( bArcInt )
break; break;
} }
if( !bInt ) if( !bInt )
return 0; return 0;
if( bArcInt ) if( bArcInt )
return 2; return 2;
return 1; return 1;
} }
/** /**
* Function CombineAreas * Function CombineAreas
* If possible, combine 2 copper areas * If possible, combine 2 copper areas
* area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList * area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList
* area_to_combine will be deleted, if areas are combined * area_to_combine will be deleted, if areas are combined
* @return : 0 if no intersection * @return : 0 if no intersection
* 1 if intersection * 1 if intersection
* 2 if arcs intersect * 2 if arcs intersect
*/ */
int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine ) int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine )
{ {
if( area_ref == area_to_combine ) if( area_ref == area_to_combine )
ASSERT( 0 ); ASSERT( 0 );
#if 0 #if 0
// test for intersection // test for intersection
int test = TestAreaIntersection( area_ref, area_to_combine ); int test = TestAreaIntersection( area_ref, area_to_combine );
if( test != 1 ) if( test != 1 )
return test; // no intersection return test; // no intersection
#endif #endif
// polygons intersect, combine them // polygons intersect, combine them
CPolyLine* poly1 = area_ref->poly; CPolyLine* poly1 = area_ref->poly;
CPolyLine* poly2 = area_to_combine->poly; CPolyLine* poly2 = area_to_combine->poly;
std::vector<CArc> arc_array1; std::vector<CArc> arc_array1;
std::vector<CArc> arc_array2; std::vector<CArc> arc_array2;
poly1->MakeGpcPoly( -1, &arc_array1 ); poly1->MakeGpcPoly( -1, &arc_array1 );
poly2->MakeGpcPoly( -1, &arc_array2 ); poly2->MakeGpcPoly( -1, &arc_array2 );
int n_ext_cont1 = 0; int n_ext_cont1 = 0;
for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ ) for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ )
if( !( (poly1->GetGpcPoly()->hole)[ic] ) ) if( !( (poly1->GetGpcPoly()->hole)[ic] ) )
n_ext_cont1++; n_ext_cont1++;
int n_ext_cont2 = 0; int n_ext_cont2 = 0;
for( int ic = 0; ic<poly2->GetGpcPoly()->num_contours; ic++ ) for( int ic = 0; ic<poly2->GetGpcPoly()->num_contours; ic++ )
if( !( (poly2->GetGpcPoly()->hole)[ic] ) ) if( !( (poly2->GetGpcPoly()->hole)[ic] ) )
n_ext_cont2++; n_ext_cont2++;
gpc_polygon* union_gpc = new gpc_polygon; gpc_polygon* union_gpc = new gpc_polygon;
gpc_polygon_clip( GPC_UNION, poly1->GetGpcPoly(), poly2->GetGpcPoly(), union_gpc ); gpc_polygon_clip( GPC_UNION, poly1->GetGpcPoly(), poly2->GetGpcPoly(), union_gpc );
// get number of outside contours // get number of outside contours
int n_union_ext_cont = 0; int n_union_ext_cont = 0;
for( int ic = 0; ic<union_gpc->num_contours; ic++ ) for( int ic = 0; ic<union_gpc->num_contours; ic++ )
if( !( (union_gpc->hole)[ic] ) ) if( !( (union_gpc->hole)[ic] ) )
n_union_ext_cont++; n_union_ext_cont++;
// if no intersection, free new gpc and return // if no intersection, free new gpc and return
if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 ) if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 )
{ {
gpc_free_polygon( union_gpc ); gpc_free_polygon( union_gpc );
delete union_gpc; delete union_gpc;
return 0; return 0;
} }
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine // intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
RemoveArea( area_to_combine ); RemoveArea( area_to_combine );
area_ref->m_Poly->RemoveAllContours(); area_ref->m_Poly->RemoveAllContours();
// create area with external contour // create area with external contour
for( int ic = 0; ic<union_gpc->num_contours; ic++ ) for( int ic = 0; ic<union_gpc->num_contours; ic++ )
{ {
if( !(union_gpc->hole)[ic] ) if( !(union_gpc->hole)[ic] )
{ {
// external contour, replace this poly // external contour, replace this poly
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ ) for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
{ {
int x = ( (union_gpc->contour)[ic].vertex )[i].x; int x = ( (union_gpc->contour)[ic].vertex )[i].x;
int y = ( (union_gpc->contour)[ic].vertex )[i].y; int y = ( (union_gpc->contour)[ic].vertex )[i].y;
if( i==0 ) if( i==0 )
{ {
area_ref->m_Poly->Start( area_ref->GetLayer(), 0, 0, x, y, area_ref->m_Poly->GetHatchStyle() ); area_ref->m_Poly->Start( area_ref->GetLayer(), 0, 0, x, y, area_ref->m_Poly->GetHatchStyle() );
} }
else else
area_ref->m_Poly->AppendCorner( x, y ); area_ref->m_Poly->AppendCorner( x, y );
} }
area_ref->m_Poly->Close(); area_ref->m_Poly->Close();
} }
} }
// add holes // add holes
for( int ic = 0; ic<union_gpc->num_contours; ic++ ) for( int ic = 0; ic<union_gpc->num_contours; ic++ )
{ {
if( (union_gpc->hole)[ic] ) if( (union_gpc->hole)[ic] )
{ {
// hole // hole
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ ) for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
{ {
int x = ( (union_gpc->contour)[ic].vertex )[i].x; int x = ( (union_gpc->contour)[ic].vertex )[i].x;
int y = ( (union_gpc->contour)[ic].vertex )[i].y; int y = ( (union_gpc->contour)[ic].vertex )[i].y;
area_ref->m_Poly->AppendCorner( x, y ); area_ref->m_Poly->AppendCorner( x, y );
} }
area_ref->m_Poly->Close(); area_ref->m_Poly->Close();
} }
} }
area_ref->utility = 1; area_ref->utility = 1;
area_ref->m_Poly->RestoreArcs( &arc_array1 ); area_ref->m_Poly->RestoreArcs( &arc_array1 );
area_ref->m_Poly->RestoreArcs( &arc_array2 ); area_ref->m_Poly->RestoreArcs( &arc_array2 );
area_ref->m_Poly->Draw(); area_ref->m_Poly->Draw();
gpc_free_polygon( union_gpc ); gpc_free_polygon( union_gpc );
delete union_gpc; delete union_gpc;
return 1; return 1;
} }
#if 0 #if 0
void dra_areas( CDlgLog* log, int copper_layers, void dra_areas( CDlgLog* log, int copper_layers,
int units, BOOL check_unrouted, int units, BOOL check_unrouted,
CArray<CPolyLine> * board_outline, CArray<CPolyLine> * board_outline,
DesignRules* dr, DRErrorList* drelist ) DesignRules* dr, DRErrorList* drelist )
{ {
CString d_str, x_str, y_str; CString d_str, x_str, y_str;
CString str; CString str;
CString str2; CString str2;
long nerrors = 0; long nerrors = 0;
// now iterate through all areas // now iterate through all areas
for( int ia = 0; ia<net->nareas; ia++ ) for( int ia = 0; ia<net->nareas; ia++ )
{ {
carea* a = &net->area[ia]; carea* a = &net->area[ia];
// iterate through all nets again // iterate through all nets again
POSITION pos2 = pos; POSITION pos2 = pos;
void* ptr2; void* ptr2;
CString name2; CString name2;
while( pos2 != NULL ) while( pos2 != NULL )
{ {
m_nlist->m_map.GetNextAssoc( pos2, name2, ptr2 ); m_nlist->m_map.GetNextAssoc( pos2, name2, ptr2 );
cnet* net2 = (cnet*) ptr2; cnet* net2 = (cnet*) ptr2;
for( int ia2 = 0; ia2<net2->nareas; ia2++ ) for( int ia2 = 0; ia2<net2->nareas; ia2++ )
{ {
carea* a2 = &net2->area[ia2]; carea* a2 = &net2->area[ia2];
// test for same layer // test for same layer
if( a->poly->GetLayer() == a2->poly->GetLayer() ) if( a->poly->GetLayer() == a2->poly->GetLayer() )
{ {
// test for points inside one another // test for points inside one another
for( int ic = 0; ic<a->poly->GetNumCorners(); ic++ ) for( int ic = 0; ic<a->poly->GetNumCorners(); ic++ )
{ {
int x = a->poly->GetX( ic ); int x = a->poly->GetX( ic );
int y = a->poly->GetY( ic ); int y = a->poly->GetY( ic );
if( a2->poly->TestPointInside( x, y ) ) if( a2->poly->TestPointInside( x, y ) )
{ {
// COPPERAREA_COPPERAREA error // COPPERAREA_COPPERAREA error
id id_a = net->id; id id_a = net->id;
id_a.st = ID_AREA; id_a.st = ID_AREA;
id_a.i = ia; id_a.i = ia;
id_a.sst = ID_SEL_CORNER; id_a.sst = ID_SEL_CORNER;
id_a.ii = ic; id_a.ii = ic;
str.Format( str.Format(
"%ld: \"%s\" copper area inside \"%s\" inside copper area\r\n", "%ld: \"%s\" copper area inside \"%s\" inside copper area\r\n",
nerrors + 1, nerrors + 1,
net->name, net->name,
net2->name ); net2->name );
DRError* dre = drelist->Add( nerrors, DRError* dre = drelist->Add( nerrors,
DRError::COPPERAREA_INSIDE_COPPERAREA, DRError::COPPERAREA_INSIDE_COPPERAREA,
&str, &str,
&net->name, &net->name,
&net2->name, &net2->name,
id_a, id_a,
id_a, id_a,
x, x,
y, y,
x, x,
y, y,
0, 0,
0 ); 0 );
if( dre ) if( dre )
{ {
nerrors++; nerrors++;
if( log ) if( log )
log->AddLine( str ); log->AddLine( str );
} }
} }
} }
for( int ic2 = 0; ic2<a2->poly->GetNumCorners(); ic2++ ) for( int ic2 = 0; ic2<a2->poly->GetNumCorners(); ic2++ )
{ {
int x = a2->poly->GetX( ic2 ); int x = a2->poly->GetX( ic2 );
int y = a2->poly->GetY( ic2 ); int y = a2->poly->GetY( ic2 );
if( a->poly->TestPointInside( x, y ) ) if( a->poly->TestPointInside( x, y ) )
{ {
// COPPERAREA_COPPERAREA error // COPPERAREA_COPPERAREA error
id id_a = net2->id; id id_a = net2->id;
id_a.st = ID_AREA; id_a.st = ID_AREA;
id_a.i = ia2; id_a.i = ia2;
id_a.sst = ID_SEL_CORNER; id_a.sst = ID_SEL_CORNER;
id_a.ii = ic2; id_a.ii = ic2;
str.Format( "%ld: \"%s\" copper area inside \"%s\" copper area\r\n", str.Format( "%ld: \"%s\" copper area inside \"%s\" copper area\r\n",
nerrors + 1, net2->name, net->name ); nerrors + 1, net2->name, net->name );
DRError* dre = drelist->Add( nerrors, DRError* dre = drelist->Add( nerrors,
DRError::COPPERAREA_INSIDE_COPPERAREA, DRError::COPPERAREA_INSIDE_COPPERAREA,
&str, &str,
&net2->name, &net2->name,
&net->name, &net->name,
id_a, id_a,
id_a, id_a,
x, x,
y, y,
x, x,
y, y,
0, 0,
0 ); 0 );
if( dre ) if( dre )
{ {
nerrors++; nerrors++;
if( log ) if( log )
log->AddLine( str ); log->AddLine( str );
} }
} }
} }
// now test spacing between areas // now test spacing between areas
for( int icont = 0; icont<a->poly->GetNumContours(); icont++ ) for( int icont = 0; icont<a->poly->GetNumContours(); icont++ )
{ {
int ic_start = a->poly->GetContourStart( icont ); int ic_start = a->poly->GetContourStart( icont );
int ic_end = a->poly->GetContourEnd( icont ); int ic_end = a->poly->GetContourEnd( icont );
for( int ic = ic_start; ic<=ic_end; ic++ ) for( int ic = ic_start; ic<=ic_end; ic++ )
{ {
id id_a = net->id; id id_a = net->id;
id_a.st = ID_AREA; id_a.st = ID_AREA;
id_a.i = ia; id_a.i = ia;
id_a.sst = ID_SIDE; id_a.sst = ID_SIDE;
id_a.ii = ic; id_a.ii = ic;
int ax1 = a->poly->GetX( ic ); int ax1 = a->poly->GetX( ic );
int ay1 = a->poly->GetY( ic ); int ay1 = a->poly->GetY( ic );
int ax2, ay2; int ax2, ay2;
if( ic == ic_end ) if( ic == ic_end )
{ {
ax2 = a->poly->GetX( ic_start ); ax2 = a->poly->GetX( ic_start );
ay2 = a->poly->GetY( ic_start ); ay2 = a->poly->GetY( ic_start );
} }
else else
{ {
ax2 = a->poly->GetX( ic + 1 ); ax2 = a->poly->GetX( ic + 1 );
ay2 = a->poly->GetY( ic + 1 ); ay2 = a->poly->GetY( ic + 1 );
} }
int astyle = a->poly->GetSideStyle( ic ); int astyle = a->poly->GetSideStyle( ic );
for( int icont2 = 0; icont2<a2->poly->GetNumContours(); icont2++ ) for( int icont2 = 0; icont2<a2->poly->GetNumContours(); icont2++ )
{ {
int ic_start2 = a2->poly->GetContourStart( icont2 ); int ic_start2 = a2->poly->GetContourStart( icont2 );
int ic_end2 = a2->poly->GetContourEnd( icont2 ); int ic_end2 = a2->poly->GetContourEnd( icont2 );
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ ) for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
{ {
id id_b = net2->id; id id_b = net2->id;
id_b.st = ID_AREA; id_b.st = ID_AREA;
id_b.i = ia2; id_b.i = ia2;
id_b.sst = ID_SIDE; id_b.sst = ID_SIDE;
id_b.ii = ic2; id_b.ii = ic2;
int bx1 = a2->poly->GetX( ic2 ); int bx1 = a2->poly->GetX( ic2 );
int by1 = a2->poly->GetY( ic2 ); int by1 = a2->poly->GetY( ic2 );
int bx2, by2; int bx2, by2;
if( ic2 == ic_end2 ) if( ic2 == ic_end2 )
{ {
bx2 = a2->poly->GetX( ic_start2 ); bx2 = a2->poly->GetX( ic_start2 );
by2 = a2->poly->GetY( ic_start2 ); by2 = a2->poly->GetY( ic_start2 );
} }
else else
{ {
bx2 = a2->poly->GetX( ic2 + 1 ); bx2 = a2->poly->GetX( ic2 + 1 );
by2 = a2->poly->GetY( ic2 + 1 ); by2 = a2->poly->GetY( ic2 + 1 );
} }
int bstyle = a2->poly->GetSideStyle( ic2 ); int bstyle = a2->poly->GetSideStyle( ic2 );
int x, y; int x, y;
int d = ::GetClearanceBetweenSegments( bx1, int d = ::GetClearanceBetweenSegments( bx1,
by1, by1,
bx2, bx2,
by2, by2,
bstyle, bstyle,
0, 0,
ax1, ax1,
ay1, ay1,
ax2, ax2,
ay2, ay2,
astyle, astyle,
0, 0,
dr->copper_copper, dr->copper_copper,
&x, &x,
&y ); &y );
if( d < dr->copper_copper ) if( d < dr->copper_copper )
{ {
// COPPERAREA_COPPERAREA error // COPPERAREA_COPPERAREA error
::MakeCStringFromDimension( &d_str, ::MakeCStringFromDimension( &d_str,
d, d,
units, units,
TRUE, TRUE,
TRUE, TRUE,
TRUE, TRUE,
1 ); 1 );
::MakeCStringFromDimension( &x_str, ::MakeCStringFromDimension( &x_str,
x, x,
units, units,
FALSE, FALSE,
TRUE, TRUE,
TRUE, TRUE,
1 ); 1 );
::MakeCStringFromDimension( &y_str, ::MakeCStringFromDimension( &y_str,
y, y,
units, units,
FALSE, FALSE,
TRUE, TRUE,
TRUE, TRUE,
1 ); 1 );
str.Format( str.Format(
"%ld: \"%s\" copper area to \"%s\" copper area = %s, x=%s, y=%s\r\n", "%ld: \"%s\" copper area to \"%s\" copper area = %s, x=%s, y=%s\r\n",
nerrors + 1, nerrors + 1,
net->name, net->name,
net2->name, net2->name,
d_str, d_str,
x_str, x_str,
y_str ); y_str );
DRError* dre = drelist->Add( DRError* dre = drelist->Add(
nerrors, nerrors,
DRError:: DRError::
COPPERAREA_COPPERAREA, COPPERAREA_COPPERAREA,
&str, &str,
&net->name, &net->name,
&net2->name, &net2->name,
id_a, id_a,
id_b, id_b,
x, x,
y, y,
x, x,
y, y,
0, 0,
0 ); 0 );
if( dre ) if( dre )
{ {
nerrors++; nerrors++;
if( log ) if( log )
log->AddLine( str ); log->AddLine( str );
} }
} }
} }
} }
} }
} }
} }
} }
} }
} }
} }
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment