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