more about zones. current No DRC for outlines
This commit is contained in:
parent
945c14d4ea
commit
ffd3a7133a
|
@ -11,12 +11,12 @@ const char * add_zone_cutout[] = {
|
||||||
" ..............",
|
" ..............",
|
||||||
".... ........",
|
".... ........",
|
||||||
"... ++++ .......",
|
"... ++++ .......",
|
||||||
".. + + .....",
|
".. +++++++ .....",
|
||||||
". + + ...",
|
". ++ ++ ...",
|
||||||
". + + ..",
|
". ++ ++ ..",
|
||||||
". + + ..",
|
". ++ ++ ..",
|
||||||
". + + .",
|
". ++ ++ .",
|
||||||
".. + + ..",
|
".. ++++++++++ ..",
|
||||||
"... +++++++ ... ",
|
"... +++++++ ... ",
|
||||||
".... .... ",
|
".... .... ",
|
||||||
"............ ",
|
"............ ",
|
||||||
|
|
|
@ -4,6 +4,14 @@ Started 2007-June-11
|
||||||
Please add newer entries at the top, list the date and your name with
|
Please add newer entries at the top, list the date and your name with
|
||||||
email address.
|
email address.
|
||||||
|
|
||||||
|
2008-jan-04 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
||||||
|
================================================================================
|
||||||
|
+pcbnew:
|
||||||
|
More about zones:
|
||||||
|
Outlines can be edited. Outlines are merged if needeed.
|
||||||
|
Current No DRC for outlines
|
||||||
|
|
||||||
|
|
||||||
2008-jan-01 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
2008-jan-01 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
||||||
================================================================================
|
================================================================================
|
||||||
+all
|
+all
|
||||||
|
|
|
@ -529,6 +529,24 @@ public:
|
||||||
*/
|
*/
|
||||||
int Fill_All_Zones( wxDC* DC, bool verbose = TRUE );
|
int Fill_All_Zones( wxDC* DC, bool verbose = TRUE );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Add_Zone_Cutout
|
||||||
|
* Add a cutout zone to a given zone outline
|
||||||
|
* @param DC = current Device Context
|
||||||
|
* @param zone_container = parent zone outline
|
||||||
|
*/
|
||||||
|
void Add_Zone_Cutout( wxDC* DC , ZONE_CONTAINER * zone_container );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Add_Similar_Zone
|
||||||
|
* Add a zone to a given zone outline.
|
||||||
|
* if the zones are overlappeing they will be merged
|
||||||
|
* @param DC = current Device Context
|
||||||
|
* @param zone_container = parent zone outline
|
||||||
|
*/
|
||||||
|
void Add_Similar_Zone( wxDC* DC , ZONE_CONTAINER * zone_container );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Edit_Zone_Params
|
* Function Edit_Zone_Params
|
||||||
* Edit params (layer, clearance, ...) for a zone outline
|
* Edit params (layer, clearance, ...) for a zone outline
|
||||||
|
@ -548,6 +566,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void End_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container );
|
void End_Move_Zone_Corner( wxDC* DC , ZONE_CONTAINER * zone_container );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function End_Move_Zone_Corner
|
||||||
|
* Remove the currently selected corner in a zone outline
|
||||||
|
* the .m_CornerSelection is used as corner selection
|
||||||
|
*/
|
||||||
|
void Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_container );
|
||||||
|
|
||||||
// Target handling
|
// Target handling
|
||||||
MIREPCB* Create_Mire( wxDC* DC );
|
MIREPCB* Create_Mire( wxDC* DC );
|
||||||
void Delete_Mire( MIREPCB* MirePcb, wxDC* DC );
|
void Delete_Mire( MIREPCB* MirePcb, wxDC* DC );
|
||||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -224,6 +224,123 @@ public:
|
||||||
void Show( int nestLevel, std::ostream& os );
|
void Show( int nestLevel, std::ostream& os );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Functions used in test, merge and cut outlines */
|
||||||
|
/**
|
||||||
|
* Function AddArea
|
||||||
|
* add empty copper area to net
|
||||||
|
* @return pointer to the new area
|
||||||
|
*/
|
||||||
|
ZONE_CONTAINER* AddArea( int netcode, int layer, int x, int y, int hatch );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove copper area from net
|
||||||
|
* @param area = area to remove
|
||||||
|
* @return 0
|
||||||
|
*/
|
||||||
|
int RemoveArea( ZONE_CONTAINER* area_to_remove );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function InsertArea
|
||||||
|
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
|
||||||
|
* @return pointer to the new area
|
||||||
|
*/
|
||||||
|
ZONE_CONTAINER* InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch );
|
||||||
|
|
||||||
|
/**
|
||||||
|
Function CompleteArea
|
||||||
|
* 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
|
||||||
|
* @param area_to_complete = area to complete or remove
|
||||||
|
* @param style = style of last corner
|
||||||
|
* @return 1 if Ok, 0 if area removed
|
||||||
|
*/
|
||||||
|
int CompleteArea( ZONE_CONTAINER* area_to_complete, int style );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 TestAreaPolygon( ZONE_CONTAINER* CurrArea );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ClipAreaPolygon
|
||||||
|
* 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.
|
||||||
|
* @param bMessageBoxInt == TRUE, shows message when clipping occurs.
|
||||||
|
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
|
||||||
|
* @return:
|
||||||
|
* -1 if arcs intersect other sides, so polygon can't be clipped
|
||||||
|
* 0 if no intersecting sides
|
||||||
|
* 1 if intersecting sides
|
||||||
|
* Also sets areas->utility1 flags if areas are modified
|
||||||
|
*/
|
||||||
|
int ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||||
|
bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs = TRUE );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an area that has been modified, by clipping its polygon against
|
||||||
|
* 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.
|
||||||
|
* @param modified_area = area to test
|
||||||
|
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
|
||||||
|
* @return :
|
||||||
|
* -1 if arcs intersect other sides, so polygon can't be clipped
|
||||||
|
* 0 if no intersecting sides
|
||||||
|
* 1 if intersecting sides, polygon clipped
|
||||||
|
*/
|
||||||
|
int AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
||||||
|
bool bMessageBoxArc,
|
||||||
|
bool bMessageBoxInt );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CombineAllAreasInNet
|
||||||
|
* Checks all copper areas in net for intersections, combining them if found
|
||||||
|
* @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 CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TestAreaIntersections
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
bool TestAreaIntersections( ZONE_CONTAINER* area_to_test );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TestAreaIntersection
|
||||||
|
* Test for intersection of 2 copper areas
|
||||||
|
* area_to_test must be after area_ref in m_ZoneDescriptorList
|
||||||
|
* @param area_ref = area reference
|
||||||
|
* @param area_to_test = area to compare for intersection calculations
|
||||||
|
* @return : 0 if no intersection
|
||||||
|
* 1 if intersection
|
||||||
|
* 2 if arcs intersect
|
||||||
|
*/
|
||||||
|
int TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CombineAreas
|
||||||
|
* If possible, combine 2 copper areas
|
||||||
|
* area_ref must be BEFORE area_to_combine
|
||||||
|
* area_to_combine will be deleted, if areas are combined
|
||||||
|
* @return : 0 if no intersection
|
||||||
|
* 1 if intersection
|
||||||
|
* 2 if arcs intersect
|
||||||
|
*/
|
||||||
|
int CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // #ifndef CLASS_BOARD_H
|
#endif // #ifndef CLASS_BOARD_H
|
||||||
|
|
|
@ -8,30 +8,9 @@
|
||||||
#include "gr_basic.h"
|
#include "gr_basic.h"
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "PolyLine.h"
|
||||||
#include "pcbnew.h"
|
#include "pcbnew.h"
|
||||||
|
|
||||||
/************************/
|
|
||||||
/* class ZONE_CONTAINER */
|
|
||||||
/************************/
|
|
||||||
|
|
||||||
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
|
|
||||||
BOARD_ITEM( parent, TYPEZONE_CONTAINER )
|
|
||||||
, CPolyLine( NULL )
|
|
||||||
|
|
||||||
{
|
|
||||||
m_NetCode = -1; // Net number for fast comparisons
|
|
||||||
m_CornerSelection = -1;
|
|
||||||
m_ZoneClearance = 200; // a reasonnable clerance value
|
|
||||||
m_GridFillValue = 50; // a reasonnable grid used for filling
|
|
||||||
m_PadOption = THERMAL_PAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ZONE_CONTAINER::~ZONE_CONTAINER()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************/
|
/**********************/
|
||||||
/* Class EDGE_ZONE */
|
/* Class EDGE_ZONE */
|
||||||
/**********************/
|
/**********************/
|
||||||
|
@ -49,7 +28,6 @@ EDGE_ZONE:: ~EDGE_ZONE()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
bool EDGE_ZONE::Save( FILE* aFile ) const
|
bool EDGE_ZONE::Save( FILE* aFile ) const
|
||||||
/****************************************/
|
/****************************************/
|
||||||
|
@ -57,6 +35,51 @@ bool EDGE_ZONE::Save( FILE* aFile ) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/* class ZONE_CONTAINER */
|
||||||
|
/************************/
|
||||||
|
|
||||||
|
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
|
||||||
|
BOARD_ITEM( parent, TYPEZONE_CONTAINER )
|
||||||
|
|
||||||
|
{
|
||||||
|
m_NetCode = -1; // Net number for fast comparisons
|
||||||
|
m_CornerSelection = -1;
|
||||||
|
m_ZoneClearance = 200; // a reasonnable clerance value
|
||||||
|
m_GridFillValue = 50; // a reasonnable grid used for filling
|
||||||
|
m_PadOption = THERMAL_PAD;
|
||||||
|
utility = 0; // flags used in polygon calculations
|
||||||
|
utility2 = 0; // flags used in polygon calculations
|
||||||
|
m_Poly = new CPolyLine( NULL ); // Outlines
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ZONE_CONTAINER::~ZONE_CONTAINER()
|
||||||
|
{
|
||||||
|
delete m_Poly;
|
||||||
|
m_Poly = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************/
|
||||||
|
void ZONE_CONTAINER::SetNet( int anet_code )
|
||||||
|
/*******************************************/
|
||||||
|
{
|
||||||
|
m_NetCode = anet_code;
|
||||||
|
if ( m_Parent )
|
||||||
|
{
|
||||||
|
EQUIPOT* net = ((BOARD*) m_Parent)->FindNet( g_HightLigth_NetCode );
|
||||||
|
if( net )
|
||||||
|
m_Netname = net->m_Netname;
|
||||||
|
else m_Netname.Empty();
|
||||||
|
}
|
||||||
|
else m_Netname.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/********************************************/
|
/********************************************/
|
||||||
bool ZONE_CONTAINER::Save( FILE* aFile ) const
|
bool ZONE_CONTAINER::Save( FILE* aFile ) const
|
||||||
/********************************************/
|
/********************************************/
|
||||||
|
@ -66,7 +89,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
|
||||||
|
|
||||||
unsigned item_pos;
|
unsigned item_pos;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned corners_count = corner.size();
|
unsigned corners_count = m_Poly->corner.size();
|
||||||
int outline_hatch;
|
int outline_hatch;
|
||||||
|
|
||||||
fprintf( aFile, "$CZONE_OUTLINE\n");
|
fprintf( aFile, "$CZONE_OUTLINE\n");
|
||||||
|
@ -79,16 +102,16 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
|
||||||
ret = fprintf( aFile, "ZLayer %d\n", m_Layer );
|
ret = fprintf( aFile, "ZLayer %d\n", m_Layer );
|
||||||
if ( ret < 1 ) return false;
|
if ( ret < 1 ) return false;
|
||||||
// Save the ouline aux info
|
// Save the ouline aux info
|
||||||
switch ( m_HatchStyle )
|
switch ( m_Poly->GetHatchStyle() )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case NO_HATCH:
|
case CPolyLine::NO_HATCH:
|
||||||
outline_hatch = 'N';
|
outline_hatch = 'N';
|
||||||
break;
|
break;
|
||||||
case DIAGONAL_EDGE:
|
case CPolyLine::DIAGONAL_EDGE:
|
||||||
outline_hatch = 'E';
|
outline_hatch = 'E';
|
||||||
break;
|
break;
|
||||||
case DIAGONAL_FULL:
|
case CPolyLine::DIAGONAL_FULL:
|
||||||
outline_hatch = 'F';
|
outline_hatch = 'F';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -99,8 +122,8 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
|
||||||
for ( item_pos = 0; item_pos < corners_count; item_pos++ )
|
for ( item_pos = 0; item_pos < corners_count; item_pos++ )
|
||||||
{
|
{
|
||||||
ret = fprintf( aFile, "ZCorner %d %d %d \n",
|
ret = fprintf( aFile, "ZCorner %d %d %d \n",
|
||||||
corner[item_pos].x, corner[item_pos].y,
|
m_Poly->corner[item_pos].x, m_Poly->corner[item_pos].y,
|
||||||
corner[item_pos].end_contour );
|
m_Poly->corner[item_pos].end_contour );
|
||||||
if ( ret < 3 ) return false;
|
if ( ret < 3 ) return false;
|
||||||
}
|
}
|
||||||
fprintf( aFile, "$endCZONE_OUTLINE\n");
|
fprintf( aFile, "$endCZONE_OUTLINE\n");
|
||||||
|
@ -122,7 +145,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
|
||||||
char netname_buffer[1024];
|
char netname_buffer[1024];
|
||||||
int ret;
|
int ret;
|
||||||
int n_corner_item = 0;
|
int n_corner_item = 0;
|
||||||
int outline_hatch = NO_HATCH;
|
int outline_hatch = CPolyLine::NO_HATCH;
|
||||||
bool error = false, has_corner = false;
|
bool error = false, has_corner = false;
|
||||||
|
|
||||||
netname_buffer[0] = 0;
|
netname_buffer[0] = 0;
|
||||||
|
@ -137,13 +160,13 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( ! has_corner )
|
if ( ! has_corner )
|
||||||
Start( m_Layer, 0, 0,
|
m_Poly->Start( m_Layer, 0, 0,
|
||||||
x, y,
|
x, y,
|
||||||
outline_hatch );
|
outline_hatch );
|
||||||
else
|
else
|
||||||
AppendCorner( x, y );
|
m_Poly->AppendCorner( x, y );
|
||||||
has_corner = true;
|
has_corner = true;
|
||||||
if ( flag ) Close();
|
if ( flag ) m_Poly->Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( strnicmp(Line, "ZInfo", 5 ) == 0 ) // general info found
|
if( strnicmp(Line, "ZInfo", 5 ) == 0 ) // general info found
|
||||||
|
@ -182,15 +205,15 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
|
||||||
{
|
{
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'N':
|
case 'N':
|
||||||
outline_hatch = NO_HATCH;
|
outline_hatch = CPolyLine::NO_HATCH;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
case 'E':
|
||||||
outline_hatch = DIAGONAL_EDGE;
|
outline_hatch = CPolyLine::DIAGONAL_EDGE;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'F':
|
case 'F':
|
||||||
outline_hatch = DIAGONAL_FULL;
|
outline_hatch = CPolyLine::DIAGONAL_FULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,32 +268,32 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& off
|
||||||
|
|
||||||
// draw the lines
|
// draw the lines
|
||||||
int i_start_contour = 0;
|
int i_start_contour = 0;
|
||||||
for( unsigned ic = 0; ic < corner.size(); ic++ )
|
for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ )
|
||||||
{
|
{
|
||||||
int xi = corner[ic].x + offset.x;
|
int xi = m_Poly->corner[ic].x + offset.x;
|
||||||
int yi = corner[ic].y + offset.y;
|
int yi = m_Poly->corner[ic].y + offset.y;
|
||||||
int xf, yf;
|
int xf, yf;
|
||||||
if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 )
|
if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 )
|
||||||
{
|
{
|
||||||
xf = corner[ic + 1].x + offset.x;
|
xf = m_Poly->corner[ic + 1].x + offset.x;
|
||||||
yf = corner[ic + 1].y + offset.y;
|
yf = m_Poly->corner[ic + 1].y + offset.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xf = corner[i_start_contour].x + offset.x;
|
xf = m_Poly->corner[i_start_contour].x + offset.x;
|
||||||
yf = corner[i_start_contour].y + offset.y;
|
yf = m_Poly->corner[i_start_contour].y + offset.y;
|
||||||
i_start_contour = ic + 1;
|
i_start_contour = ic + 1;
|
||||||
}
|
}
|
||||||
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
|
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw hatches
|
// draw hatches
|
||||||
for( unsigned ic = 0; ic < m_HatchLines.size(); ic++ )
|
for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ )
|
||||||
{
|
{
|
||||||
int xi = m_HatchLines[ic].xi + offset.x;
|
int xi = m_Poly->m_HatchLines[ic].xi + offset.x;
|
||||||
int yi = m_HatchLines[ic].yi + offset.y;
|
int yi = m_Poly->m_HatchLines[ic].yi + offset.y;
|
||||||
int xf = m_HatchLines[ic].xf + offset.x;
|
int xf = m_Poly->m_HatchLines[ic].xf + offset.x;
|
||||||
int yf =m_HatchLines[ic].yf + offset.y;
|
int yf =m_Poly->m_HatchLines[ic].yf + offset.y;
|
||||||
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
|
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +330,7 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
|
||||||
#define MIN_DIST_IN_PIXELS 5
|
#define MIN_DIST_IN_PIXELS 5
|
||||||
int dist;
|
int dist;
|
||||||
unsigned item_pos, lim;
|
unsigned item_pos, lim;
|
||||||
lim = corner.size();
|
lim = m_Poly->corner.size();
|
||||||
|
|
||||||
// Min distance to hit = MIN_DIST_IN_PIXELS pixels :
|
// Min distance to hit = MIN_DIST_IN_PIXELS pixels :
|
||||||
WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame;
|
WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame;
|
||||||
|
@ -315,7 +338,7 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
|
||||||
|
|
||||||
for ( item_pos = 0; item_pos < lim; item_pos++ )
|
for ( item_pos = 0; item_pos < lim; item_pos++ )
|
||||||
{
|
{
|
||||||
dist = abs( corner[item_pos].x - refPos.x ) + abs( corner[item_pos].y - refPos.y );
|
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y );
|
||||||
if( dist <= min_dist )
|
if( dist <= min_dist )
|
||||||
return item_pos;
|
return item_pos;
|
||||||
}
|
}
|
||||||
|
@ -335,7 +358,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||||
#define MIN_DIST_IN_PIXELS 5
|
#define MIN_DIST_IN_PIXELS 5
|
||||||
int dist;
|
int dist;
|
||||||
unsigned item_pos, lim;
|
unsigned item_pos, lim;
|
||||||
lim = corner.size();
|
lim = m_Poly->corner.size();
|
||||||
|
|
||||||
// Min distance to hit = MIN_DIST_IN_PIXELS pixels :
|
// Min distance to hit = MIN_DIST_IN_PIXELS pixels :
|
||||||
WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame;
|
WinEDA_BasePcbFrame* frame = ((BOARD*)GetParent())->m_PcbFrame;
|
||||||
|
@ -351,7 +374,7 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||||
* the last segment of the current outline starts at current corner, and ends
|
* the last segment of the current outline starts at current corner, and ends
|
||||||
* at the first corner of the outline
|
* at the first corner of the outline
|
||||||
*/
|
*/
|
||||||
if( corner[item_pos].end_contour || end_segm >= lim)
|
if( m_Poly->corner[item_pos].end_contour || end_segm >= lim)
|
||||||
{
|
{
|
||||||
unsigned tmp = first_corner_pos;
|
unsigned tmp = first_corner_pos;
|
||||||
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
|
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
|
||||||
|
@ -361,10 +384,10 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||||
/* test the dist between segment and ref point */
|
/* test the dist between segment and ref point */
|
||||||
dist = (int) GetPointToLineSegmentDistance( refPos.x,
|
dist = (int) GetPointToLineSegmentDistance( refPos.x,
|
||||||
refPos.y,
|
refPos.y,
|
||||||
corner[item_pos].x,
|
m_Poly->corner[item_pos].x,
|
||||||
corner[item_pos].y,
|
m_Poly->corner[item_pos].y,
|
||||||
corner[end_segm].x,
|
m_Poly->corner[end_segm].x,
|
||||||
corner[end_segm].y );
|
m_Poly->corner[end_segm].y );
|
||||||
if( dist <= min_dist )
|
if( dist <= min_dist )
|
||||||
return item_pos;
|
return item_pos;
|
||||||
}
|
}
|
||||||
|
@ -407,10 +430,10 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame )
|
||||||
Affiche_1_Parametre( frame, text_pos, _( "Layer" ), msg, BROWN );
|
Affiche_1_Parametre( frame, text_pos, _( "Layer" ), msg, BROWN );
|
||||||
|
|
||||||
text_pos += 8;
|
text_pos += 8;
|
||||||
msg.Printf( wxT( "%d" ), corner.size() );
|
msg.Printf( wxT( "%d" ), m_Poly->corner.size() );
|
||||||
Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE );
|
Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE );
|
||||||
|
|
||||||
text_pos += 8;
|
text_pos += 8;
|
||||||
msg.Printf( wxT( "%d" ), m_HatchLines.size() );
|
msg.Printf( wxT( "%d" ), m_Poly->m_HatchLines.size() );
|
||||||
Affiche_1_Parametre( frame, text_pos, _( "Hatch lines" ), msg, BLUE );
|
Affiche_1_Parametre( frame, text_pos, _( "Hatch lines" ), msg, BLUE );
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* others polygons inside this main polygon are holes.
|
* others polygons inside this main polygon are holes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ZONE_CONTAINER : public BOARD_ITEM, public CPolyLine
|
class ZONE_CONTAINER : public BOARD_ITEM
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum m_PadInZone { // How pads are covered by copper in zone
|
enum m_PadInZone { // How pads are covered by copper in zone
|
||||||
|
@ -24,10 +24,12 @@ public:
|
||||||
PAD_IN_ZONE // pads are covered by copper
|
PAD_IN_ZONE // pads are covered by copper
|
||||||
};
|
};
|
||||||
wxString m_Netname; // Net Name
|
wxString m_Netname; // Net Name
|
||||||
|
CPolyLine * m_Poly; // outlines
|
||||||
int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection
|
int m_CornerSelection; // For corner moving, corner index to drag, or -1 if no selection
|
||||||
int m_ZoneClearance; // clearance value
|
int m_ZoneClearance; // clearance value
|
||||||
int m_GridFillValue; // Grid used for filling
|
int m_GridFillValue; // Grid used for filling
|
||||||
m_PadInZone m_PadOption; // see m_PadInZone
|
m_PadInZone m_PadOption; // see m_PadInZone
|
||||||
|
int utility, utility2; // flags used in polygon calculations
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_NetCode; // Net number for fast comparisons
|
int m_NetCode; // Net number for fast comparisons
|
||||||
|
@ -55,7 +57,7 @@ public:
|
||||||
const wxPoint& offset, int draw_mode );
|
const wxPoint& offset, int draw_mode );
|
||||||
|
|
||||||
int GetNet( void ) { return m_NetCode; }
|
int GetNet( void ) { return m_NetCode; }
|
||||||
void SetNet( int anet_code ) { m_NetCode = anet_code; }
|
void SetNet( int anet_code );
|
||||||
/**
|
/**
|
||||||
* Function HitTest
|
* Function HitTest
|
||||||
* tests if the given wxPoint is within the bounds of this object.
|
* tests if the given wxPoint is within the bounds of this object.
|
||||||
|
@ -90,7 +92,6 @@ public:
|
||||||
* @return error level (0 = no error)
|
* @return error level (0 = no error)
|
||||||
*/
|
*/
|
||||||
int Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose = TRUE);
|
int Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose = TRUE);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*******************/
|
/*******************/
|
||||||
|
|
|
@ -281,7 +281,7 @@ void WinEDA_ZoneFrame::CreateControls()
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_Zone_Container )
|
if ( m_Zone_Container )
|
||||||
s_Zone_Hatching = m_Zone_Container->GetHatch();
|
s_Zone_Hatching = m_Zone_Container->m_Poly->GetHatchStyle();
|
||||||
switch( s_Zone_Hatching )
|
switch( s_Zone_Hatching )
|
||||||
{
|
{
|
||||||
case CPolyLine::NO_HATCH:
|
case CPolyLine::NO_HATCH:
|
||||||
|
|
|
@ -450,11 +450,13 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE:
|
case ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE:
|
||||||
wxMessageBox(wxT("ToDo"));
|
DrawPanel->MouseToCursorSchema();
|
||||||
|
Add_Similar_Zone( &dc, (ZONE_CONTAINER*) GetCurItem() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE:
|
case ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE:
|
||||||
wxMessageBox(wxT("ToDo"));
|
DrawPanel->MouseToCursorSchema();
|
||||||
|
Add_Zone_Cutout( &dc, (ZONE_CONTAINER*) GetCurItem() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_POPUP_PCB_DELETE_ZONE_CONTAINER:
|
case ID_POPUP_PCB_DELETE_ZONE_CONTAINER:
|
||||||
|
@ -469,23 +471,9 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
case ID_POPUP_PCB_DELETE_ZONE_CORNER:
|
case ID_POPUP_PCB_DELETE_ZONE_CORNER:
|
||||||
{
|
Remove_Zone_Corner( &dc, (ZONE_CONTAINER*)GetCurItem() );
|
||||||
DrawPanel->MouseToCursorSchema();
|
|
||||||
ZONE_CONTAINER * zone_cont = (ZONE_CONTAINER*)GetCurItem();
|
|
||||||
zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR);
|
|
||||||
if ( zone_cont->GetNumCorners() <= 3 )
|
|
||||||
{
|
|
||||||
Delete_Zone( &dc, NULL, zone_cont->m_TimeStamp );
|
|
||||||
m_Pcb->Delete( zone_cont );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zone_cont->DeleteCorner(zone_cont->m_CornerSelection);
|
|
||||||
zone_cont->Draw(DrawPanel,&dc, wxPoint(0,0), GR_XOR);
|
|
||||||
}
|
|
||||||
SetCurItem( NULL );
|
SetCurItem( NULL );
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case ID_POPUP_PCB_MOVE_ZONE_CORNER:
|
case ID_POPUP_PCB_MOVE_ZONE_CORNER:
|
||||||
{
|
{
|
||||||
|
@ -505,7 +493,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
|
||||||
* and start move the new corner
|
* and start move the new corner
|
||||||
*/
|
*/
|
||||||
zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR);
|
zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR);
|
||||||
zone_cont->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y );
|
zone_cont->m_Poly->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y );
|
||||||
zone_cont->m_CornerSelection++;
|
zone_cont->m_CornerSelection++;
|
||||||
zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR);
|
zone_cont->Draw(DrawPanel, &dc, wxPoint(0,0), GR_XOR);
|
||||||
Start_Move_Zone_Corner(&dc, zone_cont, zone_cont->m_CornerSelection, true);
|
Start_Move_Zone_Corner(&dc, zone_cont, zone_cont->m_CornerSelection, true);
|
||||||
|
|
|
@ -10,8 +10,10 @@ LIBVIEWER3D = ../3d-viewer/3d-viewer.a
|
||||||
ZONE_FILES = zones_by_polygon.o
|
ZONE_FILES = zones_by_polygon.o
|
||||||
#ZONE_FILES = zones.o
|
#ZONE_FILES = zones.o
|
||||||
|
|
||||||
|
|
||||||
OBJECTS= $(TARGET).o classpcb.o\
|
OBJECTS= $(TARGET).o classpcb.o\
|
||||||
$(ZONE_FILES)\
|
$(ZONE_FILES)\
|
||||||
|
zones_test_and_combine_areas.o\
|
||||||
zone_filling_algorithm.o\
|
zone_filling_algorithm.o\
|
||||||
lay2plot.o\
|
lay2plot.o\
|
||||||
modedit_undo_redo.o\
|
modedit_undo_redo.o\
|
||||||
|
|
|
@ -658,10 +658,10 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu
|
||||||
|
|
||||||
aPopMenu->AppendSeparator();
|
aPopMenu->AppendSeparator();
|
||||||
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE,
|
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_SIMILAR_ZONE,
|
||||||
_( "Add Similar Zone" ), fill_zone_xpm );
|
_( "Add Similar Zone" ), add_zone_xpm );
|
||||||
|
|
||||||
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE,
|
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_ZONE_ADD_CUTOUT_ZONE,
|
||||||
_( "Add Cutout Zone" ), add_zone_cutout );
|
_( "Add Cutout Area" ), add_zone_cutout );
|
||||||
aPopMenu->AppendSeparator();
|
aPopMenu->AppendSeparator();
|
||||||
|
|
||||||
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_FILL_ZONE,
|
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_FILL_ZONE,
|
||||||
|
|
|
@ -112,20 +112,20 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
|
||||||
|
|
||||||
// trace the zone edges into the routing matrix
|
// trace the zone edges into the routing matrix
|
||||||
int i_start_contour = 0;
|
int i_start_contour = 0;
|
||||||
for( unsigned ic = 0; ic < corner.size(); ic++ )
|
for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ )
|
||||||
{
|
{
|
||||||
int xi = corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x;
|
int xi = m_Poly->corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x;
|
||||||
int yi = corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y;
|
int yi = m_Poly->corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y;
|
||||||
int xf, yf;
|
int xf, yf;
|
||||||
if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 )
|
if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 )
|
||||||
{
|
{
|
||||||
xf = corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x;
|
xf = m_Poly->corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x;
|
||||||
yf = corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y;
|
yf = m_Poly->corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xf = corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x;
|
xf = m_Poly->corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x;
|
||||||
yf = corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y;
|
yf = m_Poly->corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y;
|
||||||
i_start_contour = ic + 1;
|
i_start_contour = ic + 1;
|
||||||
}
|
}
|
||||||
TraceLignePcb( xi, yi, xf, yf, -1, HOLE | CELL_is_EDGE, WRITE_CELL );
|
TraceLignePcb( xi, yi, xf, yf, -1, HOLE | CELL_is_EDGE, WRITE_CELL );
|
||||||
|
@ -136,9 +136,8 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
|
||||||
int cells_count = 0;
|
int cells_count = 0;
|
||||||
for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ )
|
for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ )
|
||||||
{
|
{
|
||||||
int icont = 0;
|
|
||||||
wxPoint pos;
|
wxPoint pos;
|
||||||
if( TestPointInsideContour( icont, (*pad)->m_Pos.x, (*pad)->m_Pos.y ) )
|
if( m_Poly->TestPointInside( (*pad)->m_Pos.x, (*pad)->m_Pos.y ) )
|
||||||
{
|
{
|
||||||
ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x +
|
ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x +
|
||||||
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
|
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
|
||||||
|
@ -196,20 +195,20 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
|
||||||
/* Recreate zone limits on the routing matrix
|
/* Recreate zone limits on the routing matrix
|
||||||
* (could be deleted by PlaceCells()) : */
|
* (could be deleted by PlaceCells()) : */
|
||||||
i_start_contour = 0;
|
i_start_contour = 0;
|
||||||
for( unsigned ic = 0; ic < corner.size(); ic++ )
|
for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ )
|
||||||
{
|
{
|
||||||
int xi = corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x;
|
int xi = m_Poly->corner[ic].x - Pcb->m_BoundaryBox.m_Pos.x;
|
||||||
int yi = corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y;
|
int yi = m_Poly->corner[ic].y - Pcb->m_BoundaryBox.m_Pos.y;
|
||||||
int xf, yf;
|
int xf, yf;
|
||||||
if( corner[ic].end_contour == FALSE && ic < corner.size() - 1 )
|
if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 )
|
||||||
{
|
{
|
||||||
xf = corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x;
|
xf = m_Poly->corner[ic + 1].x - Pcb->m_BoundaryBox.m_Pos.x;
|
||||||
yf = corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y;
|
yf = m_Poly->corner[ic + 1].y - Pcb->m_BoundaryBox.m_Pos.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xf = corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x;
|
xf = m_Poly->corner[i_start_contour].x - Pcb->m_BoundaryBox.m_Pos.x;
|
||||||
yf = corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y;
|
yf = m_Poly->corner[i_start_contour].y - Pcb->m_BoundaryBox.m_Pos.y;
|
||||||
i_start_contour = ic + 1;
|
i_start_contour = ic + 1;
|
||||||
}
|
}
|
||||||
TraceLignePcb( xi, yi, xf, yf, -1, HOLE | CELL_is_EDGE, WRITE_CELL );
|
TraceLignePcb( xi, yi, xf, yf, -1, HOLE | CELL_is_EDGE, WRITE_CELL );
|
||||||
|
@ -219,9 +218,8 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
|
||||||
* (could be deleted by PlaceCells()) : */
|
* (could be deleted by PlaceCells()) : */
|
||||||
for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ )
|
for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ )
|
||||||
{
|
{
|
||||||
int icont = 0;
|
|
||||||
wxPoint pos;
|
wxPoint pos;
|
||||||
if( TestPointInsideContour( icont, (*pad)->m_Pos.x, (*pad)->m_Pos.y ) )
|
if( m_Poly->TestPointInside( (*pad)->m_Pos.x, (*pad)->m_Pos.y ) )
|
||||||
{
|
{
|
||||||
ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x +
|
ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x +
|
||||||
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
|
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
|
||||||
|
|
|
@ -27,10 +27,9 @@ using namespace std;
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "pcbnew.h"
|
#include "pcbnew.h"
|
||||||
|
|
||||||
#include "autorout.h"
|
#include "autorout.h"
|
||||||
#include "cell.h"
|
|
||||||
#include "trigo.h"
|
#include "id.h"
|
||||||
|
|
||||||
#include "protos.h"
|
#include "protos.h"
|
||||||
|
|
||||||
|
@ -45,13 +44,15 @@ static void Abort_Zone_Move_Corner( WinEDA_DrawPanel* Panel, wxDC* DC );
|
||||||
static void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
|
static void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
|
||||||
|
|
||||||
/* Local variables */
|
/* Local variables */
|
||||||
static bool Zone_45_Only = FALSE;
|
static bool Zone_45_Only = FALSE;
|
||||||
static ZONE_CONTAINER::m_PadInZone s_Zone_Pad_Options = ZONE_CONTAINER::THERMAL_PAD;
|
static ZONE_CONTAINER::m_PadInZone s_Zone_Pad_Options = ZONE_CONTAINER::THERMAL_PAD;
|
||||||
static int s_Zone_Layer; // Layer used to create the current zone
|
static int s_Zone_Layer; // Layer used to create the current zone
|
||||||
static int s_Zone_Hatching; // Option to show the zone area (outlines only, short hatches or full hatches
|
static int s_Zone_Hatching; // Option to show the zone area (outlines only, short hatches or full hatches
|
||||||
static int s_NetcodeSelection; // Net code selection for the current zone
|
static int s_NetcodeSelection; // Net code selection for the current zone
|
||||||
static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
|
static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
|
||||||
static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted)
|
static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted)
|
||||||
|
static bool s_AddCutoutToCurrentZone; // if true, the next outline will be addes to s_CurrentZone
|
||||||
|
static ZONE_CONTAINER* s_CurrentZone; // if != NULL, these ZONE_CONTAINER params will be used for the next zone
|
||||||
|
|
||||||
// key used to store net sort option in config file :
|
// key used to store net sort option in config file :
|
||||||
#define ZONE_NET_SORT_OPTION_KEY wxT( "Zone_NetSort_Opt" )
|
#define ZONE_NET_SORT_OPTION_KEY wxT( "Zone_NetSort_Opt" )
|
||||||
|
@ -63,6 +64,44 @@ enum zone_cmd {
|
||||||
|
|
||||||
#include "dialog_zones_by_polygon.cpp"
|
#include "dialog_zones_by_polygon.cpp"
|
||||||
|
|
||||||
|
/**********************************************************************************/
|
||||||
|
void WinEDA_PcbFrame::Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* zone_container )
|
||||||
|
/**********************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Add_Similar_Zone
|
||||||
|
* Add a zone to a given zone outline.
|
||||||
|
* if the zones are overlappeing they will be merged
|
||||||
|
* @param DC = current Device Context
|
||||||
|
* @param zone_container = parent zone outline
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = zone_container;
|
||||||
|
wxCommandEvent evt;
|
||||||
|
evt.SetId( ID_PCB_ZONES_BUTT );
|
||||||
|
Process_Special_Functions( evt );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************************/
|
||||||
|
void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container )
|
||||||
|
/**********************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function Add_Zone_Cutout
|
||||||
|
* Add a cutout zone to a given zone outline
|
||||||
|
* @param DC = current Device Context
|
||||||
|
* @param zone_container = parent zone outline
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
s_AddCutoutToCurrentZone = true;
|
||||||
|
s_CurrentZone = zone_container;
|
||||||
|
wxCommandEvent evt;
|
||||||
|
evt.SetId( ID_PCB_ZONES_BUTT );
|
||||||
|
Process_Special_Functions( evt );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone, long aTimestamp )
|
void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone, long aTimestamp )
|
||||||
|
@ -174,6 +213,8 @@ static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC )
|
||||||
Panel->ManageCurseur = NULL;
|
Panel->ManageCurseur = NULL;
|
||||||
Panel->ForceCloseManageCurseur = NULL;
|
Panel->ForceCloseManageCurseur = NULL;
|
||||||
pcbframe->SetCurItem( NULL );
|
pcbframe->SetCurItem( NULL );
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,9 +269,11 @@ void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_con
|
||||||
zone_container->m_Flags = IN_EDIT;
|
zone_container->m_Flags = IN_EDIT;
|
||||||
DrawPanel->ManageCurseur = Show_Zone_Corner_While_Move_Mouse;
|
DrawPanel->ManageCurseur = Show_Zone_Corner_While_Move_Mouse;
|
||||||
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Move_Corner;
|
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Move_Corner;
|
||||||
s_CornerInitialPosition.x = zone_container->GetX( corner_id );
|
s_CornerInitialPosition.x = zone_container->m_Poly->GetX( corner_id );
|
||||||
s_CornerInitialPosition.y = zone_container->GetY( corner_id );
|
s_CornerInitialPosition.y = zone_container->m_Poly->GetY( corner_id );
|
||||||
s_CornerIsNew = IsNewCorner;
|
s_CornerIsNew = IsNewCorner;
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,6 +291,72 @@ void WinEDA_PcbFrame::End_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_conta
|
||||||
DrawPanel->ForceCloseManageCurseur = NULL;
|
DrawPanel->ForceCloseManageCurseur = NULL;
|
||||||
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
||||||
GetScreen()->SetModify();
|
GetScreen()->SetModify();
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = NULL;
|
||||||
|
|
||||||
|
SetCurItem( NULL ); // This outine can be deleted when merging outlines
|
||||||
|
|
||||||
|
/* Combine zones if possible */
|
||||||
|
int layer = zone_container->GetLayer();
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
if( layer == edge_zone->GetLayer() )
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Pcb->AreaPolygonModified( zone_container, true, false );
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
if( layer == edge_zone->GetLayer() )
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************************/
|
||||||
|
void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_container )
|
||||||
|
/*************************************************************************************/
|
||||||
|
/**
|
||||||
|
* Function End_Move_Zone_Corner
|
||||||
|
* Remove the currently selected corner in a zone outline
|
||||||
|
* the .m_CornerSelection is used as corner selection
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if ( zone_container->m_Poly->GetNumCorners() <= 3 )
|
||||||
|
{
|
||||||
|
Delete_Zone( DC, NULL, zone_container->m_TimeStamp );
|
||||||
|
m_Pcb->Delete( zone_container );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int layer = zone_container->GetLayer();
|
||||||
|
|
||||||
|
if ( DC )
|
||||||
|
{
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
if( layer == edge_zone->GetLayer() )
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zone_container->m_Poly->DeleteCorner(zone_container->m_CornerSelection);
|
||||||
|
|
||||||
|
// modify zones outlines accordiing to the new zone_container shape
|
||||||
|
m_Pcb->AreaPolygonModified( zone_container, true, false );
|
||||||
|
if ( DC )
|
||||||
|
{
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
if( layer == edge_zone->GetLayer() )
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,19 +376,21 @@ void Abort_Zone_Move_Corner( WinEDA_DrawPanel* Panel, wxDC* DC )
|
||||||
|
|
||||||
if( s_CornerIsNew )
|
if( s_CornerIsNew )
|
||||||
{
|
{
|
||||||
zone_container->DeleteCorner( zone_container->m_CornerSelection );
|
zone_container->m_Poly->DeleteCorner( zone_container->m_CornerSelection );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxPoint pos = s_CornerInitialPosition;
|
wxPoint pos = s_CornerInitialPosition;
|
||||||
zone_container->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
|
zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
|
||||||
}
|
}
|
||||||
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
|
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
|
||||||
|
|
||||||
Panel->ManageCurseur = NULL;
|
Panel->ManageCurseur = NULL;
|
||||||
Panel->ForceCloseManageCurseur = NULL;
|
Panel->ForceCloseManageCurseur = NULL;
|
||||||
pcbframe->SetCurItem( NULL );
|
pcbframe->SetCurItem( NULL );
|
||||||
zone_container->m_Flags = 0;
|
zone_container->m_Flags = 0;
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -299,7 +410,7 @@ void Show_Zone_Corner_While_Move_Mouse( WinEDA_DrawPanel* Panel, wxDC* DC, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
wxPoint pos = pcbframe->GetScreen()->m_Curseur;
|
wxPoint pos = pcbframe->GetScreen()->m_Curseur;
|
||||||
zone_container->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
|
zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
|
||||||
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
|
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,36 +428,61 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
|
||||||
EDGE_ZONE* oldedge;
|
EDGE_ZONE* oldedge;
|
||||||
EDGE_ZONE* newedge = NULL;
|
EDGE_ZONE* newedge = NULL;
|
||||||
|
|
||||||
|
// verify if s_CurrentZone exists:
|
||||||
|
unsigned ii;
|
||||||
|
|
||||||
|
for( ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( s_CurrentZone == m_Pcb->m_ZoneDescriptorList[ii] )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ii == m_Pcb->m_ZoneDescriptorList.size() ) // Not found: coul be deleted since last selection
|
||||||
|
{
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
oldedge = m_Pcb->m_CurrentLimitZone;
|
oldedge = m_Pcb->m_CurrentLimitZone;
|
||||||
|
|
||||||
if( m_Pcb->m_CurrentLimitZone == NULL ) /* Start a new contour: init zone params (net and layer) */
|
if( m_Pcb->m_CurrentLimitZone == NULL ) /* Start a new contour: init zone params (net and layer) */
|
||||||
{
|
{
|
||||||
DrawPanel->m_IgnoreMouseEvents = TRUE;
|
if( s_CurrentZone == NULL )
|
||||||
WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this );
|
{
|
||||||
|
DrawPanel->m_IgnoreMouseEvents = TRUE;
|
||||||
|
WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this );
|
||||||
|
|
||||||
int diag = frame->ShowModal();
|
int diag = frame->ShowModal();
|
||||||
frame->Destroy();
|
frame->Destroy();
|
||||||
DrawPanel->MouseToCursorSchema();
|
DrawPanel->MouseToCursorSchema();
|
||||||
DrawPanel->m_IgnoreMouseEvents = FALSE;
|
DrawPanel->m_IgnoreMouseEvents = FALSE;
|
||||||
|
|
||||||
if( diag == ZONE_ABORT )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
GetScreen()->m_Active_Layer = s_Zone_Layer;
|
|
||||||
|
|
||||||
|
if( diag == ZONE_ABORT )
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else /* Start a new contour: init zone params (net and layer) from an existing zone */
|
||||||
|
{
|
||||||
|
GetScreen()->m_Active_Layer = s_Zone_Layer = s_CurrentZone->GetLayer();
|
||||||
|
s_Zone_Hatching = s_CurrentZone->m_Poly->GetHatchStyle();
|
||||||
|
}
|
||||||
/* Show the Net */
|
/* Show the Net */
|
||||||
if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) )
|
if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) )
|
||||||
{
|
{
|
||||||
Hight_Light( DC ); // Remove old hightlight selection
|
Hight_Light( DC ); // Remove old hightlight selection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( s_CurrentZone )
|
||||||
|
s_NetcodeSelection = s_CurrentZone->GetNet();
|
||||||
g_HightLigth_NetCode = s_NetcodeSelection;
|
g_HightLigth_NetCode = s_NetcodeSelection;
|
||||||
if( !g_HightLigt_Status )
|
if( !g_HightLigt_Status )
|
||||||
Hight_Light( DC );
|
Hight_Light( DC );
|
||||||
|
|
||||||
|
if( !s_AddCutoutToCurrentZone )
|
||||||
|
s_CurrentZone = NULL; // the zone is used only once
|
||||||
}
|
}
|
||||||
|
|
||||||
// if first segment
|
// if first segment
|
||||||
if( (m_Pcb->m_CurrentLimitZone == NULL ) /* Initial startt of a new outline */
|
if( (m_Pcb->m_CurrentLimitZone == NULL ) /* Initial start of a new outline */
|
||||||
|| (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */
|
|| (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */
|
||||||
{
|
{
|
||||||
newedge = new EDGE_ZONE( m_Pcb );
|
newedge = new EDGE_ZONE( m_Pcb );
|
||||||
|
@ -400,6 +536,7 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
EDGE_ZONE* edge;
|
EDGE_ZONE* edge;
|
||||||
|
int layer = GetScreen()->m_Active_Layer;
|
||||||
|
|
||||||
if( m_Pcb->m_CurrentLimitZone )
|
if( m_Pcb->m_CurrentLimitZone )
|
||||||
{
|
{
|
||||||
|
@ -431,39 +568,74 @@ void WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
||||||
DrawPanel->ManageCurseur = NULL;
|
DrawPanel->ManageCurseur = NULL;
|
||||||
DrawPanel->ForceCloseManageCurseur = NULL;
|
DrawPanel->ForceCloseManageCurseur = NULL;
|
||||||
|
|
||||||
/* Put edges in list */
|
// Undraw old drawings, because they can have important changes
|
||||||
ZONE_CONTAINER* polygon = new ZONE_CONTAINER( m_Pcb );
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
polygon->SetLayer( GetScreen()->m_Active_Layer );
|
|
||||||
polygon->SetNet( g_HightLigth_NetCode );
|
|
||||||
polygon->m_TimeStamp = GetTimeStamp();
|
|
||||||
|
|
||||||
EQUIPOT* net = m_Pcb->FindNet( g_HightLigth_NetCode );
|
|
||||||
if( net )
|
|
||||||
polygon->m_Netname = net->m_Netname;
|
|
||||||
edge = m_Pcb->m_CurrentLimitZone;
|
|
||||||
polygon->Start( GetScreen()->m_Active_Layer, 0, 0,
|
|
||||||
edge->m_Start.x, edge->m_Start.y,
|
|
||||||
s_Zone_Hatching );
|
|
||||||
edge = edge->Next();
|
|
||||||
while( edge )
|
|
||||||
{
|
{
|
||||||
polygon->AppendCorner( edge->m_Start.x, edge->m_Start.y );
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
edge = edge->Next();
|
if( layer == edge_zone->GetLayer() )
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
|
||||||
}
|
}
|
||||||
|
|
||||||
polygon->Close(); // Close the current corner list
|
/* Put edges in list */
|
||||||
polygon->SetHatch( s_Zone_Hatching );
|
ZONE_CONTAINER* new_zone_container;
|
||||||
polygon->m_PadOption = s_Zone_Pad_Options;
|
if( s_CurrentZone == NULL )
|
||||||
polygon->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
|
{
|
||||||
polygon->m_GridFillValue = g_GridRoutingSize;
|
new_zone_container = new ZONE_CONTAINER( m_Pcb );
|
||||||
|
new_zone_container->SetLayer( layer );
|
||||||
|
new_zone_container->SetNet( g_HightLigth_NetCode );
|
||||||
|
new_zone_container->m_TimeStamp = GetTimeStamp();
|
||||||
|
|
||||||
m_Pcb->m_ZoneDescriptorList.push_back( polygon );
|
edge = m_Pcb->m_CurrentLimitZone;
|
||||||
|
new_zone_container->m_Poly->Start( layer, 0, 0,
|
||||||
|
edge->m_Start.x, edge->m_Start.y,
|
||||||
|
s_Zone_Hatching );
|
||||||
|
edge = edge->Next();
|
||||||
|
while( edge )
|
||||||
|
{
|
||||||
|
new_zone_container->m_Poly->AppendCorner( edge->m_Start.x, edge->m_Start.y );
|
||||||
|
edge = edge->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
new_zone_container->m_Poly->Close(); // Close the current corner list
|
||||||
|
new_zone_container->m_Poly->SetHatch( s_Zone_Hatching );
|
||||||
|
new_zone_container->m_PadOption = s_Zone_Pad_Options;
|
||||||
|
new_zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
|
||||||
|
new_zone_container->m_GridFillValue = g_GridRoutingSize;
|
||||||
|
|
||||||
|
m_Pcb->m_ZoneDescriptorList.push_back( new_zone_container );
|
||||||
|
}
|
||||||
|
else // Append this outline as a cutout to an existing zone
|
||||||
|
{
|
||||||
|
new_zone_container = s_CurrentZone;
|
||||||
|
edge = m_Pcb->m_CurrentLimitZone;
|
||||||
|
while( edge )
|
||||||
|
{
|
||||||
|
new_zone_container->m_Poly->AppendCorner( edge->m_Start.x, edge->m_Start.y );
|
||||||
|
edge = edge->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
new_zone_container->m_Poly->Close(); // Close the current corner list
|
||||||
|
}
|
||||||
|
|
||||||
|
s_AddCutoutToCurrentZone = false;
|
||||||
|
s_CurrentZone = NULL;
|
||||||
|
|
||||||
/* Remove the current temporary list */
|
/* Remove the current temporary list */
|
||||||
DelLimitesZone( DC, TRUE );
|
DelLimitesZone( DC, TRUE );
|
||||||
|
|
||||||
/* Redraw the real edge zone */
|
new_zone_container->m_Flags = 0;
|
||||||
polygon->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
SetCurItem( NULL ); // This outine can be deleted when merging outlines
|
||||||
|
|
||||||
|
// Combine zones if possible :
|
||||||
|
m_Pcb->AreaPolygonModified( new_zone_container, true, false );
|
||||||
|
|
||||||
|
// Redraw the real edge zone :
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
if( layer == edge_zone->GetLayer() )
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
||||||
|
}
|
||||||
|
|
||||||
GetScreen()->SetModify();
|
GetScreen()->SetModify();
|
||||||
}
|
}
|
||||||
|
@ -540,19 +712,32 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container
|
||||||
if( diag == ZONE_ABORT )
|
if( diag == ZONE_ABORT )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
|
// Undraw old zone outlines
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
|
||||||
|
}
|
||||||
|
|
||||||
zone_container->SetLayer( s_Zone_Layer );
|
zone_container->SetLayer( s_Zone_Layer );
|
||||||
zone_container->SetNet( s_NetcodeSelection );
|
zone_container->SetNet( s_NetcodeSelection );
|
||||||
EQUIPOT* net = m_Pcb->FindNet( s_NetcodeSelection );
|
EQUIPOT* net = m_Pcb->FindNet( s_NetcodeSelection );
|
||||||
if( net )
|
if( net )
|
||||||
zone_container->m_Netname = net->m_Netname;
|
zone_container->m_Netname = net->m_Netname;
|
||||||
zone_container->SetHatch( s_Zone_Hatching );
|
zone_container->m_Poly->SetHatch( s_Zone_Hatching );
|
||||||
zone_container->m_PadOption = s_Zone_Pad_Options;
|
zone_container->m_PadOption = s_Zone_Pad_Options;
|
||||||
zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
|
zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
|
||||||
zone_container->m_GridFillValue = g_GridRoutingSize;
|
zone_container->m_GridFillValue = g_GridRoutingSize;
|
||||||
|
|
||||||
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
// Combine zones if possible :
|
||||||
|
m_Pcb->AreaPolygonModified( zone_container, true, false );
|
||||||
|
|
||||||
|
// Redraw the real new zone outlines:
|
||||||
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
|
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
|
||||||
|
}
|
||||||
|
|
||||||
GetScreen()->SetModify();
|
GetScreen()->SetModify();
|
||||||
}
|
}
|
||||||
|
@ -587,11 +772,11 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v
|
||||||
s_NetcodeSelection = zone_container->GetNet();
|
s_NetcodeSelection = zone_container->GetNet();
|
||||||
if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) && DC )
|
if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) && DC )
|
||||||
{
|
{
|
||||||
Hight_Light( DC ); // Remove old hightlight selection
|
Hight_Light( DC ); // Remove old hightlight selection
|
||||||
}
|
}
|
||||||
|
|
||||||
g_HightLigth_NetCode = s_NetcodeSelection;
|
g_HightLigth_NetCode = s_NetcodeSelection;
|
||||||
if( !g_HightLigt_Status && DC)
|
if( !g_HightLigt_Status && DC )
|
||||||
Hight_Light( DC );
|
Hight_Light( DC );
|
||||||
|
|
||||||
if( g_HightLigth_NetCode > 0 )
|
if( g_HightLigth_NetCode > 0 )
|
||||||
|
@ -613,7 +798,7 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v
|
||||||
msg = _( "No Net" );
|
msg = _( "No Net" );
|
||||||
|
|
||||||
Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED );
|
Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED );
|
||||||
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
|
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
|
||||||
zone_container->m_PadOption = s_Zone_Pad_Options;
|
zone_container->m_PadOption = s_Zone_Pad_Options;
|
||||||
zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
|
zone_container->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
|
||||||
zone_container->m_GridFillValue = g_GridRoutingSize;
|
zone_container->m_GridFillValue = g_GridRoutingSize;
|
||||||
|
@ -641,22 +826,22 @@ int WinEDA_PcbFrame::Fill_All_Zones( wxDC* DC, bool verbose )
|
||||||
ZONE_CONTAINER* zone_container;
|
ZONE_CONTAINER* zone_container;
|
||||||
int error_level = 0;
|
int error_level = 0;
|
||||||
|
|
||||||
// Remove all zones :
|
// Remove all zones :
|
||||||
if ( m_Pcb->m_Zone )
|
if( m_Pcb->m_Zone )
|
||||||
{
|
{
|
||||||
m_Pcb->m_Zone->DeleteStructList();
|
m_Pcb->m_Zone->DeleteStructList();
|
||||||
m_Pcb->m_Zone = NULL;
|
m_Pcb->m_Zone = NULL;
|
||||||
m_Pcb->m_NbSegmZone = 0;
|
m_Pcb->m_NbSegmZone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
|
||||||
{
|
{
|
||||||
zone_container = m_Pcb->m_ZoneDescriptorList[ii];
|
zone_container = m_Pcb->m_ZoneDescriptorList[ii];
|
||||||
error_level = Fill_Zone( NULL, zone_container, verbose );
|
error_level = Fill_Zone( NULL, zone_container, verbose );
|
||||||
if( error_level && ! verbose )
|
if( error_level && !verbose )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawPanel->Refresh(true);
|
DrawPanel->Refresh( true );
|
||||||
return error_level;
|
return error_level;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,975 @@
|
||||||
|
/****************************************************************************/
|
||||||
|
/* functions to test, merges and cut polygons used as copper areas outlines */
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fctsys.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "pcbnew.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#undef ASSERT
|
||||||
|
#define ASSERT wxASSERT
|
||||||
|
|
||||||
|
bool bDontShowSelfIntersectionArcsWarning;
|
||||||
|
bool bDontShowSelfIntersectionWarning;
|
||||||
|
bool bDontShowIntersectionArcsWarning;
|
||||||
|
bool bDontShowIntersectionWarning;
|
||||||
|
|
||||||
|
|
||||||
|
#define poly m_Poly
|
||||||
|
|
||||||
|
// carea: describes a copper area
|
||||||
|
#define carea ZONE_CONTAINER
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function AddArea
|
||||||
|
* add empty copper area to net
|
||||||
|
* @return pointer to the new area
|
||||||
|
*/
|
||||||
|
ZONE_CONTAINER* BOARD::AddArea( int netcode, int layer, int x, int y, int hatch )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* new_area = InsertArea( netcode, m_ZoneDescriptorList.size(
|
||||||
|
) - 1, layer, x, y, hatch );
|
||||||
|
|
||||||
|
return new_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove copper area from net
|
||||||
|
* @param area = area to remove
|
||||||
|
* @return 0
|
||||||
|
*/
|
||||||
|
int BOARD::RemoveArea( ZONE_CONTAINER* area_to_remove )
|
||||||
|
{
|
||||||
|
Delete( area_to_remove );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function InsertArea
|
||||||
|
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
|
||||||
|
* @return pointer to the new area
|
||||||
|
*/
|
||||||
|
ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
|
||||||
|
|
||||||
|
new_area->SetNet( netcode );
|
||||||
|
new_area->SetLayer( layer );
|
||||||
|
new_area->m_TimeStamp = GetTimeStamp();
|
||||||
|
if( iarea < (int) ( m_ZoneDescriptorList.size() - 1) )
|
||||||
|
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
|
||||||
|
else
|
||||||
|
m_ZoneDescriptorList.push_back( new_area );
|
||||||
|
|
||||||
|
new_area->poly->Start( layer, 1, 10 * NM_PER_MIL, x, y,
|
||||||
|
hatch );
|
||||||
|
return new_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CompleteArea
|
||||||
|
* 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
|
||||||
|
* @param area_to_complete = area to complete or remove
|
||||||
|
* @param style = style of last corner
|
||||||
|
* @return 1 if Ok, 0 if area removed
|
||||||
|
*/
|
||||||
|
int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style )
|
||||||
|
{
|
||||||
|
if( area_to_complete->poly->GetNumCorners() > 2 )
|
||||||
|
{
|
||||||
|
area_to_complete->poly->Close( style );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RemoveArea( area_to_complete );
|
||||||
|
}
|
||||||
|
return 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->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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ClipAreaPolygon
|
||||||
|
* 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.
|
||||||
|
* @param bMessageBoxInt == TRUE, shows message when clipping occurs.
|
||||||
|
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
|
||||||
|
* @return:
|
||||||
|
* -1 if arcs intersect other sides, so polygon can't be clipped
|
||||||
|
* 0 if no intersecting sides
|
||||||
|
* 1 if intersecting sides
|
||||||
|
* Also sets areas->utility1 flags if areas are modified
|
||||||
|
*/
|
||||||
|
int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||||
|
bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs )
|
||||||
|
{
|
||||||
|
CPolyLine* p = CurrArea->poly;
|
||||||
|
int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag
|
||||||
|
|
||||||
|
if( test == -1 && !bRetainArcs )
|
||||||
|
test = 1;
|
||||||
|
if( test == -1 )
|
||||||
|
{
|
||||||
|
// arc intersections, don't clip unless bRetainArcs == false
|
||||||
|
if( bMessageBoxArc && bDontShowSelfIntersectionArcsWarning == false )
|
||||||
|
{
|
||||||
|
wxString str;
|
||||||
|
str.Printf( wxT( "Area %X of net \"%s\" has arcs intersecting other sides.\n" ),
|
||||||
|
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
|
||||||
|
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( "Manual correction is recommended." );
|
||||||
|
wxMessageBox( str );
|
||||||
|
|
||||||
|
// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState;
|
||||||
|
}
|
||||||
|
return -1; // arcs intersect with other sides, error
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark all areas as unmodified except this one
|
||||||
|
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
|
||||||
|
m_ZoneDescriptorList[ia]->utility = 0;
|
||||||
|
|
||||||
|
CurrArea->utility = 1;
|
||||||
|
|
||||||
|
if( test == 1 )
|
||||||
|
{
|
||||||
|
// non-arc intersections, clip the polygon
|
||||||
|
if( bMessageBoxInt && bDontShowSelfIntersectionWarning == false )
|
||||||
|
{
|
||||||
|
wxString str;
|
||||||
|
str.Printf( wxT( "Area %d 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." );
|
||||||
|
wxMessageBox( str );
|
||||||
|
|
||||||
|
// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//** TODO test for cutouts outside of area
|
||||||
|
//** if( test == 1 )
|
||||||
|
{
|
||||||
|
std::vector<CPolyLine*> * pa = new std::vector<CPolyLine*>;
|
||||||
|
p->Undraw();
|
||||||
|
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
|
||||||
|
{
|
||||||
|
for( int ip = 1; ip < n_poly; ip++ )
|
||||||
|
{
|
||||||
|
// create new copper area and copy poly into it
|
||||||
|
CPolyLine* new_p = (*pa)[ip - 1];
|
||||||
|
CurrArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 );
|
||||||
|
|
||||||
|
// remove the poly that was automatically created for the new area
|
||||||
|
// and replace it with a poly from NormalizeWithGpc
|
||||||
|
delete CurrArea->poly;
|
||||||
|
CurrArea->poly = new_p;
|
||||||
|
CurrArea->poly->Draw();
|
||||||
|
CurrArea->utility = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->Draw();
|
||||||
|
delete pa;
|
||||||
|
}
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an area that has been modified, by clipping its polygon against
|
||||||
|
* 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.
|
||||||
|
* @param modified_area = area to test
|
||||||
|
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
|
||||||
|
* @return :
|
||||||
|
* -1 if arcs intersect other sides, so polygon can't be clipped
|
||||||
|
* 0 if no intersecting sides
|
||||||
|
* 1 if intersecting sides, polygon clipped
|
||||||
|
*/
|
||||||
|
int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
||||||
|
bool bMessageBoxArc,
|
||||||
|
bool bMessageBoxInt )
|
||||||
|
{
|
||||||
|
// clip polygon against itself
|
||||||
|
int test = ClipAreaPolygon( modified_area, bMessageBoxArc, bMessageBoxInt );
|
||||||
|
|
||||||
|
if( test == -1 )
|
||||||
|
return test;
|
||||||
|
|
||||||
|
// now see if we need to clip against other areas
|
||||||
|
bool bCheckAllAreas = false;
|
||||||
|
if( test == 1 )
|
||||||
|
bCheckAllAreas = TRUE;
|
||||||
|
else
|
||||||
|
bCheckAllAreas = TestAreaIntersections( modified_area );
|
||||||
|
if( bCheckAllAreas )
|
||||||
|
CombineAllAreasInNet( modified_area->GetNet(), bMessageBoxInt, TRUE );
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CombineAllAreasInNet
|
||||||
|
* Checks all copper areas in net for intersections, combining them if found
|
||||||
|
* @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( int aNetCode, bool bMessageBox, bool bUseUtility )
|
||||||
|
{
|
||||||
|
if( m_ZoneDescriptorList.size() > 1 )
|
||||||
|
{
|
||||||
|
// 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->poly->GetCornerBounds();
|
||||||
|
bool mod_ia1 = false;
|
||||||
|
for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];
|
||||||
|
if( curr_area->poly->GetLayer() == area2->poly->GetLayer()
|
||||||
|
&& curr_area->utility2 != -1 && area2->utility2 != -1 )
|
||||||
|
{
|
||||||
|
CRect b2 = area2->poly->GetCornerBounds();
|
||||||
|
if( !( b1.left > b2.right || b1.right < b2.left
|
||||||
|
|| b1.bottom > b2.top || b1.top < b2.bottom ) )
|
||||||
|
{
|
||||||
|
// check ia2 against 1a1
|
||||||
|
if( curr_area->utility || area2->utility || bUseUtility ==
|
||||||
|
false )
|
||||||
|
{
|
||||||
|
int ret = TestAreaIntersection( curr_area, area2 );
|
||||||
|
if( ret == 1 )
|
||||||
|
ret = CombineAreas( curr_area, area2 );
|
||||||
|
if( ret == 1 )
|
||||||
|
{
|
||||||
|
if( bMessageBox && bDontShowIntersectionWarning == false )
|
||||||
|
{
|
||||||
|
wxString str;
|
||||||
|
str.Printf(
|
||||||
|
wxT(
|
||||||
|
"Areas %d and %d of net \"%s\" intersect and will be combined.\n" ),
|
||||||
|
ia1 + 1,
|
||||||
|
ia2 + 1,
|
||||||
|
curr_area->m_Netname.GetData() );
|
||||||
|
str += wxT(
|
||||||
|
"If they are complex, this may take a few seconds." );
|
||||||
|
wxMessageBox( str );
|
||||||
|
|
||||||
|
// bDontShowIntersectionWarning = dlg.bDontShowBoxState;
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
curr_area->m_Netname.GetData() );
|
||||||
|
str += wxT( "Therefore, these areas can't be combined." );
|
||||||
|
wxMessageBox( str );
|
||||||
|
|
||||||
|
// bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mod_ia1 )
|
||||||
|
ia1--; // if modified, we need to check it again
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TestAreaIntersections
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
|
||||||
|
{
|
||||||
|
CPolyLine* poly1 = area_to_test->poly;
|
||||||
|
|
||||||
|
for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ )
|
||||||
|
{
|
||||||
|
ZONE_CONTAINER* area2 = m_ZoneDescriptorList[ia2];
|
||||||
|
if( area_to_test->GetNet() != area_to_test->GetNet() )
|
||||||
|
continue;
|
||||||
|
if( area_to_test != area2 )
|
||||||
|
{
|
||||||
|
// see if areas are on same layer
|
||||||
|
if( area_to_test->GetLayer() != area2->GetLayer() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CPolyLine* poly2 = area2->poly;
|
||||||
|
|
||||||
|
// test bounding rects
|
||||||
|
CRect b1 = poly1->GetCornerBounds();
|
||||||
|
CRect b2 = poly2->GetCornerBounds();
|
||||||
|
if( b1.bottom > b2.top
|
||||||
|
|| b1.top < b2.bottom
|
||||||
|
|| b1.left > b2.right
|
||||||
|
|| b1.right < b2.left )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// test for intersecting segments
|
||||||
|
for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ )
|
||||||
|
{
|
||||||
|
int is1 = poly1->GetContourStart( icont1 );
|
||||||
|
int ie1 = poly1->GetContourEnd( icont1 );
|
||||||
|
for( int ic1 = is1; ic1<=ie1; ic1++ )
|
||||||
|
{
|
||||||
|
int xi1 = poly1->GetX( ic1 );
|
||||||
|
int yi1 = poly1->GetY( ic1 );
|
||||||
|
int xf1, yf1, style1;
|
||||||
|
if( ic1 < ie1 )
|
||||||
|
{
|
||||||
|
xf1 = poly1->GetX( ic1 + 1 );
|
||||||
|
yf1 = poly1->GetY( ic1 + 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xf1 = poly1->GetX( is1 );
|
||||||
|
yf1 = poly1->GetY( is1 );
|
||||||
|
}
|
||||||
|
style1 = poly1->GetSideStyle( ic1 );
|
||||||
|
for( int icont2 = 0; icont2<poly2->GetNumContours(); icont2++ )
|
||||||
|
{
|
||||||
|
int is2 = poly2->GetContourStart( icont2 );
|
||||||
|
int ie2 = poly2->GetContourEnd( icont2 );
|
||||||
|
for( int ic2 = is2; ic2<=ie2; ic2++ )
|
||||||
|
{
|
||||||
|
int xi2 = poly2->GetX( ic2 );
|
||||||
|
int yi2 = poly2->GetY( ic2 );
|
||||||
|
int xf2, yf2, style2;
|
||||||
|
if( ic2 < ie2 )
|
||||||
|
{
|
||||||
|
xf2 = poly2->GetX( ic2 + 1 );
|
||||||
|
yf2 = poly2->GetY( ic2 + 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xf2 = poly2->GetX( is2 );
|
||||||
|
yf2 = poly2->GetY( is2 );
|
||||||
|
}
|
||||||
|
style2 = poly2->GetSideStyle( ic2 );
|
||||||
|
int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1,
|
||||||
|
xi2, yi2, xf2, yf2, style2 );
|
||||||
|
if( n_int )
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function TestAreaIntersection
|
||||||
|
* Test for intersection of 2 copper areas
|
||||||
|
* area_to_test must be after area_ref in m_ZoneDescriptorList
|
||||||
|
* @param area_ref = area reference
|
||||||
|
* @param area_to_test = area to compare for intersection calculations
|
||||||
|
* @return : 0 if no intersection
|
||||||
|
* 1 if intersection
|
||||||
|
* 2 if arcs intersect
|
||||||
|
*/
|
||||||
|
int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test )
|
||||||
|
{
|
||||||
|
// see if areas are on same layer
|
||||||
|
if( area_ref->GetLayer() != area_to_test->GetLayer() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
CPolyLine* poly1 = area_ref->poly;
|
||||||
|
CPolyLine* poly2 = area_to_test->poly;
|
||||||
|
|
||||||
|
// test bounding rects
|
||||||
|
CRect b1 = poly1->GetCornerBounds();
|
||||||
|
CRect b2 = poly2->GetCornerBounds();
|
||||||
|
if( b1.bottom > b2.top
|
||||||
|
|| b1.top < b2.bottom
|
||||||
|
|| b1.left > b2.right
|
||||||
|
|| b1.right < b2.left )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// now test for intersecting segments
|
||||||
|
bool bInt = false;
|
||||||
|
bool bArcInt = false;
|
||||||
|
for( int icont1 = 0; icont1<poly1->GetNumContours(); icont1++ )
|
||||||
|
{
|
||||||
|
int is1 = poly1->GetContourStart( icont1 );
|
||||||
|
int ie1 = poly1->GetContourEnd( icont1 );
|
||||||
|
for( int ic1 = is1; ic1<=ie1; ic1++ )
|
||||||
|
{
|
||||||
|
int xi1 = poly1->GetX( ic1 );
|
||||||
|
int yi1 = poly1->GetY( ic1 );
|
||||||
|
int xf1, yf1, style1;
|
||||||
|
if( ic1 < ie1 )
|
||||||
|
{
|
||||||
|
xf1 = poly1->GetX( ic1 + 1 );
|
||||||
|
yf1 = poly1->GetY( ic1 + 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xf1 = poly1->GetX( is1 );
|
||||||
|
yf1 = poly1->GetY( is1 );
|
||||||
|
}
|
||||||
|
style1 = poly1->GetSideStyle( ic1 );
|
||||||
|
for( int icont2 = 0; icont2<poly2->GetNumContours(); icont2++ )
|
||||||
|
{
|
||||||
|
int is2 = poly2->GetContourStart( icont2 );
|
||||||
|
int ie2 = poly2->GetContourEnd( icont2 );
|
||||||
|
for( int ic2 = is2; ic2<=ie2; ic2++ )
|
||||||
|
{
|
||||||
|
int xi2 = poly2->GetX( ic2 );
|
||||||
|
int yi2 = poly2->GetY( ic2 );
|
||||||
|
int xf2, yf2, style2;
|
||||||
|
if( ic2 < ie2 )
|
||||||
|
{
|
||||||
|
xf2 = poly2->GetX( ic2 + 1 );
|
||||||
|
yf2 = poly2->GetY( ic2 + 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xf2 = poly2->GetX( is2 );
|
||||||
|
yf2 = poly2->GetY( is2 );
|
||||||
|
}
|
||||||
|
style2 = poly2->GetSideStyle( ic2 );
|
||||||
|
int n_int = FindSegmentIntersections( xi1, yi1, xf1, yf1, style1,
|
||||||
|
xi2, yi2, xf2, yf2, style2 );
|
||||||
|
if( n_int )
|
||||||
|
{
|
||||||
|
bInt = TRUE;
|
||||||
|
if( style1 != CPolyLine::STRAIGHT || style2 != CPolyLine::STRAIGHT )
|
||||||
|
bArcInt = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bArcInt )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bArcInt )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bArcInt )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !bInt )
|
||||||
|
return 0;
|
||||||
|
if( bArcInt )
|
||||||
|
return 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function CombineAreas
|
||||||
|
* If possible, combine 2 copper areas
|
||||||
|
* area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList
|
||||||
|
* area_to_combine will be deleted, if areas are combined
|
||||||
|
* @return : 0 if no intersection
|
||||||
|
* 1 if intersection
|
||||||
|
* 2 if arcs intersect
|
||||||
|
*/
|
||||||
|
int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine )
|
||||||
|
{
|
||||||
|
if( area_ref == area_to_combine )
|
||||||
|
ASSERT( 0 );
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// test for intersection
|
||||||
|
int test = TestAreaIntersection( area_ref, area_to_combine );
|
||||||
|
if( test != 1 )
|
||||||
|
return test; // no intersection
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// polygons intersect, combine them
|
||||||
|
CPolyLine* poly1 = area_ref->poly;
|
||||||
|
CPolyLine* poly2 = area_to_combine->poly;
|
||||||
|
std::vector<CArc> arc_array1;
|
||||||
|
std::vector<CArc> arc_array2;
|
||||||
|
poly1->MakeGpcPoly( -1, &arc_array1 );
|
||||||
|
poly2->MakeGpcPoly( -1, &arc_array2 );
|
||||||
|
int n_ext_cont1 = 0;
|
||||||
|
for( int ic = 0; ic<poly1->GetGpcPoly()->num_contours; ic++ )
|
||||||
|
if( !( (poly1->GetGpcPoly()->hole)[ic] ) )
|
||||||
|
n_ext_cont1++;
|
||||||
|
|
||||||
|
int n_ext_cont2 = 0;
|
||||||
|
for( int ic = 0; ic<poly2->GetGpcPoly()->num_contours; ic++ )
|
||||||
|
if( !( (poly2->GetGpcPoly()->hole)[ic] ) )
|
||||||
|
n_ext_cont2++;
|
||||||
|
|
||||||
|
gpc_polygon* union_gpc = new gpc_polygon;
|
||||||
|
gpc_polygon_clip( GPC_UNION, poly1->GetGpcPoly(), poly2->GetGpcPoly(), union_gpc );
|
||||||
|
|
||||||
|
// get number of outside contours
|
||||||
|
int n_union_ext_cont = 0;
|
||||||
|
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||||
|
if( !( (union_gpc->hole)[ic] ) )
|
||||||
|
n_union_ext_cont++;
|
||||||
|
|
||||||
|
// if no intersection, free new gpc and return
|
||||||
|
if( n_union_ext_cont == n_ext_cont1 + n_ext_cont2 )
|
||||||
|
{
|
||||||
|
gpc_free_polygon( union_gpc );
|
||||||
|
delete union_gpc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
|
||||||
|
RemoveArea( area_to_combine );
|
||||||
|
area_ref->m_Poly->RemoveAllContours();
|
||||||
|
|
||||||
|
// create area with external contour
|
||||||
|
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||||
|
{
|
||||||
|
if( !(union_gpc->hole)[ic] )
|
||||||
|
{
|
||||||
|
// external contour, replace this poly
|
||||||
|
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
||||||
|
{
|
||||||
|
int x = ( (union_gpc->contour)[ic].vertex )[i].x;
|
||||||
|
int y = ( (union_gpc->contour)[ic].vertex )[i].y;
|
||||||
|
if( i==0 )
|
||||||
|
{
|
||||||
|
area_ref->m_Poly->Start( area_ref->GetLayer(), 0, 0, x, y, area_ref->m_Poly->GetHatchStyle() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
area_ref->m_Poly->AppendCorner( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
area_ref->m_Poly->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add holes
|
||||||
|
for( int ic = 0; ic<union_gpc->num_contours; ic++ )
|
||||||
|
{
|
||||||
|
if( (union_gpc->hole)[ic] )
|
||||||
|
{
|
||||||
|
// hole
|
||||||
|
for( int i = 0; i<union_gpc->contour[ic].num_vertices; i++ )
|
||||||
|
{
|
||||||
|
int x = ( (union_gpc->contour)[ic].vertex )[i].x;
|
||||||
|
int y = ( (union_gpc->contour)[ic].vertex )[i].y;
|
||||||
|
area_ref->m_Poly->AppendCorner( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
area_ref->m_Poly->Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
area_ref->utility = 1;
|
||||||
|
area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
||||||
|
area_ref->m_Poly->RestoreArcs( &arc_array2 );
|
||||||
|
area_ref->m_Poly->Draw();
|
||||||
|
gpc_free_polygon( union_gpc );
|
||||||
|
delete union_gpc;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void dra_areas( CDlgLog* log, int copper_layers,
|
||||||
|
int units, BOOL check_unrouted,
|
||||||
|
CArray<CPolyLine> * board_outline,
|
||||||
|
DesignRules* dr, DRErrorList* drelist )
|
||||||
|
{
|
||||||
|
CString d_str, x_str, y_str;
|
||||||
|
CString str;
|
||||||
|
CString str2;
|
||||||
|
long nerrors = 0;
|
||||||
|
|
||||||
|
// now iterate through all areas
|
||||||
|
for( int ia = 0; ia<net->nareas; ia++ )
|
||||||
|
{
|
||||||
|
carea* a = &net->area[ia];
|
||||||
|
|
||||||
|
// iterate through all nets again
|
||||||
|
POSITION pos2 = pos;
|
||||||
|
void* ptr2;
|
||||||
|
CString name2;
|
||||||
|
while( pos2 != NULL )
|
||||||
|
{
|
||||||
|
m_nlist->m_map.GetNextAssoc( pos2, name2, ptr2 );
|
||||||
|
cnet* net2 = (cnet*) ptr2;
|
||||||
|
for( int ia2 = 0; ia2<net2->nareas; ia2++ )
|
||||||
|
{
|
||||||
|
carea* a2 = &net2->area[ia2];
|
||||||
|
|
||||||
|
// test for same layer
|
||||||
|
if( a->poly->GetLayer() == a2->poly->GetLayer() )
|
||||||
|
{
|
||||||
|
// test for points inside one another
|
||||||
|
for( int ic = 0; ic<a->poly->GetNumCorners(); ic++ )
|
||||||
|
{
|
||||||
|
int x = a->poly->GetX( ic );
|
||||||
|
int y = a->poly->GetY( ic );
|
||||||
|
if( a2->poly->TestPointInside( x, y ) )
|
||||||
|
{
|
||||||
|
// COPPERAREA_COPPERAREA error
|
||||||
|
id id_a = net->id;
|
||||||
|
id_a.st = ID_AREA;
|
||||||
|
id_a.i = ia;
|
||||||
|
id_a.sst = ID_SEL_CORNER;
|
||||||
|
id_a.ii = ic;
|
||||||
|
str.Format(
|
||||||
|
"%ld: \"%s\" copper area inside \"%s\" inside copper area\r\n",
|
||||||
|
nerrors + 1,
|
||||||
|
net->name,
|
||||||
|
net2->name );
|
||||||
|
DRError* dre = drelist->Add( nerrors,
|
||||||
|
DRError::COPPERAREA_INSIDE_COPPERAREA,
|
||||||
|
&str,
|
||||||
|
&net->name,
|
||||||
|
&net2->name,
|
||||||
|
id_a,
|
||||||
|
id_a,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
0,
|
||||||
|
0 );
|
||||||
|
if( dre )
|
||||||
|
{
|
||||||
|
nerrors++;
|
||||||
|
if( log )
|
||||||
|
log->AddLine( str );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int ic2 = 0; ic2<a2->poly->GetNumCorners(); ic2++ )
|
||||||
|
{
|
||||||
|
int x = a2->poly->GetX( ic2 );
|
||||||
|
int y = a2->poly->GetY( ic2 );
|
||||||
|
if( a->poly->TestPointInside( x, y ) )
|
||||||
|
{
|
||||||
|
// COPPERAREA_COPPERAREA error
|
||||||
|
id id_a = net2->id;
|
||||||
|
id_a.st = ID_AREA;
|
||||||
|
id_a.i = ia2;
|
||||||
|
id_a.sst = ID_SEL_CORNER;
|
||||||
|
id_a.ii = ic2;
|
||||||
|
str.Format( "%ld: \"%s\" copper area inside \"%s\" copper area\r\n",
|
||||||
|
nerrors + 1, net2->name, net->name );
|
||||||
|
DRError* dre = drelist->Add( nerrors,
|
||||||
|
DRError::COPPERAREA_INSIDE_COPPERAREA,
|
||||||
|
&str,
|
||||||
|
&net2->name,
|
||||||
|
&net->name,
|
||||||
|
id_a,
|
||||||
|
id_a,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
0,
|
||||||
|
0 );
|
||||||
|
if( dre )
|
||||||
|
{
|
||||||
|
nerrors++;
|
||||||
|
if( log )
|
||||||
|
log->AddLine( str );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now test spacing between areas
|
||||||
|
for( int icont = 0; icont<a->poly->GetNumContours(); icont++ )
|
||||||
|
{
|
||||||
|
int ic_start = a->poly->GetContourStart( icont );
|
||||||
|
int ic_end = a->poly->GetContourEnd( icont );
|
||||||
|
for( int ic = ic_start; ic<=ic_end; ic++ )
|
||||||
|
{
|
||||||
|
id id_a = net->id;
|
||||||
|
id_a.st = ID_AREA;
|
||||||
|
id_a.i = ia;
|
||||||
|
id_a.sst = ID_SIDE;
|
||||||
|
id_a.ii = ic;
|
||||||
|
int ax1 = a->poly->GetX( ic );
|
||||||
|
int ay1 = a->poly->GetY( ic );
|
||||||
|
int ax2, ay2;
|
||||||
|
if( ic == ic_end )
|
||||||
|
{
|
||||||
|
ax2 = a->poly->GetX( ic_start );
|
||||||
|
ay2 = a->poly->GetY( ic_start );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ax2 = a->poly->GetX( ic + 1 );
|
||||||
|
ay2 = a->poly->GetY( ic + 1 );
|
||||||
|
}
|
||||||
|
int astyle = a->poly->GetSideStyle( ic );
|
||||||
|
for( int icont2 = 0; icont2<a2->poly->GetNumContours(); icont2++ )
|
||||||
|
{
|
||||||
|
int ic_start2 = a2->poly->GetContourStart( icont2 );
|
||||||
|
int ic_end2 = a2->poly->GetContourEnd( icont2 );
|
||||||
|
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
|
||||||
|
{
|
||||||
|
id id_b = net2->id;
|
||||||
|
id_b.st = ID_AREA;
|
||||||
|
id_b.i = ia2;
|
||||||
|
id_b.sst = ID_SIDE;
|
||||||
|
id_b.ii = ic2;
|
||||||
|
int bx1 = a2->poly->GetX( ic2 );
|
||||||
|
int by1 = a2->poly->GetY( ic2 );
|
||||||
|
int bx2, by2;
|
||||||
|
if( ic2 == ic_end2 )
|
||||||
|
{
|
||||||
|
bx2 = a2->poly->GetX( ic_start2 );
|
||||||
|
by2 = a2->poly->GetY( ic_start2 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bx2 = a2->poly->GetX( ic2 + 1 );
|
||||||
|
by2 = a2->poly->GetY( ic2 + 1 );
|
||||||
|
}
|
||||||
|
int bstyle = a2->poly->GetSideStyle( ic2 );
|
||||||
|
int x, y;
|
||||||
|
int d = ::GetClearanceBetweenSegments( bx1,
|
||||||
|
by1,
|
||||||
|
bx2,
|
||||||
|
by2,
|
||||||
|
bstyle,
|
||||||
|
0,
|
||||||
|
ax1,
|
||||||
|
ay1,
|
||||||
|
ax2,
|
||||||
|
ay2,
|
||||||
|
astyle,
|
||||||
|
0,
|
||||||
|
dr->copper_copper,
|
||||||
|
&x,
|
||||||
|
&y );
|
||||||
|
if( d < dr->copper_copper )
|
||||||
|
{
|
||||||
|
// COPPERAREA_COPPERAREA error
|
||||||
|
::MakeCStringFromDimension( &d_str,
|
||||||
|
d,
|
||||||
|
units,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1 );
|
||||||
|
::MakeCStringFromDimension( &x_str,
|
||||||
|
x,
|
||||||
|
units,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1 );
|
||||||
|
::MakeCStringFromDimension( &y_str,
|
||||||
|
y,
|
||||||
|
units,
|
||||||
|
FALSE,
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
1 );
|
||||||
|
str.Format(
|
||||||
|
"%ld: \"%s\" copper area to \"%s\" copper area = %s, x=%s, y=%s\r\n",
|
||||||
|
nerrors + 1,
|
||||||
|
net->name,
|
||||||
|
net2->name,
|
||||||
|
d_str,
|
||||||
|
x_str,
|
||||||
|
y_str );
|
||||||
|
DRError* dre = drelist->Add(
|
||||||
|
nerrors,
|
||||||
|
DRError::
|
||||||
|
COPPERAREA_COPPERAREA,
|
||||||
|
&str,
|
||||||
|
&net->name,
|
||||||
|
&net2->name,
|
||||||
|
id_a,
|
||||||
|
id_b,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
0,
|
||||||
|
0 );
|
||||||
|
if( dre )
|
||||||
|
{
|
||||||
|
nerrors++;
|
||||||
|
if( log )
|
||||||
|
log->AddLine( str );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -748,6 +748,19 @@ void CPolyLine::RemoveContour( int icont )
|
||||||
Draw();
|
Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CPolyLine::RemoveAllContours( void )
|
||||||
|
/**
|
||||||
|
* function RemoveAllContours
|
||||||
|
* removes all corners from the lists.
|
||||||
|
* Others params are not chnaged
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
corner.clear( );
|
||||||
|
side_style.clear( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Function InsertCorner
|
/** Function InsertCorner
|
||||||
* insert a new corner between two existing corners
|
* insert a new corner between two existing corners
|
||||||
* @param ic = index for the insertion point: the corner is inserted AFTER ic
|
* @param ic = index for the insertion point: the corner is inserted AFTER ic
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
void MoveCorner( int ic, int x, int y );
|
void MoveCorner( int ic, int x, int y );
|
||||||
void Close( int style = STRAIGHT, BOOL bDraw=TRUE );
|
void Close( int style = STRAIGHT, BOOL bDraw=TRUE );
|
||||||
void RemoveContour( int icont );
|
void RemoveContour( int icont );
|
||||||
|
void RemoveAllContours( void );
|
||||||
|
|
||||||
// drawing functions
|
// drawing functions
|
||||||
void HighlightSide( int is );
|
void HighlightSide( int is );
|
||||||
|
@ -107,6 +108,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// access functions
|
// access functions
|
||||||
|
int GetLayer() { return m_layer;}
|
||||||
int GetNumCorners();
|
int GetNumCorners();
|
||||||
int GetNumSides();
|
int GetNumSides();
|
||||||
int GetClosed();
|
int GetClosed();
|
||||||
|
@ -125,7 +127,7 @@ public:
|
||||||
id GetId();
|
id GetId();
|
||||||
int GetSelBoxSize();
|
int GetSelBoxSize();
|
||||||
CDisplayList * GetDisplayList(){ return m_dlist; };
|
CDisplayList * GetDisplayList(){ return m_dlist; };
|
||||||
int GetHatch(){ return m_HatchStyle; }
|
int GetHatchStyle(){ return m_HatchStyle; }
|
||||||
void SetHatch( int hatch ){ Undraw(); m_HatchStyle = hatch; Draw(); };
|
void SetHatch( int hatch ){ Undraw(); m_HatchStyle = hatch; Draw(); };
|
||||||
void SetX( int ic, int x );
|
void SetX( int ic, int x );
|
||||||
void SetY( int ic, int y );
|
void SetY( int ic, int y );
|
||||||
|
@ -159,14 +161,14 @@ private:
|
||||||
int m_Width; // line width
|
int m_Width; // line width
|
||||||
int m_sel_box; // corner selection box width/2
|
int m_sel_box; // corner selection box width/2
|
||||||
int utility;
|
int utility;
|
||||||
protected:
|
public:
|
||||||
std::vector <CPolyPt> corner; // array of points for corners
|
std::vector <CPolyPt> corner; // array of points for corners
|
||||||
std::vector <int> side_style; // array of styles for sides
|
std::vector <int> side_style; // array of styles for sides
|
||||||
private:
|
private:
|
||||||
std::vector <dl_element*> dl_side; // graphic elements
|
std::vector <dl_element*> dl_side; // graphic elements
|
||||||
std::vector <dl_element*> dl_side_sel;
|
std::vector <dl_element*> dl_side_sel;
|
||||||
std::vector <dl_element*> dl_corner_sel;
|
std::vector <dl_element*> dl_corner_sel;
|
||||||
protected:
|
public:
|
||||||
int m_HatchStyle; // hatch style, see enum above
|
int m_HatchStyle; // hatch style, see enum above
|
||||||
std::vector <CSegment> m_HatchLines; // hatch lines
|
std::vector <CSegment> m_HatchLines; // hatch lines
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue