Commit af445e70 authored by CHARRAS's avatar CHARRAS

remove the old EDGEZONE class. Cleaning code in polyline.x

parent b62a69fc
......@@ -5,6 +5,13 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-Jan-31 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
remove the old EDGEZONE class.
A ZONE_CONTAINER class is used instead to handle the creation of a new zone outline
2008-Jan-29 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew:
......
......@@ -40,7 +40,7 @@ enum KICAD_T {
TYPEMIRE,
TYPESCREEN,
TYPEBLOCK,
TYPEEDGEZONE,
TYPEZONE_UNUSED,
TYPEZONE_EDGE_CORNER,
TYPEZONE_CONTAINER,
......
......@@ -109,6 +109,9 @@
#define ECO2_LAYER (1 << ECO2_N)
#define EDGE_LAYER (1 << EDGE_N)
#define FIRST_NON_COPPER_LAYER ADHESIVE_N_CU
#define LAST_NON_COPPER_LAYER EDGE_N
// extra bits 0xE0000000
/* masques generaux : */
#define ALL_LAYERS 0x1FFFFFFF
......
......@@ -35,7 +35,6 @@ class MODULE;
class TRACK;
class SEGZONE;
class SEGVIA;
class EDGE_ZONE;
class D_PAD;
class TEXTE_MODULE;
class MIREPCB;
......@@ -268,13 +267,6 @@ public:
void Block_Duplicate( wxDC* DC );
/**
* Function DelLimitesZone
* deletes the limits of a zone.
* @param DC A wxDC to draw onto.
* @param Redraw If true, means redraw the pcb without the zone limits
*/
void DelLimitesZone( wxDC* DC, bool Redraw );
// layerhandling:
// (See pcbnew/sel_layer.cpp for description of why null_layer parameter is provided)
......@@ -487,14 +479,21 @@ public:
*/
void Delete_Zone_Fill( wxDC* DC, SEGZONE* Track, long aTimestamp = 0 );
EDGE_ZONE* Del_LastSegmEdgeZone( wxDC* DC );
/** Function Delete_LastCreatedCorner
* Used only while creating a new zone outline
* Remove and delete the current outline segment in progress
* @return 0 if no corner in list, or corner number
*/
int Delete_LastCreatedCorner( wxDC* DC);
/**
* Function Begin_Zone
* initiates a zone edge creation process,
* or terminates the current zone edge and creates a new zone edge stub
*/
EDGE_ZONE* Begin_Zone( wxDC* DC );
int Begin_Zone( wxDC* DC );
/**
* Function End_Zone
......
......@@ -36,7 +36,7 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) :
m_Pads = NULL; // pointeur liste d'acces aux pads
m_Ratsnest = NULL; // pointeur liste rats
m_LocalRatsnest = NULL; // pointeur liste rats local
m_CurrentLimitZone = NULL; // pointeur liste des EDEGE_ZONES
m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the zone contour cuurently in progress
// de determination des contours de zone
}
......@@ -61,9 +61,6 @@ BOARD::~BOARD()
m_Zone->DeleteStructList();
m_Zone = 0;
m_CurrentLimitZone->DeleteStructList();
m_CurrentLimitZone = 0;
MyFree( m_Pads );
m_Pads = 0;
......@@ -75,6 +72,9 @@ BOARD::~BOARD()
DeleteMARKERs();
DeleteZONEOutlines();
delete m_CurrentZoneContour;
m_CurrentZoneContour = NULL;
}
......@@ -588,9 +588,7 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
++p;
break;
case TYPEEDGEZONE:
result = IterateForward( m_CurrentLimitZone, inspector, testData, p );
++p;
case TYPEZONE_UNUSED: // Unused type
break;
default: // catch EOT or ANY OTHER type here and return.
......
......@@ -45,7 +45,7 @@ public:
CHEVELU* m_Ratsnest; // Rastnest list
CHEVELU* m_LocalRatsnest; // Rastnest list used while moving a footprint
EDGE_ZONE* m_CurrentLimitZone; /* zone contour currently in progress */
ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress
BOARD( EDA_BaseStruct* StructFather, WinEDA_BasePcbFrame* frame );
~BOARD();
......
......@@ -89,8 +89,9 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
break;
case TYPEEDGEMODULE:
{
text << _( "Graphic" ) << wxT( " " );
const wxChar* cp;
wxString cp;
switch( ( (EDGE_MODULE*) item )->m_Shape )
{
......@@ -126,10 +127,12 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
cp = wxT( "??EDGE??" ); break;
}
text << *cp << _( " of " )
text << cp;
text << wxT( " (" ) << ReturnPcbLayerName( ((EDGE_MODULE*) item )->m_Layer ).Trim() << wxT( ")" );
text << _( " of " )
<< ( (MODULE*) GetParent() )->GetReference();
break;
}
case TYPETRACK:
// deleting tracks requires all the information we can get to
// disambiguate all the crap under the cursor!
......@@ -239,8 +242,8 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const
;
break;
case TYPEEDGEZONE:
text << _( "Edge Zone" ) << _( " on " ) << ReturnPcbLayerName( item->GetLayer() ).Trim(); // @todo: extend text
case TYPEZONE_UNUSED:
text << wxT( "Unused" );
break;
default:
......@@ -318,8 +321,8 @@ const char** BOARD_ITEM::MenuIcon() const
xpm = add_mires_xpm;
break;
case TYPEEDGEZONE:
xpm = show_mod_edge_xpm; // @todo: pcb edge xpm
case TYPEZONE_UNUSED:
xpm = 0; // unused
break;
default:
......
......@@ -298,70 +298,9 @@ void EDGE_MODULE::Display_Infos( WinEDA_DrawFrame* frame )
}
#if 0 // replaced by Save()
/*****************************************/
int EDGE_MODULE::WriteDescr( FILE* File )
/*****************************************/
/* Write one EDGE_MODULE description
* File must be opened.
*/
{
int NbLigne = 0, ii, * ptr;
switch( m_Shape )
{
case S_SEGMENT:
fprintf( File, "DS %d %d %d %d %d %d\n",
m_Start0.x, m_Start0.y,
m_End0.x, m_End0.y,
m_Width, m_Layer );
NbLigne++;
break;
case S_CIRCLE:
fprintf( File, "DC %d %d %d %d %d %d\n",
m_Start0.x, m_Start0.y,
m_End0.x, m_End0.y,
m_Width, m_Layer );
NbLigne++;
break;
case S_ARC:
fprintf( File, "DA %d %d %d %d %d %d %d\n",
m_Start0.x, m_Start0.y,
m_End0.x, m_End0.y,
m_Angle,
m_Width, m_Layer );
NbLigne++;
break;
case S_POLYGON:
fprintf( File, "DP %d %d %d %d %d %d %d\n",
m_Start0.x, m_Start0.y,
m_End0.x, m_End0.y,
m_PolyCount,
m_Width, m_Layer );
NbLigne++;
for( ii = 0, ptr = m_PolyList; ii < m_PolyCount; ii++ )
{
fprintf( File, "Dl %d %d\n",
*ptr, *(ptr + 1) );
NbLigne++; ptr += 2;
}
break;
default:
DisplayError( NULL, wxT( "Type Edge Module inconnu" ) );
break;
}
return NbLigne;
}
#endif
/*******************************************/
bool EDGE_MODULE::Save( FILE* aFile ) const
/*******************************************/
{
int ret = -1;
......@@ -514,12 +453,15 @@ int EDGE_MODULE::ReadDescr( char* Line, FILE* File,
break;
}
// Controle d'epaisseur raisonnable:
// Check for a reasonnable width:
if( m_Width <= 1 )
m_Width = 1;
if( m_Width > MAX_WIDTH )
m_Width = MAX_WIDTH;
// Check for a reasonnable layer:
if ( (m_Layer < FIRST_NON_COPPER_LAYER) || (m_Layer > LAST_NON_COPPER_LAYER) )
m_Layer = SILKSCREEN_N_CMP;
return error;
}
......
......@@ -12,67 +12,6 @@
#include "pcbnew.h"
#include "trigo.h"
/**********************/
/* Class EDGE_ZONE */
/**********************/
/* now used only to create a zone outline
* TODO: remove this class and use only the ZONE_CONTAINER::m_Poly
* to create outlines
*/
/* Constructor */
EDGE_ZONE::EDGE_ZONE( BOARD* parent ) :
DRAWSEGMENT( parent, TYPEEDGEZONE )
{
m_Width = 2; // a minimum for visibility, while dragging
SetNet(0);
}
/* Destructor */
EDGE_ZONE:: ~EDGE_ZONE()
{
}
/****************************************/
bool EDGE_ZONE::Save( FILE* aFile ) const
/****************************************/
/* edge_zone is a temporary item only used when creating a zone area.
* it will not saved in file
*/
{
return true;
}
// see pcbstruct.h
void EDGE_ZONE::Display_Infos( WinEDA_DrawFrame* frame )
{
int itype;
wxString msg;
frame->MsgPanel->EraseMsgBox();
itype = m_Type & 0x0F;
msg = wxT( "Edge Zone" );
Affiche_1_Parametre( frame, 1, _( "Type" ), msg, DARKCYAN );
Affiche_1_Parametre( frame, 16, _( "Layer" ),
ReturnPcbLayerName( GetLayer() ), BROWN );
msg.Empty(); msg << GetNet();
Affiche_1_Parametre( frame, 25, _( "Netcode" ), msg, RED );
msg = wxT("???");
if ( m_Parent )
{
EQUIPOT* net = ((BOARD*) m_Parent)->FindNet( GetNet() );
if( net )
msg = net->m_Netname;
}
Affiche_1_Parametre( frame, 34, _( "Netname" ), msg, RED );
}
/************************/
/* class ZONE_CONTAINER */
......@@ -82,48 +21,50 @@ 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(); // Outlines
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(); // Outlines
}
ZONE_CONTAINER::~ZONE_CONTAINER()
{
delete m_Poly;
m_Poly = NULL;
delete m_Poly;
m_Poly = NULL;
}
/*******************************************/
void ZONE_CONTAINER::SetNet( int anet_code )
/*******************************************/
/**
* Set the netcode and the netname
* Set the netcode and the netname
* if netcode >= 0, set the netname
* if netcode < 0: keep old netname (used to set an necode error flag)
*/
{
m_NetCode = anet_code;
if ( anet_code < 0 ) return;
if ( m_Parent )
{
EQUIPOT* net = ((BOARD*) m_Parent)->FindNet( anet_code );
if( net )
m_Netname = net->m_Netname;
else m_Netname.Empty();
}
else m_Netname.Empty();
}
m_NetCode = anet_code;
if( anet_code < 0 )
return;
if( m_Parent )
{
EQUIPOT* net = ( (BOARD*) m_Parent )->FindNet( anet_code );
if( net )
m_Netname = net->m_Netname;
else
m_Netname.Empty();
}
else
m_Netname.Empty();
}
/********************************************/
......@@ -133,144 +74,163 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
if( GetState( DELETED ) )
return true;
unsigned item_pos;
int ret;
unsigned corners_count = m_Poly->corner.size();
int outline_hatch;
fprintf( aFile, "$CZONE_OUTLINE\n");
// Save the outline main info
ret = fprintf( aFile, "ZInfo %8.8lX %d \"%s\"\n",
m_TimeStamp, m_NetCode,
CONV_TO_UTF8(m_Netname) );
if ( ret < 3 ) return false;
// Save the ouline layer info
ret = fprintf( aFile, "ZLayer %d\n", m_Layer );
if ( ret < 1 ) return false;
// Save the ouline aux info
switch ( m_Poly->GetHatchStyle() )
{
default:
case CPolyLine::NO_HATCH:
outline_hatch = 'N';
break;
case CPolyLine::DIAGONAL_EDGE:
outline_hatch = 'E';
break;
case CPolyLine::DIAGONAL_FULL:
outline_hatch = 'F';
break;
}
ret = fprintf( aFile, "ZAux %d %c\n", corners_count, outline_hatch );
if ( ret < 2 ) return false;
// Save the corner list
for ( item_pos = 0; item_pos < corners_count; item_pos++ )
{
ret = fprintf( aFile, "ZCorner %d %d %d \n",
unsigned item_pos;
int ret;
unsigned corners_count = m_Poly->corner.size();
int outline_hatch;
fprintf( aFile, "$CZONE_OUTLINE\n" );
// Save the outline main info
ret = fprintf( aFile, "ZInfo %8.8lX %d \"%s\"\n",
m_TimeStamp, m_NetCode,
CONV_TO_UTF8( m_Netname ) );
if( ret < 3 )
return false;
// Save the ouline layer info
ret = fprintf( aFile, "ZLayer %d\n", m_Layer );
if( ret < 1 )
return false;
// Save the ouline aux info
switch( m_Poly->GetHatchStyle() )
{
default:
case CPolyLine::NO_HATCH:
outline_hatch = 'N';
break;
case CPolyLine::DIAGONAL_EDGE:
outline_hatch = 'E';
break;
case CPolyLine::DIAGONAL_FULL:
outline_hatch = 'F';
break;
}
ret = fprintf( aFile, "ZAux %d %c\n", corners_count, outline_hatch );
if( ret < 2 )
return false;
// Save the corner list
for( item_pos = 0; item_pos < corners_count; item_pos++ )
{
ret = fprintf( aFile, "ZCorner %d %d %d \n",
m_Poly->corner[item_pos].x, m_Poly->corner[item_pos].y,
m_Poly->corner[item_pos].end_contour );
if ( ret < 3 ) return false;
}
fprintf( aFile, "$endCZONE_OUTLINE\n");
return true;
if( ret < 3 )
return false;
}
fprintf( aFile, "$endCZONE_OUTLINE\n" );
return true;
}
/**********************************************************/
int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
/**********************************************************/
/** Function ReadDescr
* @param aFile = opened file
* @param aLineNum = pointer on a line number counter (can be NULL or missing)
* @return 0 if ok or NULL
*/
{
char Line[1024], * text;
char netname_buffer[1024];
int ret;
int n_corner_item = 0;
int outline_hatch = CPolyLine::NO_HATCH;
bool error = false, has_corner = false;
netname_buffer[0] = 0;
char Line[1024], * text;
char netname_buffer[1024];
int ret;
int n_corner_item = 0;
int outline_hatch = CPolyLine::NO_HATCH;
bool error = false, has_corner = false;
netname_buffer[0] = 0;
while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
{
if( strnicmp(Line, "ZCorner", 7 ) == 0 ) // new corner found
if( strnicmp( Line, "ZCorner", 7 ) == 0 ) // new corner found
{
int x = 0, y = 0, flag = 0;
text = Line + 7;
ret = sscanf( text, "%d %d %d", &x, &y, &flag);
if (ret < 3 ) error = true;
else
{
if ( ! has_corner )
m_Poly->Start( m_Layer, 0, 0,
x, y,
outline_hatch );
else
m_Poly->AppendCorner( x, y );
has_corner = true;
if ( flag ) m_Poly->Close();
}
}
if( strnicmp(Line, "ZInfo", 5 ) == 0 ) // general info found
int x = 0, y = 0, flag = 0;
text = Line + 7;
ret = sscanf( text, "%d %d %d", &x, &y, &flag );
if( ret < 3 )
error = true;
else
{
if( !has_corner )
m_Poly->Start( m_Layer, x, y, outline_hatch );
else
AppendCorner( wxPoint(x, y) );
has_corner = true;
if( flag )
m_Poly->Close();
}
}
if( strnicmp( Line, "ZInfo", 5 ) == 0 ) // general info found
{
int ts = 0, netcode = 0;
text = Line + 5;
ret = sscanf( text, "%X %d %s", &ts, &netcode, netname_buffer);
if (ret < 3 ) error = true;
else
{
m_TimeStamp = ts;
m_NetCode = netcode;
ReadDelimitedText( netname_buffer, netname_buffer, 1024 );
m_Netname = CONV_FROM_UTF8(netname_buffer);
}
}
if( strnicmp(Line, "ZLayer", 6 ) == 0 ) // layer found
int ts = 0, netcode = 0;
text = Line + 5;
ret = sscanf( text, "%X %d %s", &ts, &netcode, netname_buffer );
if( ret < 3 )
error = true;
else
{
m_TimeStamp = ts;
m_NetCode = netcode;
ReadDelimitedText( netname_buffer, netname_buffer, 1024 );
m_Netname = CONV_FROM_UTF8( netname_buffer );
}
}
if( strnicmp( Line, "ZLayer", 6 ) == 0 ) // layer found
{
int x = 0;
text = Line + 6;
ret = sscanf( text, "%d", &x);
if (ret < 1 ) error = true;
else m_Layer = x;
}
if( strnicmp(Line, "ZAux", 4 ) == 0 ) // aux info found
int x = 0;
text = Line + 6;
ret = sscanf( text, "%d", &x );
if( ret < 1 )
error = true;
else
m_Layer = x;
}
if( strnicmp( Line, "ZAux", 4 ) == 0 ) // aux info found
{
int x = 0;
char hopt[10];
text = Line + 4;
ret = sscanf( text, "%d %c", &x, hopt );
if (ret < 2 ) error = true;
else
{
n_corner_item = x;
switch ( hopt[0] )
{
case 'n':
case 'N':
outline_hatch = CPolyLine::NO_HATCH;
break;
case 'e':
case 'E':
outline_hatch = CPolyLine::DIAGONAL_EDGE;
break;
case 'f':
case 'F':
outline_hatch = CPolyLine::DIAGONAL_FULL;
break;
}
}
}
if( strnicmp(Line, "$end", 4 ) == 0 ) // end of description
int x = 0;
char hopt[10];
text = Line + 4;
ret = sscanf( text, "%d %c", &x, hopt );
if( ret < 2 )
error = true;
else
{
n_corner_item = x;
switch( hopt[0] )
{
case 'n':
case 'N':
outline_hatch = CPolyLine::NO_HATCH;
break;
case 'e':
case 'E':
outline_hatch = CPolyLine::DIAGONAL_EDGE;
break;
case 'f':
case 'F':
outline_hatch = CPolyLine::DIAGONAL_FULL;
break;
}
}
}
if( strnicmp( Line, "$end", 4 ) == 0 ) // end of description
{
break;
}
}
return error ? 0 : 1;
break;
}
}
return error ? 0 : 1;
}
......@@ -285,7 +245,10 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& off
* @param draw_mode = draw mode: OR, XOR ..
*/
{
if ( DC == NULL ) return;
if( DC == NULL )
return;
wxPoint seg_start, seg_end;
int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
int color = g_DesignSettings.m_LayerColor[m_Layer];
......@@ -315,38 +278,101 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& off
// draw the lines
int i_start_contour = 0;
for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ )
for( int ic = 0; ic < GetNumCorners(); ic++ )
{
int xi = m_Poly->corner[ic].x + offset.x;
int yi = m_Poly->corner[ic].y + offset.y;
int xf, yf;
if( m_Poly->corner[ic].end_contour == FALSE && ic < m_Poly->corner.size() - 1 )
seg_start = GetCornerPosition(ic) + offset;
if( m_Poly->corner[ic].end_contour == FALSE && ic < GetNumCorners() - 1 )
{
xf = m_Poly->corner[ic + 1].x + offset.x;
yf = m_Poly->corner[ic + 1].y + offset.y;
seg_end = GetCornerPosition(ic + 1) + offset;
}
else
{
xf = m_Poly->corner[i_start_contour].x + offset.x;
yf = m_Poly->corner[i_start_contour].y + offset.y;
seg_end = GetCornerPosition(i_start_contour) + offset;
i_start_contour = ic + 1;
}
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
GRLine( &panel->m_ClipBox, DC, seg_start.x, seg_start.y, seg_end.x, seg_end.y, 0, color );
}
// draw hatches
// draw hatches
for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ )
{
int xi = m_Poly->m_HatchLines[ic].xi + offset.x;
int yi = m_Poly->m_HatchLines[ic].yi + offset.y;
int xf = m_Poly->m_HatchLines[ic].xf + offset.x;
int yf =m_Poly->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 );
}
}
/**********************************************************************************************/
void ZONE_CONTAINER::DrawWhileCreateOutline( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode )
/***********************************************************************************************/
/**
* Function DrawWhileCreateOutline
* Draws the zone outline when ir is created.
* The moving edges (last segment and the closing edge segment) are in XOR graphic mode,
* old segment in OR graphic mode
* The closing edge has its owm shape
* @param panel = current Draw Panel
* @param DC = current Device Context
* @param draw_mode = draw mode: OR, XOR ..
*/
{
int current_gr_mode = draw_mode;
bool is_close_segment = false;
wxPoint seg_start, seg_end;
if( DC == NULL )
return;
int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
int color = g_DesignSettings.m_LayerColor[m_Layer] & MASKCOLOR;
if( DisplayOpt.ContrastModeDisplay )
{
if( !IsOnLayer( curr_layer ) )
{
color &= ~MASKCOLOR;
color |= DARKDARKGRAY;
}
}
// draw the lines
wxPoint start_contour_pos = GetCornerPosition(0);
for( int ic = 0; ic < GetNumCorners(); ic++ )
{
int xi = GetCornerPosition(ic).x;
int yi = GetCornerPosition(ic).y;
int xf, yf;
if( m_Poly->corner[ic].end_contour == FALSE && ic < GetNumCorners() - 1 )
{
is_close_segment = false;
xf = GetCornerPosition(ic + 1).x;
yf = GetCornerPosition(ic + 1).y;
if ( (m_Poly->corner[ic + 1].end_contour) || (ic == GetNumCorners() - 2) )
current_gr_mode = GR_XOR;
else
current_gr_mode = draw_mode;
}
else
{
is_close_segment = true;
current_gr_mode = GR_XOR;
xf = start_contour_pos.x;
yf = start_contour_pos.y;
start_contour_pos = GetCornerPosition(ic + 1);
}
GRSetDrawMode( DC, current_gr_mode );
if ( is_close_segment )
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, WHITE );
else
GRLine( &panel->m_ClipBox, DC, xi, yi, xf, yf, 0, color );
}
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
......@@ -375,29 +401,31 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
*/
int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
{
#define CORNER_MIN_DIST 500 // distance (in internal units) to detect a corner in a zone outline
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
m_CornerSelection = -1;
min_dist = CORNER_MIN_DIST;
for ( item_pos = 0; item_pos < lim; item_pos++ )
{
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y );
if( dist <= min_dist )
{
m_CornerSelection = item_pos;
min_dist = dist;
}
}
if ( m_CornerSelection >= 0 )
return item_pos;
#define CORNER_MIN_DIST 500 // distance (in internal units) to detect a corner in a zone outline
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
m_CornerSelection = -1;
min_dist = CORNER_MIN_DIST;
for( item_pos = 0; item_pos < lim; item_pos++ )
{
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs(
m_Poly->corner[item_pos].y - refPos.y );
if( dist <= min_dist )
{
m_CornerSelection = item_pos;
min_dist = dist;
}
}
if( m_CornerSelection >= 0 )
return item_pos;
return -1;
}
/**
* Function HitTestForEdge
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
......@@ -408,61 +436,63 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
*/
int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
{
#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
/* Test for an entire segment */
unsigned first_corner_pos = 0, end_segm;
m_CornerSelection = -1;
min_dist = EDGE_MIN_DIST;
for ( item_pos = 0; item_pos < lim; item_pos++ )
{
end_segm = item_pos+1;
/* the last corner of the current outline is tested
* the last segment of the current outline starts at current corner, and ends
* at the first corner of the outline
*/
if( m_Poly->corner[item_pos].end_contour || end_segm >= lim)
{
unsigned tmp = first_corner_pos;
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
end_segm = tmp; // end_segm is the beginning of the current outline
}
/* test the dist between segment and ref point */
dist = (int) GetPointToLineSegmentDistance( refPos.x,
refPos.y,
m_Poly->corner[item_pos].x,
m_Poly->corner[item_pos].y,
m_Poly->corner[end_segm].x,
m_Poly->corner[end_segm].y );
if( dist <= min_dist )
{
m_CornerSelection = item_pos;
min_dist = dist;
}
}
if ( m_CornerSelection >= 0 )
return item_pos;
m_CornerSelection = -1;
min_dist = EDGE_MIN_DIST;
for( item_pos = 0; item_pos < lim; item_pos++ )
{
end_segm = item_pos + 1;
/* the last corner of the current outline is tested
* the last segment of the current outline starts at current corner, and ends
* at the first corner of the outline
*/
if( m_Poly->corner[item_pos].end_contour || end_segm >= lim )
{
unsigned tmp = first_corner_pos;
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
end_segm = tmp; // end_segm is the beginning of the current outline
}
/* test the dist between segment and ref point */
dist = (int) GetPointToLineSegmentDistance( refPos.x,
refPos.y,
m_Poly->corner[item_pos].x,
m_Poly->corner[item_pos].y,
m_Poly->corner[end_segm].x,
m_Poly->corner[end_segm].y );
if( dist <= min_dist )
{
m_CornerSelection = item_pos;
min_dist = dist;
}
}
if( m_CornerSelection >= 0 )
return item_pos;
return -1;
}
/**
* Function HitTest (overlayed)
* tests if the given EDA_Rect contains the bounds of this object.
* @param refArea : the given EDA_Rect
* @return bool - true if a hit, else false
*/
bool ZONE_CONTAINER::HitTest( EDA_Rect& refArea )
bool ZONE_CONTAINER::HitTest( EDA_Rect& refArea )
{
bool is_out_of_box = false;
bool is_out_of_box = false;
CRect rect = m_Poly->GetCornerBounds();
CRect rect = m_Poly->GetCornerBounds();
if( rect.left < refArea.GetX() )
is_out_of_box = true;
......@@ -476,97 +506,102 @@ bool ZONE_CONTAINER::HitTest( EDA_Rect& refArea )
return is_out_of_box ? false : true;
}
/************************************************************/
void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame )
/************************************************************/
{
wxString msg;
int text_pos;
frame->MsgPanel->EraseMsgBox();
msg = _( "Zone Outline" );
msg = _( "Zone Outline" );
int ncont = m_Poly->GetContour(m_CornerSelection);
if ( ncont ) msg << wxT(" ") << _("(Cutout)");
int ncont = m_Poly->GetContour( m_CornerSelection );
if( ncont )
msg << wxT( " " ) << _( "(Cutout)" );
text_pos = 1;
Affiche_1_Parametre( frame, text_pos, _( "Type" ), msg, DARKCYAN );
text_pos += 15;
if ( GetNet() >= 0 )
{
EQUIPOT* equipot = ( (WinEDA_PcbFrame*) frame )->m_Pcb->FindNet( GetNet() );
if( equipot )
msg = equipot->m_Netname;
else
msg = wxT( "<noname>" );
}
else // a netcode < is an error
{
msg = wxT( " [" );
msg << m_Netname + wxT( "]" );
msg << wxT(" <") << _("Not Found") << wxT(">");
}
Affiche_1_Parametre( frame, text_pos, _( "NetName" ), msg, RED );
/* Display net code : (usefull in test or debug) */
text_pos += 18;
msg.Printf( wxT( "%d" ), GetNet());
Affiche_1_Parametre( frame, text_pos, _( "NetCode" ), msg, RED );
if( GetNet() >= 0 )
{
EQUIPOT* equipot = ( (WinEDA_PcbFrame*) frame )->m_Pcb->FindNet( GetNet() );
if( equipot )
msg = equipot->m_Netname;
else
msg = wxT( "<noname>" );
}
else // a netcode < is an error
{
msg = wxT( " [" );
msg << m_Netname + wxT( "]" );
msg << wxT( " <" ) << _( "Not Found" ) << wxT( ">" );
}
Affiche_1_Parametre( frame, text_pos, _( "NetName" ), msg, RED );
/* Display net code : (usefull in test or debug) */
text_pos += 18;
msg.Printf( wxT( "%d" ), GetNet() );
Affiche_1_Parametre( frame, text_pos, _( "NetCode" ), msg, RED );
text_pos += 8;
msg = ReturnPcbLayerName( m_Layer );
msg = ReturnPcbLayerName( m_Layer );
Affiche_1_Parametre( frame, text_pos, _( "Layer" ), msg, BROWN );
text_pos += 8;
msg.Printf( wxT( "%d" ), m_Poly->corner.size() );
msg.Printf( wxT( "%d" ), m_Poly->corner.size() );
Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE );
text_pos += 8;
msg.Printf( wxT( "%d" ), m_Poly->m_HatchLines.size() );
msg.Printf( wxT( "%d" ), m_Poly->m_HatchLines.size() );
Affiche_1_Parametre( frame, text_pos, _( "Hatch lines" ), msg, BLUE );
}
/* Geometric transformations: */
/**
* Function Move
* Move the outlines
* @param offset = moving vector
*/
void ZONE_CONTAINER::Move(const wxPoint& offset )
void ZONE_CONTAINER::Move( const wxPoint& offset )
{
for ( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ )
{
m_Poly->corner[ii].x += offset.x;
m_Poly->corner[ii].y += offset.y;
}
m_Poly->Hatch();
for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ )
{
m_Poly->corner[ii].x += offset.x;
m_Poly->corner[ii].y += offset.y;
}
m_Poly->Hatch();
}
/**
* Function Move
* Move the outlines
* @param centre = rot centre
* @param angle = in 0.1 degree
*/
void ZONE_CONTAINER::Rotate( const wxPoint& centre, int angle)
void ZONE_CONTAINER::Rotate( const wxPoint& centre, int angle )
{
for ( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ )
{
wxPoint pos;
pos.x = m_Poly->corner[ii].x;
pos.y = m_Poly->corner[ii].y;
RotatePoint(&pos, centre, angle );
m_Poly->corner[ii].x = pos.x;
m_Poly->corner[ii].y = pos.y;
}
m_Poly->Hatch();
for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ )
{
wxPoint pos;
pos.x = m_Poly->corner[ii].x;
pos.y = m_Poly->corner[ii].y;
RotatePoint( &pos, centre, angle );
m_Poly->corner[ii].x = pos.x;
m_Poly->corner[ii].y = pos.y;
}
m_Poly->Hatch();
}
......@@ -575,15 +610,16 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, int angle)
* flip the outlines , relative to a given horizontal axis
* @param mirror_ref = vertical axis position
*/
void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref)
void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
{
for ( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ )
{
m_Poly->corner[ii].y -= mirror_ref.y;
m_Poly->corner[ii].y = - m_Poly->corner[ii].y;
m_Poly->corner[ii].y += mirror_ref.y;
}
m_Poly->Hatch();
for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ )
{
m_Poly->corner[ii].y -= mirror_ref.y;
m_Poly->corner[ii].y = -m_Poly->corner[ii].y;
m_Poly->corner[ii].y += mirror_ref.y;
}
m_Poly->Hatch();
}
......@@ -591,18 +627,16 @@ void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref)
* copy usefull data from the source.
* flags and linked list pointers are NOT copied
*/
void ZONE_CONTAINER::Copy( ZONE_CONTAINER * src )
void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
{
m_Parent = src->m_Parent;
m_Layer = src->m_Layer;
SetNet(src->GetNet());
m_TimeStamp = src->m_TimeStamp;
m_Poly->Copy(src->m_Poly); // copy outlines
m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection
m_ZoneClearance = src->m_ZoneClearance; // clearance value
m_GridFillValue = src->m_GridFillValue; // Grid used for filling
m_PadOption = src->m_PadOption;
m_Poly->SetHatch(src->m_Poly->GetHatchStyle());
m_Parent = src->m_Parent;
m_Layer = src->m_Layer;
SetNet( src->GetNet() );
m_TimeStamp = src->m_TimeStamp;
m_Poly->Copy( src->m_Poly ); // copy outlines
m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection
m_ZoneClearance = src->m_ZoneClearance; // clearance value
m_GridFillValue = src->m_GridFillValue; // Grid used for filling
m_PadOption = src->m_PadOption;
m_Poly->SetHatch( src->m_Poly->GetHatchStyle() );
}
......@@ -73,6 +73,19 @@ public:
void Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int draw_mode );
/**
* Function DrawWhileCreateOutline
* Draws the zone outline when ir is created.
* The moving edges are in XOR graphic mode, old segment in draw_mode graphic mode (usually GR_OR)
* The closing edge has its owm shape
* @param panel = current Draw Panel
* @param DC = current Device Context
* @param draw_mode = draw mode: OR, XOR ..
*/
void DrawWhileCreateOutline( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode = GR_OR );
int GetNet( void ) const
{
return m_NetCode;
......@@ -158,73 +171,36 @@ public:
{
return wxT( "ZONE_CONTAINER" );
}
/** Acces to m_Poly parameters
*/
int GetNumCorners(void)
{
return m_Poly->GetNumCorners();
}
void RemoveAllContours(void)
{
m_Poly->RemoveAllContours();
}
wxPoint GetCornerPosition(int aCornerIndex)
{
return wxPoint(m_Poly->GetX(aCornerIndex), m_Poly->GetY(aCornerIndex));
}
void SetCornerPosition(int aCornerIndex, wxPoint new_pos)
{
m_Poly->SetX(aCornerIndex, new_pos.x);
m_Poly->SetY(aCornerIndex, new_pos.y);
}
void AppendCorner( wxPoint position )
{
m_Poly->AppendCorner( position.x, position.y );
}
};
/*******************/
/* class EDGE_ZONE */
/*******************/
/* Classe used temporary to create a zone outline.
*
* TODO: remove this class and use only the ZONE_CONTAINER::m_Poly
* to create outlines
*/
class EDGE_ZONE : public DRAWSEGMENT
{
private:
int m_NetCode;
public:
EDGE_ZONE( BOARD * StructFather );
~EDGE_ZONE();
EDGE_ZONE* Next()
{
return (EDGE_ZONE*) Pnext;
}
EDGE_ZONE* Back()
{
return (EDGE_ZONE*) Pback;
}
int GetNet( void ) const
{
return m_NetCode;
}
void SetNet( int anet_code )
{
m_NetCode = anet_code;
}
/**
* Function Display_Infos
* has knowledge about the frame and how and where to put status information
* about this object into the frame's message panel.
* Is virtual from EDA_BaseStruct.
* @param frame A WinEDA_BasePcbFrame in which to print status information.
*/
void Display_Infos( WinEDA_DrawFrame* frame );
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/**
* Function GetClass
* returns the class name.
* @return wxString
*/
wxString GetClass() const
{
return wxT( "EDGE_ZONE" );
}
};
#endif // #ifndef CLASS_ZONE_H
......@@ -157,22 +157,23 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
}
/*********************************************/
int DRC::Drc( const EDGE_ZONE* aEdge )
/*********************************************/
/**************************************************************/
int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex )
/*************************************************************/
/**
* Function Drc
* tests the current EDGE_ZONE segment and returns the result and displays the error
* tests the outline segment starting at CornerIndex and returns the result and displays the error
* in the status panel only if one exists.
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @param aEdge The areaparent which contains the corner.
* @param CornerIndex The starting point of the segment to test.
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
{
updatePointers();
if( ! doEdgeZoneDrc( aEdge ) )
if( ! doEdgeZoneDrc( aArea, CornerIndex ) )
{
wxASSERT( m_currentMarker );
m_currentMarker->Display_Infos( m_mainWindow );
......@@ -461,9 +462,10 @@ MARKER* DRC::fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe
return fillMe;
}
MARKER* DRC::fillMarker( const EDGE_ZONE * aEdge, const wxPoint & aPos, int aErrorCode, MARKER* fillMe )
MARKER* DRC::fillMarker( const ZONE_CONTAINER * aArea, const wxPoint & aPos, int aErrorCode, MARKER* fillMe )
{
wxString textA = aEdge->MenuText( m_pcb );
wxString textA = aArea->MenuText( m_pcb );
wxPoint posA = aPos;
......
......@@ -373,7 +373,7 @@ private:
* @param fillMe A MARKER* which is to be filled in, or NULL if one is to
* first be allocated, then filled.
*/
MARKER* fillMarker( const EDGE_ZONE * aEdge, const wxPoint & aPos, int aErrorCode, MARKER* fillMe );
MARKER* fillMarker( const ZONE_CONTAINER * aArea, const wxPoint & aPos, int aErrorCode, MARKER* fillMe );
//-----<categorical group tests>-----------------------------------------
......@@ -413,14 +413,15 @@ private:
/**
* Function doEdgeZoneDrc
* tests the current EDGE_ZONE segment:
* tests a segment in ZONE_CONTAINER * aArea:
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @param aArea The current area.
* @param aCornerIndex The first corner of the segment to test.
* @return bool - false if DRC error or true if OK
*/
bool doEdgeZoneDrc( const EDGE_ZONE* aEdge );
bool doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex );
//-----<single tests>----------------------------------------------
......@@ -496,14 +497,15 @@ public:
/**
* Function Drc
* tests the current EDGE_ZONE segment and returns the result and displays the error
* tests the outline segment starting at CornerIndex and returns the result and displays the error
* in the status panel only if one exists.
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @param aEdge The areaparent which contains the corner.
* @param CornerIndex The starting point of the segment to test.
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int Drc( const EDGE_ZONE* aEdge );
int Drc( ZONE_CONTAINER * aArea, int CornerIndex );
/**
* Function DrcBlind
......
......@@ -267,7 +267,6 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
SetToolID( id, wxCURSOR_PENCIL, _( "Add Zones" ) );
if( !DisplayOpt.DisplayZones )
DisplayInfo( this, _( "Warning: Display Zone is OFF!!!" ) );
DelLimitesZone( &dc, TRUE );
if( !g_HightLigt_Status && (g_HightLigth_NetCode > 0 ) )
Hight_Light( &dc );
break;
......@@ -821,7 +820,8 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
DrawPanel->MouseToCursorSchema();
if( GetCurItem() && (GetCurItem()->m_Flags & IS_NEW) )
{
SetCurItem( Del_LastSegmEdgeZone( &dc ) );
if ( Delete_LastCreatedCorner( &dc ) == 0) // No more segment in outline,
SetCurItem(NULL);
}
break;
......
......@@ -145,8 +145,6 @@ bool WinEDA_BasePcbFrame::Clear_Pcb( bool query )
m_Pcb->m_Zone = NULL;
m_Pcb->m_NbSegmZone = 0;
DelLimitesZone( NULL, FALSE );
m_Pcb->DeleteMARKERs();
m_Pcb->DeleteZONEOutlines();
......@@ -222,7 +220,6 @@ void WinEDA_PcbFrame::Erase_Zones( bool query )
m_Pcb->m_NbSegmZone = 0;
}
DelLimitesZone( NULL, FALSE );
m_Pcb->DeleteZONEOutlines();
GetScreen()->SetModify();
......
......@@ -39,7 +39,10 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
switch( DrawStruct->Type() )
{
case TYPEZONE_CONTAINER:
End_Move_Zone_Corner_Or_Outlines( DC, (ZONE_CONTAINER *) DrawStruct );
if ( (DrawStruct->m_Flags & IS_NEW) )
Begin_Zone( DC );
else
End_Move_Zone_Corner_Or_Outlines( DC, (ZONE_CONTAINER *) DrawStruct );
exit = true;
break;
......@@ -220,13 +223,19 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
case ID_PCB_ZONES_BUTT:
if( (DrawStruct == NULL) || (DrawStruct->m_Flags == 0) )
{
GetScreen()->SetCurItem( DrawStruct = Begin_Zone( DC ) );
if ( Begin_Zone( DC ) )
{
DrawStruct = m_Pcb->m_CurrentZoneContour;
GetScreen()->SetCurItem( DrawStruct );
}
}
else if( DrawStruct
&& (DrawStruct->Type() == TYPEEDGEZONE)
&& (DrawStruct->Type() == TYPEZONE_CONTAINER)
&& (DrawStruct->m_Flags & IS_NEW) )
{
GetScreen()->SetCurItem( DrawStruct = Begin_Zone( DC ) );
Begin_Zone( DC );
DrawStruct = m_Pcb->m_CurrentZoneContour;
GetScreen()->SetCurItem( DrawStruct );
}
else
DisplayError( this, wxT( "Edit: zone internal error" ) );
......
......@@ -277,25 +277,23 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
case TYPEZONE: // Item used to fill a zone
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE,
_( "Delete Zone" ), delete_xpm );
_( "Delete Zone Filling" ), delete_xpm );
break;
case TYPEEDGEZONE: // Graphic Item used to create a new zone outline
if( flags & IS_NEW )
case TYPEZONE_CONTAINER: // Item used to handle a zone area (outlines, holes ...)
if( flags & IS_NEW )
{
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_STOP_CURRENT_EDGE_ZONE,
_( "End edge zone" ), apply_xpm );
_( "Close Zone Outline" ), apply_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER,
_( "Delete Last Corner" ), delete_xpm );
}
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_DELETE_ZONE_LAST_CREATED_CORNER,
_( "Delete Current Edge" ), delete_xpm );
break;
case TYPEZONE_CONTAINER: // Item used to handle a zone area (outlines, holes ...)
else
createPopUpMenuForZones( (ZONE_CONTAINER*) item, aPopMenu );
break;
case TYPETEXTE:
createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu );
createPopUpMenuForTexts( (TEXTE_PCB*) item, aPopMenu );
break;
case TYPETRACK:
......
......@@ -176,18 +176,10 @@ void WinEDA_PcbFrame::Trace_Pcb( wxDC* DC, int mode )
if( g_HightLigt_Status )
DrawHightLight( DC, g_HightLigth_NetCode );
EDGE_ZONE* segment;
for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = segment->Next() )
{
if( segment->m_Flags & IS_MOVED )
continue;
Trace_DrawSegmentPcb( DrawPanel, DC, segment, mode );
}
for( unsigned ii = 0; ii < m_Pcb->m_ZoneDescriptorList.size(); ii++ )
for( unsigned ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->m_ZoneDescriptorList[ii];
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea(ii);
edge_zone->Draw( DrawPanel, DC, wxPoint(0,0), mode);
}
......
......@@ -196,7 +196,12 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
if( cells_count == 0 )
{
if( verbose )
DisplayError( frame, _( "No pads or starting point found to fill this zone outline" ) );
{
msg = _( "No pads or starting point found to fill this zone outline" );
msg << wxT("\n");
msg << MenuText( frame->m_Pcb );
DisplayError( frame, msg );
}
error_level = 2;
goto end_of_zone_fill;
}
......
/////////////////////////////////////////////////////////////////////////////
// Name: zones_by_polygon.cpp
// Licence: GPL License
/////////////////////////////////////////////////////////////////////////////
......@@ -32,7 +33,7 @@ using namespace std;
#include "protos.h"
bool verbose = false; // false if zone outline diags mst not be shown
bool verbose = false; // false if zone outline diags mst not be shown
// Outline creation:
static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC );
......@@ -40,7 +41,9 @@ static void Show_New_Zone_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC*
// Corner moving
static void Abort_Zone_Move_Corner_Or_Outlines( WinEDA_DrawPanel* Panel, wxDC* DC );
static void Show_Zone_Corner_Or_Outline_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
static void Show_Zone_Corner_Or_Outline_While_Move_Mouse( WinEDA_DrawPanel* panel,
wxDC* DC,
bool erase );
/* Local variables */
static bool Zone_45_Only = FALSE;
......@@ -52,11 +55,11 @@ static wxPoint s_CornerInitialPosition; // Used to abort
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
static wxPoint s_CursorLastPosition; // in move zone outline, last cursor position. Used to calculate the move vector
static wxPoint s_CursorLastPosition; // in move zone outline, last cursor position. Used to calculate the move vector
// keys used to store net sort option in config file :
#define ZONE_NET_OUTLINES_HATCH_OPTION_KEY wxT( "Zone_Ouline_Hatch_Opt" )
#define ZONE_NET_SORT_OPTION_KEY wxT( "Zone_NetSort_Opt" )
#define ZONE_NET_FILTER_STRING_KEY wxT( "Zone_Filter_Opt" )
#define ZONE_NET_SORT_OPTION_KEY wxT( "Zone_NetSort_Opt" )
#define ZONE_NET_FILTER_STRING_KEY wxT( "Zone_Filter_Opt" )
enum zone_cmd {
ZONE_ABORT,
......@@ -149,31 +152,29 @@ void WinEDA_PcbFrame::Delete_Zone_Fill( wxDC* DC, SEGZONE* aZone, long aTimestam
}
/*****************************************************************************/
EDGE_ZONE* WinEDA_PcbFrame::Del_LastSegmEdgeZone( wxDC* DC)
/*******************************************************/
int WinEDA_PcbFrame::Delete_LastCreatedCorner( wxDC* DC )
/*****************************************************************************/
/* Used only while creating a new zone outline
/** Used only while creating a new zone outline
* Remove and delete the current outline segment in progress
* @return 0 if no corner in list, or corner number
* if no corner in list, close the outline creation
*/
{
EDGE_ZONE* segm = m_Pcb->m_CurrentLimitZone;
ZONE_CONTAINER* zone = m_Pcb->m_CurrentZoneContour;
if( segm == NULL )
return NULL;
if( zone == NULL )
return 0;
Trace_DrawSegmentPcb( DrawPanel, DC, segm, GR_XOR );
if( zone->GetNumCorners() == 0 )
return 0;
m_Pcb->m_CurrentLimitZone = segm->Next();
delete segm;
zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
segm = m_Pcb->m_CurrentLimitZone;
SetCurItem( segm );
if( segm )
if( zone->GetNumCorners() > 1 )
{
segm->Pback = NULL;
segm->m_Flags |= IS_NEW | IS_MOVED;
zone->m_Poly->DeleteCorner( zone->GetNumCorners() - 1 );
if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
}
......@@ -182,8 +183,9 @@ EDGE_ZONE* WinEDA_PcbFrame::Del_LastSegmEdgeZone( wxDC* DC)
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
SetCurItem( NULL );
zone->RemoveAllContours();
}
return segm;
return zone->GetNumCorners();
}
......@@ -197,14 +199,13 @@ static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC )
*/
{
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
ZONE_CONTAINER* zone = pcbframe->m_Pcb->m_CurrentZoneContour;
if( pcbframe->m_Pcb->m_CurrentLimitZone )
if( zone )
{
if( Panel->ManageCurseur ) // trace in progress
{
Panel->ManageCurseur( Panel, DC, 0 );
}
pcbframe->DelLimitesZone( DC, TRUE );
zone->DrawWhileCreateOutline( Panel, DC, GR_XOR );
zone->m_Flags = 0;
zone->RemoveAllContours();
}
Panel->ManageCurseur = NULL;
......@@ -215,36 +216,6 @@ static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC )
}
/**************************************************************/
void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
/**************************************************************/
{
EDGE_ZONE* segment;
EDGE_ZONE* next;
if( m_Pcb->m_CurrentLimitZone == NULL )
return;
// erase the old zone outline, one segment at a time
for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = next )
{
next = segment->Next();
if( Redraw && DC )
{
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_OR );
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR );
}
delete segment;
}
m_Pcb->m_CurrentLimitZone = NULL;
SetCurItem( NULL );
}
/*******************************************************************************************************/
void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_container,
int corner_id, bool IsNewCorner )
......@@ -257,13 +228,14 @@ void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_con
*/
{
/* Show the Net */
if( g_HightLigt_Status && DC)
if( g_HightLigt_Status && DC )
{
Hight_Light( DC ); // Remove old hightlight selection
}
g_HightLigth_NetCode = s_NetcodeSelection = zone_container->GetNet();
if ( DC ) Hight_Light( DC );
if( DC )
Hight_Light( DC );
zone_container->m_Flags = IN_EDIT;
DrawPanel->ManageCurseur = Show_Zone_Corner_Or_Outline_While_Move_Mouse;
......@@ -275,6 +247,7 @@ void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_con
s_CurrentZone = NULL;
}
/*******************************************************************************************************/
void WinEDA_PcbFrame::Start_Move_Zone_Outlines( wxDC* DC, ZONE_CONTAINER* zone_container )
/*******************************************************************************************************/
......@@ -317,36 +290,38 @@ void WinEDA_PcbFrame::End_Move_Zone_Corner_Or_Outlines( wxDC* DC, ZONE_CONTAINER
zone_container->m_Flags = 0;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
if ( DC )
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
if( DC )
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
GetScreen()->SetModify();
s_AddCutoutToCurrentZone = false;
s_CurrentZone = NULL;
SetCurItem( NULL ); // This outine can be deleted when merging outlines
SetCurItem( NULL ); // This outline can be deleted when merging outlines
/* Combine zones if possible */
wxBusyCursor dummy;
wxBusyCursor dummy;
int layer = zone_container->GetLayer();
int layer = zone_container->GetLayer();
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_XOR, layer);
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_XOR, layer );
m_Pcb->AreaPolygonModified( zone_container, true, verbose );
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_OR, layer);
int ii = m_Pcb->GetAreaIndex(zone_container); // test if zone_container exists
if ( ii < 0 ) zone_container = NULL; // was removed by combining zones
int error_count = m_Pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines(zone_container, true);
if ( error_count )
{
DisplayError(this, _("Area: DRC outline error"));
}
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_OR, layer );
int ii = m_Pcb->GetAreaIndex( zone_container ); // test if zone_container exists
if( ii < 0 )
zone_container = NULL; // was removed by combining zones
int error_count = m_Pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone_container, true );
if( error_count )
{
DisplayError( this, _( "Area: DRC outline error" ) );
}
}
/*************************************************************************************/
void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_container )
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
......@@ -355,31 +330,32 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER * zone_contai
{
GetScreen()->SetModify();
if ( zone_container->m_Poly->GetNumCorners() <= 3 )
{
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp );
m_Pcb->Delete( zone_container );
return;
}
if( zone_container->m_Poly->GetNumCorners() <= 3 )
{
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp );
m_Pcb->Delete( zone_container );
return;
}
int layer = zone_container->GetLayer();
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_XOR, layer);
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_XOR, layer );
zone_container->m_Poly->DeleteCorner( zone_container->m_CornerSelection );
zone_container->m_Poly->DeleteCorner(zone_container->m_CornerSelection);
// modify zones outlines according to the new zone_container shape
// modify zones outlines according to the new zone_container shape
m_Pcb->AreaPolygonModified( zone_container, true, verbose );
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_OR, layer);
int ii = m_Pcb->GetAreaIndex(zone_container); // test if zone_container exists
if ( ii < 0 ) zone_container = NULL; // zone_container does not exist anymaore, after combining zones
int error_count = m_Pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines(zone_container, true);
if ( error_count )
{
DisplayError(this, _("Area: DRC outline error"));
}
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_OR, layer );
int ii = m_Pcb->GetAreaIndex( zone_container ); // test if zone_container exists
if( ii < 0 )
zone_container = NULL; // zone_container does not exist anymaore, after combining zones
int error_count = m_Pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone_container, true );
if( error_count )
{
DisplayError( this, _( "Area: DRC outline error" ) );
}
}
......@@ -397,24 +373,24 @@ void Abort_Zone_Move_Corner_Or_Outlines( WinEDA_DrawPanel* Panel, wxDC* DC )
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
if ( zone_container->m_Flags == IS_MOVED )
{
wxPoint offset;
offset = s_CornerInitialPosition - s_CursorLastPosition;
zone_container->Move(offset);
}
else
{
if( s_CornerIsNew )
{
zone_container->m_Poly->DeleteCorner( zone_container->m_CornerSelection );
}
else
{
wxPoint pos = s_CornerInitialPosition;
zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
}
}
if( zone_container->m_Flags == IS_MOVED )
{
wxPoint offset;
offset = s_CornerInitialPosition - s_CursorLastPosition;
zone_container->Move( offset );
}
else
{
if( s_CornerIsNew )
{
zone_container->m_Poly->DeleteCorner( zone_container->m_CornerSelection );
}
else
{
wxPoint pos = s_CornerInitialPosition;
zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
}
}
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
Panel->ManageCurseur = NULL;
......@@ -436,29 +412,29 @@ void Show_Zone_Corner_Or_Outline_While_Move_Mouse( WinEDA_DrawPanel* Panel, wxDC
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) pcbframe->GetCurItem();
// if( erase ) /* Undraw edge in old position*/
if( erase ) /* Undraw edge in old position*/
{
zone_container->Draw( Panel, DC, wxPoint( 0, 0 ), GR_XOR );
zone_container->Draw( Panel, DC, wxPoint(0,0), GR_XOR );
}
wxPoint pos = pcbframe->GetScreen()->m_Curseur;
if( zone_container->m_Flags == IS_MOVED )
{
wxPoint offset;
offset.x = pos.x - s_CursorLastPosition.x;
offset.y = pos.y - s_CursorLastPosition.y;
zone_container->Move(offset);
s_CursorLastPosition = pos;
}
else
zone_container->m_Poly->MoveCorner( zone_container->m_CornerSelection, pos.x, pos.y );
if( zone_container->m_Flags == IS_MOVED )
{
wxPoint offset;
offset.x = pos.x - s_CursorLastPosition.x;
offset.y = pos.y - s_CursorLastPosition.y;
zone_container->Move( offset );
s_CursorLastPosition = pos;
}
else
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 );
}
/*************************************************/
EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
int WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
/*************************************************/
/**
......@@ -467,15 +443,12 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
* intermediate segment.
*/
{
EDGE_ZONE* oldedge;
EDGE_ZONE* newedge = NULL;
// verify if s_CurrentZone exists:
int ii;
int ii;
for( ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
if( s_CurrentZone == m_Pcb->GetArea(ii) )
if( s_CurrentZone == m_Pcb->GetArea( ii ) )
break;
}
......@@ -485,9 +458,12 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
s_CurrentZone = NULL;
}
oldedge = m_Pcb->m_CurrentLimitZone;
ZONE_CONTAINER* zone;
if( m_Pcb->m_CurrentZoneContour == NULL )
m_Pcb->m_CurrentZoneContour = new ZONE_CONTAINER( m_Pcb );
if( m_Pcb->m_CurrentLimitZone == NULL ) /* Start a new contour: init zone params (net and layer) */
zone = m_Pcb->m_CurrentZoneContour;
if( zone->GetNumCorners() == 0 ) /* Start a new contour: init zone params (net and layer) */
{
if( s_CurrentZone == NULL )
{
......@@ -500,11 +476,11 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
DrawPanel->m_IgnoreMouseEvents = FALSE;
if( diag == ZONE_ABORT )
return NULL;
GetScreen()->m_Active_Layer = s_Zone_Layer; // Set by the dialog frame
return 0;
GetScreen()->m_Active_Layer = s_Zone_Layer; // Set by the dialog frame
}
else /* Start a new contour: init zone params (net and layer) from an existing zone */
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();
......@@ -526,65 +502,51 @@ EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( wxDC* DC )
}
// if first segment
if( (m_Pcb->m_CurrentLimitZone == NULL ) /* Initial start of a new outline */
|| (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */
{
newedge = new EDGE_ZONE( m_Pcb );
newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED;
newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur;
newedge->SetLayer( GetScreen()->m_Active_Layer );
newedge->SetNet( s_NetcodeSelection );
if( Drc_On && m_drc->Drc( newedge ) == BAD_DRC )
{
delete newedge;
// use the form of SetCurItem() which does not write to the msg panel,
// SCREEN::SetCurItem(), so the DRC error remains on screen.
// WinEDA_PcbFrame::SetCurItem() calls Display_Infos().
GetScreen()->SetCurItem( NULL );
DisplayError(this, _("DRC error: this start point is inside or too close an other area"));
return NULL;
}
// link into list:
newedge->Pnext = oldedge;
SetCurItem( newedge );
if( oldedge )
oldedge->Pback = newedge;
m_Pcb->m_CurrentLimitZone = newedge;
if( zone->GetNumCorners() == 0 )
{
zone->m_Flags = IS_NEW;
zone->SetLayer( s_Zone_Layer );
zone->SetNet( s_NetcodeSelection );
zone->m_TimeStamp = GetTimeStamp();
zone->m_PadOption = s_Zone_Pad_Options;
zone->m_ZoneClearance = g_DesignSettings.m_ZoneClearence;
zone->m_GridFillValue = g_GridRoutingSize;
zone->m_Poly->Start( s_Zone_Layer,
GetScreen()->m_Curseur.x, GetScreen()->m_Curseur.y,
s_Zone_Hatching );
zone->AppendCorner( GetScreen()->m_Curseur );
if( Drc_On && m_drc->Drc( zone, 0 ) == BAD_DRC )
{
zone->m_Flags = 0;
zone->RemoveAllContours();
// use the form of SetCurItem() which does not write to the msg panel,
// SCREEN::SetCurItem(), so the DRC error remains on screen.
// WinEDA_PcbFrame::SetCurItem() calls Display_Infos().
GetScreen()->SetCurItem( NULL );
DisplayError( this,
_( "DRC error: this start point is inside or too close an other area" ) );
return 0;
}
SetCurItem( zone );
DrawPanel->ManageCurseur = Show_New_Zone_Edge_While_Move_Mouse;
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Create_Outline;
}
// edge in progress:
else
{
/* edge in progress : the ending point coordinate was set by Show_New_Zone_Edge_While_Move_Mouse */
if( oldedge->m_Start != oldedge->m_End )
ii = zone->GetNumCorners() - 1;
/* edge in progress : the current corner coordinate was set by Show_New_Zone_Edge_While_Move_Mouse */
if( zone->GetCornerPosition( ii - 1 ) != zone->GetCornerPosition( ii ) )
{
if ( Drc_On && m_drc->Drc( oldedge ) == BAD_DRC )
{
return oldedge;
}
oldedge->m_Flags &= ~(IS_NEW | IS_MOVED);
newedge = new EDGE_ZONE( m_Pcb );
newedge->m_Flags = IS_NEW | IS_MOVED;
newedge->m_Start = newedge->m_End = oldedge->m_End;
newedge->SetLayer( oldedge->GetLayer() );
newedge->SetNet( s_NetcodeSelection );
// link into list:
newedge->Pnext = oldedge;
oldedge->Pback = newedge;
m_Pcb->m_CurrentLimitZone = newedge;
SetCurItem( newedge );
if( Drc_On && m_drc->Drc( zone, ii - 1 ) == OK_DRC ) // Ok, we can add a new corner
zone->AppendCorner( GetScreen()->m_Curseur );
}
}
return newedge;
return zone->GetNumCorners();
}
......@@ -600,127 +562,82 @@ bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
* if ok, put it in the main list m_Pcb->m_ZoneDescriptorList (a vector<ZONE_CONTAINER*>)
*/
{
if( m_Pcb->m_CurrentLimitZone == NULL ) return true;
EDGE_ZONE* edge = m_Pcb->m_CurrentLimitZone;
EDGE_ZONE* last_edge = m_Pcb->m_CurrentLimitZone;
int layer = edge->GetLayer();
// Validate the current edge:
if ( edge->m_Start != edge->m_End )
{
Begin_Zone( DC );
if ( edge == m_Pcb->m_CurrentLimitZone ) // no new segment -> DRC error
{
return false;
}
}
/* The last segment is a stub: its lenght is 0.
* Use it to close the polygon by setting its ending point coordinate = start point of first segment
*/
/* search first segment outline ( last item of the linked list ) */
edge = m_Pcb->m_CurrentLimitZone;
while( edge->Next() )
{
edge = edge->Next();
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
}
wxPoint curr_endpoint = m_Pcb->m_CurrentLimitZone->m_End;
m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start;
edge = m_Pcb->m_CurrentLimitZone;
if ( Drc_On && m_drc->Drc( edge ) == BAD_DRC )
{
edge->m_End = curr_endpoint;
if ( last_edge != edge ) // Remove edge create previously
{
delete edge;
m_Pcb->m_CurrentLimitZone = edge = last_edge;
edge->Pback = NULL;
edge->m_Flags = (IS_NEW | IS_MOVED);
}
SetCurItem( edge );
DisplayError(this, _("DRC error: closing this area creates a drc error with an other area"));
ZONE_CONTAINER* zone = m_Pcb->m_CurrentZoneContour;
if( zone == NULL )
return true;
// Validate the curren outline:
if( zone->GetNumCorners() <= 2 ) // An outline must have 3 corners or more
{
Abort_Zone_Create_Outline( DrawPanel, DC );
return true;
}
// Validate the current edge:
int icorner = zone->GetNumCorners() - 1;
if( Drc_On && m_drc->Drc( zone, icorner - 1 ) == BAD_DRC ) // we can't validate last edge
return false;
if( Drc_On && m_drc->Drc( zone, icorner ) == BAD_DRC ) // we can't validate the closing edge
{
DisplayError( this,
_( "DRC error: closing this area creates a drc error with an other area" ) );
DrawPanel->MouseToCursorSchema();
return false;
}
return false;
}
zone->m_Flags = 0;
edge->m_Flags &= ~(IS_NEW | IS_MOVED);
Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR );
zone->DrawWhileCreateOutline( DrawPanel, DC, GR_XOR );
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
// Undraw old drawings, because they can have important changes
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_XOR, layer);
int layer = zone->GetLayer();
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_XOR, layer );
/* Put edges in list */
ZONE_CONTAINER* new_zone_container;
if( s_CurrentZone == NULL )
{
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();
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 );
zone->m_Poly->Close(); // Close the current corner list
m_Pcb->Add( zone );
m_Pcb->m_CurrentZoneContour = NULL;
}
else // Append this outline as a cutout to an existing zone
{
new_zone_container = s_CurrentZone;
edge = m_Pcb->m_CurrentLimitZone;
while( edge )
for( int ii = 0; ii < zone->GetNumCorners(); ii++ )
{
new_zone_container->m_Poly->AppendCorner( edge->m_Start.x, edge->m_Start.y );
edge = edge->Next();
s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) );
}
new_zone_container->m_Poly->Close(); // Close the current corner list
s_CurrentZone->m_Poly->Close(); // Close the current corner list
zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list.
zone = s_CurrentZone;
}
s_AddCutoutToCurrentZone = false;
s_CurrentZone = NULL;
/* Remove the current temporary list */
DelLimitesZone( DC, TRUE );
new_zone_container->m_Flags = 0;
GetScreen()->SetCurItem( NULL ); // This outine can be deleted when merging outlines
// Combine zones if possible :
m_Pcb->AreaPolygonModified( new_zone_container, true, verbose );
m_Pcb->AreaPolygonModified( zone, true, verbose );
// Redraw the real edge zone :
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_OR, layer);
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_OR, layer );
int ii = m_Pcb->GetAreaIndex(new_zone_container); // test if zone_container exists
if ( ii < 0 ) new_zone_container = NULL; // was removed by combining zones
int error_count = m_Pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines(new_zone_container, true);
if ( error_count )
{
DisplayError(this, _("Area: DRC outline error"));
}
int ii = m_Pcb->GetAreaIndex( zone ); // test if zone_container exists
if( ii < 0 )
zone = NULL; // was removed by combining zones
int error_count = m_Pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone, true );
if( error_count )
{
DisplayError( this, _( "Area: DRC outline error" ) );
}
GetScreen()->SetModify();
return true;
return true;
}
......@@ -731,41 +648,32 @@ static void Show_New_Zone_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC*
/* Redraws the edge zone when moving mouse
*/
{
EDGE_ZONE* edge;
EDGE_ZONE* currentEdge;
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent;
wxPoint c_pos = pcbframe->GetScreen()->m_Curseur;
ZONE_CONTAINER* zone = pcbframe->m_Pcb->m_CurrentZoneContour;
if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL )
if( zone == NULL )
return;
int icorner = zone->GetNumCorners() - 1;
if( erase ) /* Undraw edge in old position*/
{
edge = pcbframe->m_Pcb->m_CurrentLimitZone;
// for( ; edge; edge = edge->Next() )
{
Trace_DrawSegmentPcb( panel, DC, edge, GR_XOR );
}
zone->DrawWhileCreateOutline( panel, DC );
}
/* Redraw the curent edge in its new position */
currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone;
if( Zone_45_Only )
{
// calculate the new position as allowed
currentEdge->m_End = pcbframe->GetScreen()->m_Curseur;
Calcule_Coord_Extremite_45( currentEdge->m_Start.x, currentEdge->m_Start.y,
&currentEdge->m_End.x, &currentEdge->m_End.y );
}
else /* all orientations are allowed */
{
currentEdge->m_End = pcbframe->GetScreen()->m_Curseur;
wxPoint StartPoint = zone->GetCornerPosition( icorner - 1 );
Calcule_Coord_Extremite_45( StartPoint.x, StartPoint.y,
&c_pos.x, &c_pos.y );
}
// for( ; currentEdge; currentEdge = currentEdge->Next() )
{
Trace_DrawSegmentPcb( panel, DC, currentEdge, GR_XOR );
}
zone->SetCornerPosition( icorner, c_pos );
zone->DrawWhileCreateOutline( panel, DC );
}
......@@ -789,10 +697,10 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container
if( diag == ZONE_ABORT )
return;
// Undraw old zone outlines
// Undraw old zone outlines
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea(ii);
ZONE_CONTAINER* edge_zone = m_Pcb->GetArea( ii );
edge_zone->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
}
......@@ -810,11 +718,12 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container
m_Pcb->AreaPolygonModified( zone_container, true, verbose );
// Redraw the real new zone outlines:
m_Pcb->RedrawAreasOutlines(DrawPanel, DC, GR_OR, -1);
m_Pcb->RedrawAreasOutlines( DrawPanel, DC, GR_OR, -1 );
GetScreen()->SetModify();
}
/************************************************************************************/
void WinEDA_PcbFrame::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_container )
/************************************************************************************/
......@@ -829,22 +738,22 @@ void WinEDA_PcbFrame::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_contai
* otherwise, the hole is deleted
*/
{
int ncont = zone_container->m_Poly->GetContour(zone_container->m_CornerSelection);
if ( DC )
zone_container->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR);
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); // Remove fill segments
if ( ncont == 0 ) // This is the main outline: remove all
m_Pcb->Delete( zone_container );
else
{
zone_container->m_Poly->RemoveContour( ncont );
if ( DC )
zone_container->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR);
}
int ncont = zone_container->m_Poly->GetContour( zone_container->m_CornerSelection );
if( DC )
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); // Remove fill segments
if( ncont == 0 ) // This is the main outline: remove all
m_Pcb->Delete( zone_container );
else
{
zone_container->m_Poly->RemoveContour( ncont );
if( DC )
zone_container->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
}
GetScreen()->SetModify();
}
......@@ -942,7 +851,7 @@ int WinEDA_PcbFrame::Fill_All_Zones( wxDC* DC, bool verbose )
for( int ii = 0; ii < m_Pcb->GetAreaCount(); ii++ )
{
zone_container = m_Pcb->GetArea(ii);
zone_container = m_Pcb->GetArea( ii );
error_level = Fill_Zone( NULL, zone_container, verbose );
if( error_level && !verbose )
break;
......@@ -962,23 +871,23 @@ int WinEDA_PcbFrame::Fill_All_Zones( wxDC* DC, bool verbose )
* Must be called after pad netcodes are calculated
* @return : error count
*/
int BOARD::SetAreasNetCodesFromNetNames(void)
int BOARD::SetAreasNetCodesFromNetNames( void )
{
int error_count = 0;
for ( int ii = 0; ii < GetAreaCount(); ii++ )
{
const EQUIPOT* net = FindNet( GetArea(ii)->m_Netname );
if ( net )
{
GetArea(ii)->SetNet(net->GetNet());
}
else
{
error_count++;
GetArea(ii)->SetNet(-1); //keep Net Name ane set m_NetCode to -1 : error flag
}
}
return error_count;
int error_count = 0;
for( int ii = 0; ii < GetAreaCount(); ii++ )
{
const EQUIPOT* net = FindNet( GetArea( ii )->m_Netname );
if( net )
{
GetArea( ii )->SetNet( net->GetNet() );
}
else
{
error_count++;
GetArea( ii )->SetNet( -1 ); //keep Net Name ane set m_NetCode to -1 : error flag
}
}
return error_count;
}
......@@ -65,8 +65,7 @@ ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int
else
m_ZoneDescriptorList.push_back( new_area );
new_area->m_Poly->Start( layer, 1, 10 * NM_PER_MIL, x, y,
hatch );
new_area->m_Poly->Start( layer, x, y, hatch );
return new_area;
}
......@@ -744,7 +743,7 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
if( i==0 )
{
area_ref->m_Poly->Start( area_ref->GetLayer(
), 0, 0, x, y, area_ref->m_Poly->GetHatchStyle() );
), x, y, area_ref->m_Poly->GetHatchStyle() );
}
else
area_ref->m_Poly->AppendCorner( x, y );
......@@ -997,17 +996,39 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
/**
* Function doEdgeZoneDrc
* tests the current EDGE_ZONE segment and returns the result and displays the error
* in the status panel only if one exists.
* tests a segment in ZONE_CONTAINER * aArea:
* Test Edge inside other areas
* Test Edge too close other areas
* @param aEdge The current segment to test.
* @param aArea The current area.
* @param aCornerIndex The first corner of the segment to test.
* @return bool - false if DRC error or true if OK
*/
bool DRC::doEdgeZoneDrc( const EDGE_ZONE* aEdge )
bool DRC::doEdgeZoneDrc( ZONE_CONTAINER * aArea, int aCornerIndex )
{
wxString str;
wxPoint start = aArea->GetCornerPosition(aCornerIndex);
wxPoint end;
// Search the end point of the edge starting at aCornerIndex
if( aArea->m_Poly->corner[aCornerIndex].end_contour == FALSE &&
aCornerIndex < (aArea->GetNumCorners() - 1) )
{
end = aArea->GetCornerPosition(aCornerIndex+1);
}
else // aCornerIndex is the last corner of an outline.
// the corresponding end point of the segment is the first corner of the outline
{
int ii = aCornerIndex-1;
end = aArea->GetCornerPosition(ii);
while ( ii >= 0 )
{
if ( aArea->m_Poly->corner[ii].end_contour )
break;
end = aArea->GetCornerPosition(ii);
ii--;
}
}
// iterate through all areas
for( int ia2 = 0; ia2 < m_pcb->GetAreaCount(); ia2++ )
......@@ -1015,20 +1036,20 @@ bool DRC::doEdgeZoneDrc( const EDGE_ZONE* aEdge )
ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ia2 );
// test for same layer
if( Area_To_Test->GetLayer() != aEdge->GetLayer() )
if( Area_To_Test->GetLayer() != aArea->GetLayer() )
continue;
// Test for same net
if( (aEdge->GetNet() == Area_To_Test->GetNet()) && (aEdge->GetNet() > 0) )
if( (aArea->GetNet() == Area_To_Test->GetNet()) && (aArea->GetNet() > 0) )
continue;
// test for ending line inside Area_To_Test
int x = aEdge->m_End.x;
int y = aEdge->m_End.y;
int x = end.x;
int y = end.y;
if( Area_To_Test->m_Poly->TestPointInside( x, y ) )
{
// COPPERAREA_COPPERAREA error: corner inside copper area
m_currentMarker = fillMarker( aEdge, wxPoint( x, y ),
m_currentMarker = fillMarker( aArea, wxPoint( x, y ),
COPPERAREA_INSIDE_COPPERAREA,
m_currentMarker );
return false;
......@@ -1036,10 +1057,10 @@ bool DRC::doEdgeZoneDrc( const EDGE_ZONE* aEdge )
// now test spacing between areas
int astyle = CPolyLine::STRAIGHT;
int ax1 = aEdge->m_Start.x;
int ay1 = aEdge->m_Start.y;
int ax2 = aEdge->m_End.x;
int ay2 = aEdge->m_End.y;
int ax1 = start.x;
int ay1 = start.y;
int ax2 = end.x;
int ay2 = end.y;
for( int icont2 = 0; icont2 < Area_To_Test->m_Poly->GetNumContours(); icont2++ )
{
int ic_start2 = Area_To_Test->m_Poly->GetContourStart( icont2 );
......@@ -1070,7 +1091,7 @@ bool DRC::doEdgeZoneDrc( const EDGE_ZONE* aEdge )
if( d < g_DesignSettings.m_ZoneClearence )
{
// COPPERAREA_COPPERAREA error : edge intersect or too close
m_currentMarker = fillMarker( aEdge, wxPoint( x, y ),
m_currentMarker = fillMarker( aArea, wxPoint( x, y ),
COPPERAREA_CLOSE_TO_COPPERAREA,
m_currentMarker );
return false;
......
......@@ -22,7 +22,7 @@ using namespace std;
CPolyLine::CPolyLine()
{
m_HatchStyle = 0;
m_sel_box = 0;
m_Width = 0;
utility = 0;
m_gpc_poly = new gpc_polygon;
m_gpc_poly->num_contours = 0;
......@@ -72,7 +72,7 @@ int CPolyLine::NormalizeWithGpc( std::vector<CPolyLine*> * pa, bool bRetainArcs
int x = to_int(((m_gpc_poly->contour)[ic].vertex)[i].x);
int y = to_int(((m_gpc_poly->contour)[ic].vertex)[i].y);
if( i==0 )
Start( m_layer, m_Width, m_sel_box, x, y, m_HatchStyle );
Start( m_layer, x, y, m_HatchStyle );
else
AppendCorner( x, y, STRAIGHT, FALSE );
}
......@@ -89,7 +89,7 @@ int CPolyLine::NormalizeWithGpc( std::vector<CPolyLine*> * pa, bool bRetainArcs
int x = to_int(((m_gpc_poly->contour)[ic].vertex)[i].x);
int y = to_int(((m_gpc_poly->contour)[ic].vertex)[i].y);
if( i==0 )
poly->Start( m_layer, m_Width, m_sel_box, x, y, m_HatchStyle );
poly->Start( m_layer, x, y, m_HatchStyle );
else
poly->AppendCorner( x, y, STRAIGHT, FALSE );
}
......@@ -199,10 +199,7 @@ void CPolyLine::ClipPhpPolygon( int php_op, CPolyLine * poly )
do
{
vertex * v = p->getFirst();
Start( m_layer, m_Width, m_sel_box,
to_int(v->X()*DENOM),
to_int(v->Y()*DENOM),
m_HatchStyle );
Start( m_layer, to_int(v->X()*DENOM), to_int(v->Y()*DENOM), m_HatchStyle );
do
{
vertex * n = v->Next();
......@@ -606,12 +603,9 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
// id.i = index to area
// ptr = pointer to net
//
void CPolyLine::Start( int layer, int w, int sel_box, int x, int y,
int hatch )
void CPolyLine::Start( int layer, int x, int y, int hatch )
{
m_layer = layer;
m_Width = w;
m_sel_box = sel_box;
m_HatchStyle = hatch;
CPolyPt poly_pt( x, y );
poly_pt.end_contour = FALSE;
......@@ -1002,7 +996,7 @@ void CPolyLine::Hatch()
int layer = m_layer;
// if( /*m_dlist && */GetClosed() )
if( GetClosed() ) // If not closed, the poly is beeing created and not finalised. Not not hatch
{
enum {
MAXPTS = 100,
......@@ -1082,7 +1076,7 @@ void CPolyLine::Hatch()
{
double x, y, x2, y2;
int ok;
if( corner[ic].end_contour )
if( corner[ic].end_contour || (ic == (int)(corner.size()-1)) )
{
ok = FindLineSegmentIntersection( a, slope,
corner[ic].x, corner[ic].y,
......@@ -1396,7 +1390,7 @@ CPolyLine * CPolyLine::MakePolylineForPad( int type, int x, int y, int w, int l,
}
if( type == PAD_ROUND )
{
poly->Start( 0, 0, 0, x-dx, y, 0 );
poly->Start( 0, x-dx, y, 0 );
poly->AppendCorner( x, y+dy, ARC_CW, 0 );
poly->AppendCorner( x+dx, y, ARC_CW, 0 );
poly->AppendCorner( x, y-dy, ARC_CW, 0 );
......
......@@ -69,8 +69,7 @@ public:
~CPolyLine();
// functions for modifying polyline
void Start( int layer, int w, int sel_box, int x, int y,
int hatch );
void Start( int layer, int x, int y, int hatch );
void AppendCorner( int x, int y, int style = STRAIGHT, bool bDraw=TRUE );
void InsertCorner( int ic, int x, int y );
void DeleteCorner( int ic, bool bDraw=TRUE );
......@@ -138,8 +137,7 @@ public:
private:
int m_layer; // layer to draw on
int m_Width; // line width
int m_sel_box; // corner selection box width/2
int m_Width; // lines width when drawing. Provided but not really used
int utility;
public:
std::vector <CPolyPt> corner; // array of points for corners
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment