beautification, hit test improvements

This commit is contained in:
dickelbeck 2007-08-10 19:14:51 +00:00
parent ea6aba8212
commit 8a8377ff6a
15 changed files with 5440 additions and 4897 deletions

View File

@ -22,10 +22,10 @@
#define PENALITE 500
/* Penalite pour orientation donnee par CntRot90 et CntRot180:
gradue de 0 ( rotation interdite ) a 10 ( rotation a cout null )
Le cout est ici donne en majoration
* gradue de 0 ( rotation interdite ) a 10 ( rotation a cout null )
* Le cout est ici donne en majoration
*/
static float OrientPenality[11] = {
static const float OrientPenality[11] = {
2.0, /* CntRot = 0 en fait rotation interdite */
1.9, /* CntRot = 1 */
1.8, /* CntRot = 2 */
@ -36,8 +36,8 @@ static float OrientPenality[11] = {
1.3, /* CntRot = 7 */
1.2, /* CntRot = 8 */
1.1, /* CntRot = 9 */
1.0}; /* CntRot = 10 rotation autorisee, penalite nulle */
1.0 /* CntRot = 10 rotation autorisee, penalite nulle */
};
/* Etat d'une cellule */
#define OUT_OF_BOARD -2
@ -68,8 +68,8 @@ void WinEDA_PcbFrame::AutoPlaceModule(MODULE * Module, int place_mode, wxDC * DC
/********************************************************************************/
/* Routine de Placement Automatique des composants dans le contour du PCB
Les composants ayant le status FIXE ne sont pas bouges
Si le menu appelant est le placement de 1 module, il sera replace
* Les composants ayant le status FIXE ne sont pas bouges
* Si le menu appelant est le placement de 1 module, il sera replace
*/
{
@ -84,7 +84,8 @@ int NbTotalModules = 0;
float Pas;
int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
if( m_Pcb->m_Modules == NULL ) return;
if( m_Pcb->m_Modules == NULL )
return;
DrawPanel->m_AbortRequest = FALSE;
DrawPanel->m_AbortEnable = TRUE;
@ -93,7 +94,8 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
{
case PLACE_1_MODULE:
ThisModule = Module;
if(ThisModule == NULL) return;
if( ThisModule == NULL )
return;
ThisModule->m_ModuleStatus &= ~(MODULE_is_PLACED | MODULE_to_PLACE);
break;
@ -117,8 +119,10 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
OldPasRoute = g_GridRoutingSize;
g_GridRoutingSize = m_CurrentScreen->GetGrid().x;
// Ensure g_GridRoutingSize has a reasonnable value:
if ( g_GridRoutingSize < 10 ) g_GridRoutingSize = 10; // Min value = 1/1000 inch
if( g_GridRoutingSize < 10 )
g_GridRoutingSize = 10; // Min value = 1/1000 inch
/* Compute module parmeters used in auto place */
Module = m_Pcb->m_Modules;
@ -129,7 +133,8 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
}
/* Generation du plan de placement */
if( GenPlaceBoard() == 0) return;
if( GenPlaceBoard() == 0 )
return;
/* Mise a jour des parametres modules utiles au placement */
BaseListeModules = GenListeModules( m_Pcb, &NbTotalModules );
@ -150,14 +155,16 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
case PLACE_OUT_OF_BOARD:
Module->m_ModuleStatus &= ~MODULE_is_PLACED;
if( Module->m_ModuleStatus & MODULE_is_LOCKED ) break;
if( Module->m_ModuleStatus & MODULE_is_LOCKED )
break;
if( !m_Pcb->m_BoundaryBox.Inside( Module->m_Pos ) )
Module->m_ModuleStatus |= MODULE_to_PLACE;
break;
case PLACE_ALL:
Module->m_ModuleStatus &= ~MODULE_is_PLACED;
if( Module->m_ModuleStatus & MODULE_is_LOCKED ) break;
if( Module->m_ModuleStatus & MODULE_is_LOCKED )
break;
Module->m_ModuleStatus |= MODULE_to_PLACE;
break;
@ -177,7 +184,6 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
NbModules++;
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
}
else
{
GenModuleOnBoard( Module );
@ -186,7 +192,8 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
/* Placement des modules */
activ = 0; Pas = 100.0;
if( NbModules ) Pas = 100.0 / (float)NbModules;
if( NbModules )
Pas = 100.0 / (float) NbModules;
while( ( Module = PickModule( this, DC ) ) != NULL )
{
float BestScore;
@ -199,7 +206,8 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
error = RecherchePlacementModule( Module, DC );
BestScore = MinCout;
PosOK = CurrPosition;
if ( error == ESC ) goto end_of_tst;
if( error == ESC )
goto end_of_tst;
/* Recherche du placement: orientation 180 */
ii = Module->m_CntRot180 & 0x0F;
@ -220,7 +228,8 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
Angle_Rot_Module = -1800;
Rotate_Module( DC, Module, Angle_Rot_Module, FALSE );
}
if ( error == ESC ) goto end_of_tst;
if( error == ESC )
goto end_of_tst;
}
/* Recherche du placement: orientation 90 */
@ -241,7 +250,8 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
Angle_Rot_Module = -900;
Rotate_Module( DC, Module, Angle_Rot_Module, FALSE );
}
if ( error == ESC ) goto end_of_tst;
if( error == ESC )
goto end_of_tst;
}
/* Recherche du placement: orientation -90 (ou 270 degres) */
@ -262,12 +272,14 @@ int lay_tmp_TOP, lay_tmp_BOTTOM, OldPasRoute;
Angle_Rot_Module = -2700;
Rotate_Module( DC, Module, Angle_Rot_Module, FALSE );
}
if ( error == ESC ) goto end_of_tst;
if( error == ESC )
goto end_of_tst;
}
end_of_tst:
if ( error == ESC ) break;
if( error == ESC )
break;
/* placement du module */
CurrPosition = m_CurrentScreen->m_Curseur;
@ -304,12 +316,13 @@ end_of_tst:
DrawPanel->ReDraw( DC, TRUE );
DrawPanel->m_AbortEnable = FALSE;
}
/**********************************************/
void WinEDA_PcbFrame::DrawInfoPlace( wxDC* DC )
/**********************************************/
/* Affiche a l'ecran les infos de placement
*/
{
@ -330,13 +343,17 @@ int ox, oy, top_state, bottom_state;
top_state = GetCell( ii, jj, TOP );
bottom_state = GetCell( ii, jj, BOTTOM );
if( (top_state & CELL_is_ZONE) ) color = BLUE;
if( (top_state & CELL_is_ZONE) )
color = BLUE;
/* obstacles */
if( (top_state & CELL_is_EDGE) || (bottom_state & CELL_is_EDGE)) color = WHITE;
if( (top_state & CELL_is_EDGE) || (bottom_state & CELL_is_EDGE) )
color = WHITE;
else if( top_state & (HOLE|CELL_is_MODULE) ) color = LIGHTRED;
else if( bottom_state & (HOLE|CELL_is_MODULE) ) color = LIGHTGREEN;
else if( top_state & (HOLE | CELL_is_MODULE) )
color = LIGHTRED;
else if( bottom_state & (HOLE | CELL_is_MODULE) )
color = LIGHTGREEN;
else /* Affichage du remplissage: Penalites */
{
@ -355,22 +372,22 @@ int WinEDA_PcbFrame::GenPlaceBoard(void)
/***************************************/
/* Routine de generation du board ( cote composant + cote cuivre ) :
Alloue la memoire necessaire pour representer en "bitmap" sur la grille
courante:
- la surface de placement des composant ( le board )
- le bitmap des penalites
et initialise les cellules du board a
- HOLE pour les cellules occupees par un segment EDGE
- CELL_is_ZONE pour les cellules internes au contour EDGE (s'il est ferme)
la surface de placement (board) donne les cellules internes au contour
du pcb, et parmi celle-ci les cellules libres et les cellules deja occupees
le bitmap des penalites donnent les cellules occupes par les modules,
augmentes d'une surface de penalite liee au nombre de pads du module
le bitmap des penalites est mis a 0
l'occupation des cellules est laisse a 0
* Alloue la memoire necessaire pour representer en "bitmap" sur la grille
* courante:
* - la surface de placement des composant ( le board )
* - le bitmap des penalites
* et initialise les cellules du board a
* - HOLE pour les cellules occupees par un segment EDGE
* - CELL_is_ZONE pour les cellules internes au contour EDGE (s'il est ferme)
*
* la surface de placement (board) donne les cellules internes au contour
* du pcb, et parmi celle-ci les cellules libres et les cellules deja occupees
*
* le bitmap des penalites donnent les cellules occupes par les modules,
* augmentes d'une surface de penalite liee au nombre de pads du module
*
* le bitmap des penalites est mis a 0
* l'occupation des cellules est laisse a 0
*/
{
int jj, ii;
@ -383,7 +400,7 @@ wxString msg;
if( !SetBoardBoundaryBoxFromEdgesOnly() )
{
DisplayError( this, _( "No edge PCB, Unknown board size!" ), 30 );
return(0);
return 0;
}
/* The boundary box must have its start point on placing grid: */
@ -412,7 +429,8 @@ wxString msg;
/* Choix du nombre de faces de placement */
Nb_Sides = TWO_SIDES;
Affiche_1_Parametre(this, 22, wxT("S"), ( Nb_Sides == TWO_SIDES ) ? wxT("2") : wxT("1"), WHITE);
Affiche_1_Parametre( this, 22, wxT( "S" ), ( Nb_Sides == TWO_SIDES ) ? wxT( "2" ) : wxT(
"1" ), WHITE );
/* Creation du mapping du board */
Board.InitBoard();
@ -422,23 +440,27 @@ wxString msg;
Affiche_1_Parametre( this, 24, wxT( "Mem(Ko)" ), msg, CYAN );
Route_Layer_BOTTOM = CMP_N;
if( Nb_Sides == TWO_SIDES ) Route_Layer_BOTTOM = CUIVRE_N;
if( Nb_Sides == TWO_SIDES )
Route_Layer_BOTTOM = CUIVRE_N;
Route_Layer_TOP = CMP_N;
/* Place the edge layer segments */
PtStruct = m_Pcb->m_Drawings;
TRACK TmpSegm( NULL );
TmpSegm.m_Layer = -1;
TmpSegm.m_NetCode = -1;
TmpSegm.m_Width = g_GridRoutingSize / 2;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
DRAWSEGMENT* DrawSegm;
switch( PtStruct->m_StructType )
{
case TYPEDRAWSEGMENT:
DrawSegm = (DRAWSEGMENT*) PtStruct;
if(DrawSegm->m_Layer != EDGE_N) break;
if( DrawSegm->m_Layer != EDGE_N )
break;
TmpSegm.m_Start = DrawSegm->m_Start;
TmpSegm.m_End = DrawSegm->m_End;
@ -449,11 +471,11 @@ wxString msg;
break;
case TYPETEXTE:
default: break;
default:
break;
}
}
/* Init du point d'accrochage de la zone */
OrCell( Nrows / 2, Ncols / 2, BOTTOM, CELL_is_ZONE );
@ -471,15 +493,16 @@ wxString msg;
if( Board.m_BoardSide[TOP] )
memcpy( Board.m_BoardSide[TOP], Board.m_BoardSide[BOTTOM], NbCells * sizeof(BoardCell) );
return(1);
return 1;
}
/******************************************************/
void WinEDA_PcbFrame::GenModuleOnBoard( MODULE* Module )
/******************************************************/
/* initialise sur le board de placement les cellules correspondantes au
module Module
* module Module
*/
{
int ox, oy, fx, fy, Penalite;
@ -497,21 +520,26 @@ D_PAD * Pad;
if( ox > m_Pcb->m_BoundaryBox.GetRight() )
ox = m_Pcb->m_BoundaryBox.GetRight();
if( fx < m_Pcb->m_BoundaryBox.m_Pos.x) fx = m_Pcb->m_BoundaryBox.m_Pos.x;
if( fx < m_Pcb->m_BoundaryBox.m_Pos.x )
fx = m_Pcb->m_BoundaryBox.m_Pos.x;
if( fx > m_Pcb->m_BoundaryBox.GetRight() )
fx = m_Pcb->m_BoundaryBox.GetRight();
if( oy < m_Pcb->m_BoundaryBox.m_Pos.y) oy = m_Pcb->m_BoundaryBox.m_Pos.y;
if( oy < m_Pcb->m_BoundaryBox.m_Pos.y )
oy = m_Pcb->m_BoundaryBox.m_Pos.y;
if( oy > m_Pcb->m_BoundaryBox.GetBottom() )
oy = m_Pcb->m_BoundaryBox.GetBottom();
if( fy < m_Pcb->m_BoundaryBox.m_Pos.y) fy = m_Pcb->m_BoundaryBox.m_Pos.y;
if( fy < m_Pcb->m_BoundaryBox.m_Pos.y )
fy = m_Pcb->m_BoundaryBox.m_Pos.y;
if( fy > m_Pcb->m_BoundaryBox.GetBottom() )
fy = m_Pcb->m_BoundaryBox.GetBottom();
masque_layer = 0;
if( Module->m_Layer == CMP_N ) masque_layer = CMP_LAYER;
if( Module->m_Layer == CUIVRE_N ) masque_layer = CUIVRE_LAYER;
if( Module->m_Layer == CMP_N )
masque_layer = CMP_LAYER;
if( Module->m_Layer == CUIVRE_N )
masque_layer = CUIVRE_LAYER;
TraceFilledRectangle( m_Pcb, ox, oy, fx, fy, masque_layer,
CELL_is_MODULE, WRITE_OR_CELL );
@ -535,13 +563,14 @@ D_PAD * Pad;
/************************************************************************/
int WinEDA_PcbFrame::RecherchePlacementModule( MODULE* Module, wxDC* DC )
/************************************************************************/
/*
Routine Principale de recherche de la position optimale du module
Entree:
Module pointe la struct MODULE du module a placer.
Retourne:
1 si placement impossible, 0 si OK
et MinCout = variable externe = cout du meilleur placement
* Routine Principale de recherche de la position optimale du module
* Entree:
* Module pointe la struct MODULE du module a placer.
* Retourne:
* 1 si placement impossible, 0 si OK
* et MinCout = variable externe = cout du meilleur placement
*/
{
int cx, cy;
@ -577,20 +606,22 @@ bool TstOtherSide;
m_Pcb->m_Status_Pcb &= ~CHEVELU_LOCAL_OK;
/* tst des pastilles traversantes, qui pour un circuit imprime ayant des
composants des 2 cotes, peuvent tomber sur un composant de cote oppose:
s'il y a au moins 1 pastille apparaissant sur l'autre cote, ce cote
est teste */
* composants des 2 cotes, peuvent tomber sur un composant de cote oppose:
* s'il y a au moins 1 pastille apparaissant sur l'autre cote, ce cote
* est teste */
TstOtherSide = FALSE;
if( Nb_Sides == TWO_SIDES )
{
D_PAD* Pad; int masque_otherlayer;
masque_otherlayer = CUIVRE_LAYER;
if ( Module->m_Layer == CUIVRE_N ) masque_otherlayer = CMP_LAYER;
if( Module->m_Layer == CUIVRE_N )
masque_otherlayer = CMP_LAYER;
for( Pad = Module->m_Pads; Pad != NULL; Pad = (D_PAD*) Pad->Pnext )
{
if( (Pad->m_Masque_Layer & masque_otherlayer) == 0 ) continue;
if( (Pad->m_Masque_Layer & masque_otherlayer) == 0 )
continue;
TstOtherSide = TRUE;
break;
}
@ -608,8 +639,10 @@ bool TstOtherSide;
wxYield();
if( DrawPanel->m_AbortRequest )
{
if ( IsOK(this, _("Ok to abort ?")) ) return ESC;
else DrawPanel->m_AbortRequest = FALSE;
if( IsOK( this, _( "Ok to abort ?" ) ) )
return ESC;
else
DrawPanel->m_AbortRequest = FALSE;
}
cx = Module->m_Pos.x; cy = Module->m_Pos.y;
@ -630,7 +663,8 @@ bool TstOtherSide;
{
/* effacement des traces */
DrawModuleOutlines( DrawPanel, DC, Module );
if (DisplayChevelu) Compute_Ratsnest_PlaceModule(DC);
if( DisplayChevelu )
Compute_Ratsnest_PlaceModule( DC );
DisplayChevelu = 0;
Module->m_RealBoundaryBox.m_Pos.x = ox + CurrPosition.x;
Module->m_RealBoundaryBox.m_Pos.y = oy + CurrPosition.y;
@ -657,13 +691,15 @@ bool TstOtherSide;
Affiche_Message( msg );
}
}
if( DisplayChevelu ) Compute_Ratsnest_PlaceModule(DC);
if( DisplayChevelu )
Compute_Ratsnest_PlaceModule( DC );
DisplayChevelu = 0;
}
}
DrawModuleOutlines( DrawPanel, DC, Module ); /* effacement du dernier trace */
if (DisplayChevelu) Compute_Ratsnest_PlaceModule(DC);
if( DisplayChevelu )
Compute_Ratsnest_PlaceModule( DC );
/* Regeneration des variables modifiees */
Module->m_RealBoundaryBox.m_Pos.x = ox + cx;
@ -673,19 +709,19 @@ bool TstOtherSide;
m_Pcb->m_Status_Pcb &= ~(CHEVELU_LOCAL_OK | LISTE_PAD_OK );
MinCout = mincout;
return(error);
return error;
}
/**************************************************************************/
int TstRectangle( BOARD* Pcb, int ux0, int uy0, int ux1, int uy1, int side )
/**************************************************************************/
/* tst si la surface rectangulaire (ux,y0 .. ux,y1):
- est sur une zone libre ( retourne OCCUPED_By_MODULE sinon)
- est sur la surface utile du board ( retourne OUT_OF_BOARD sinon)
retourne 0 si OK
/* tst si la surface rectangulaire (ux,y0 .. ux,y1):
* - est sur une zone libre ( retourne OCCUPED_By_MODULE sinon)
* - est sur la surface utile du board ( retourne OUT_OF_BOARD sinon)
*
* retourne 0 si OK
*/
{
int row, col;
@ -698,13 +734,19 @@ unsigned int data;
/* Calcul des coord limites des cellules appartenant au rectangle */
row_max = uy1 / g_GridRoutingSize;
col_max = ux1 / g_GridRoutingSize;
row_min = uy0 / g_GridRoutingSize; if (uy0 > row_min*g_GridRoutingSize ) row_min++;
col_min = ux0 / g_GridRoutingSize; if (ux0 > col_min*g_GridRoutingSize ) col_min++;
row_min = uy0 / g_GridRoutingSize; if( uy0 > row_min * g_GridRoutingSize )
row_min++;
col_min = ux0 / g_GridRoutingSize; if( ux0 > col_min * g_GridRoutingSize )
col_min++;
if( row_min < 0 ) row_min = 0;
if( row_max >= (Nrows-1)) row_max = Nrows-1;
if( col_min < 0 ) col_min = 0;
if( col_max >= (Ncols-1)) col_max = Ncols-1;
if( row_min < 0 )
row_min = 0;
if( row_max >= (Nrows - 1) )
row_max = Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= (Ncols - 1) )
col_max = Ncols - 1;
for( row = row_min; row <= row_max; row++ )
{
@ -712,12 +754,13 @@ unsigned int data;
{
data = GetCell( row, col, side );
if( (data & CELL_is_ZONE) == 0 ) /* Cellule non autorisee */
return(OUT_OF_BOARD);
return OUT_OF_BOARD;
if( data & CELL_is_MODULE ) /* Deja utilisee */
return(OCCUPED_By_MODULE);
return OCCUPED_By_MODULE;
}
}
return( 0 );
return 0;
}
@ -725,8 +768,9 @@ unsigned int data;
unsigned int CalculePenaliteRectangle( BOARD* Pcb, int ux0, int uy0,
int ux1, int uy1, int side )
/******************************************************************************/
/* calcule et retourne la penalite de la surface rectangulaire (ux,y0 .. ux,y1):
( somme des valeurs des cellules du plan des Distances )
* ( somme des valeurs des cellules du plan des Distances )
*/
{
int row, col;
@ -739,13 +783,19 @@ unsigned int Penalite;
/* Calcul des coord limites des cellules appartenant au rectangle */
row_max = uy1 / g_GridRoutingSize;
col_max = ux1 / g_GridRoutingSize;
row_min = uy0 / g_GridRoutingSize; if (uy0 > row_min*g_GridRoutingSize ) row_min++;
col_min = ux0 / g_GridRoutingSize; if (ux0 > col_min*g_GridRoutingSize ) col_min++;
row_min = uy0 / g_GridRoutingSize; if( uy0 > row_min * g_GridRoutingSize )
row_min++;
col_min = ux0 / g_GridRoutingSize; if( ux0 > col_min * g_GridRoutingSize )
col_min++;
if( row_min < 0 ) row_min = 0;
if( row_max >= (Nrows-1)) row_max = Nrows-1;
if( col_min < 0 ) col_min = 0;
if( col_max >= (Ncols-1)) col_max = Ncols-1;
if( row_min < 0 )
row_min = 0;
if( row_max >= (Nrows - 1) )
row_max = Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= (Ncols - 1) )
col_max = Ncols - 1;
Penalite = 0;
for( row = row_min; row <= row_max; row++ )
@ -755,15 +805,18 @@ unsigned int Penalite;
Penalite += (int) GetDist( row, col, side );
}
}
return( Penalite );
return Penalite;
}
/**********************************************************************/
int TstModuleOnBoard( BOARD* Pcb, MODULE* Module, bool TstOtherSide )
/**********************************************************************/
/* Teste si le module peut etre place sur le board.
retourne de diagnostic de TstRectangle().
le module est connu par son rectangle d'encadrement
* retourne de diagnostic de TstRectangle().
* le module est connu par son rectangle d'encadrement
*/
{
int ox, oy, fx, fy;
@ -781,19 +834,21 @@ int error, Penalite, marge, side, otherside;
fy = Module->m_RealBoundaryBox.GetBottom();
error = TstRectangle( Pcb, ox, oy, fx, fy, side );
if( error < 0 ) return (error);
if( error < 0 )
return error;
if( TstOtherSide )
{
error = TstRectangle( Pcb, ox, oy, fx, fy, otherside );
if( error < 0 ) return (error);
if( error < 0 )
return error;
}
marge = (g_GridRoutingSize * Module->m_PadNum ) / GAIN;
Penalite = CalculePenaliteRectangle( Pcb, ox - marge, oy - marge,
fx + marge, fy + marge, side );
return( Penalite );
return Penalite;
}
@ -802,9 +857,9 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule(wxDC * DC)
/************************************************************/
/* Routine affichant le chevelu du module en cours de deplacement, et
evaluant le "cout" de la position.
Le cout est la longueur des chevelus en distance de manhattan, avec
penalite pour les inclinaisons se rapprochant de 45 degre
* evaluant le "cout" de la position.
* Le cout est la longueur des chevelus en distance de manhattan, avec
* penalite pour les inclinaisons se rapprochant de 45 degre
*/
{
CHEVELU* pt_local_chevelu;
@ -813,17 +868,14 @@ float cout, icout;
int ox, oy, fx, fy, dx, dy;
if( (m_Pcb->m_Status_Pcb & CHEVELU_LOCAL_OK) == 0 )
return(-1);
return -1;
pt_local_chevelu = local_liste_chevelu;
ii = nb_local_chevelu; cout = 0;
while( ii-- > 0 )
{
if(pt_local_chevelu->status & LOCAL_CHEVELU)
{ // Non Affiché
}
else
if( !(pt_local_chevelu->status & LOCAL_CHEVELU) )
{
ox = pt_local_chevelu->pad_start->m_Pos.x - g_Offset_Module.x;
oy = pt_local_chevelu->pad_start->m_Pos.y - g_Offset_Module.y;
@ -839,7 +891,8 @@ int ox, oy, fx, fy, dx , dy;
/* Evaluation du cout du chevelu: */
dx = fx - ox; dy = fy - oy;
dx = abs( dx ); dy = abs( dy );
if( dx < dy ) EXCHG(dx,dy); /* dx >= dy */
if( dx < dy )
EXCHG( dx, dy );/* dx >= dy */
/* cout de la distance: */
icout = (float) dx * dx;
/* cout de l'inclinaison */
@ -847,34 +900,39 @@ int ox, oy, fx, fy, dx , dy;
icout = sqrt( icout );
cout += icout; /* cout total = somme des couts de chaque chevelu */
}
pt_local_chevelu++;
}
return (cout);
return cout;
}
/********************************************/
void Build_PlacedPads_List( BOARD* Pcb )
/********************************************/
/*
construction de la liste ( sous forme d'une liste de stucture )
des caract utiles des pads du PCB pour Placement Automatique )
Cette liste est restreinte a la liste des pads des modules deja places sur
la carte.
parametres:
adresse du buffer de classement = Pcb->ptr_pads;
Variables globales mise a jour:
pointeur ptr_pads (adr de classement de la liste des pads)
nb_pads = nombre utile de pastilles classes
m_Status_Pcb |= LISTE_PAD_OK
* construction de la liste ( sous forme d'une liste de stucture )
* des caract utiles des pads du PCB pour Placement Automatique )
* Cette liste est restreinte a la liste des pads des modules deja places sur
* la carte.
*
* parametres:
* adresse du buffer de classement = Pcb->ptr_pads;
*
* Variables globales mise a jour:
* pointeur ptr_pads (adr de classement de la liste des pads)
* nb_pads = nombre utile de pastilles classes
* m_Status_Pcb |= LISTE_PAD_OK
*/
{
LISTE_PAD* pt_liste_pad;
MODULE* Module;
D_PAD* PtPad;
if( Pcb->m_Pads ) MyFree( Pcb->m_Pads );
if( Pcb->m_Pads )
MyFree( Pcb->m_Pads );
pt_liste_pad = Pcb->m_Pads = NULL;
Pcb->m_NbPads = Pcb->m_NbNodes = 0;
@ -883,7 +941,8 @@ D_PAD * PtPad;
Module = Pcb->m_Modules;
for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
{
if( Module->m_ModuleStatus & MODULE_to_PLACE ) continue;
if( Module->m_ModuleStatus & MODULE_to_PLACE )
continue;
PtPad = (D_PAD*) Module->m_Pads;
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext )
{
@ -902,7 +961,8 @@ D_PAD * PtPad;
Module = Pcb->m_Modules;
for( ; (Module != NULL) && (pt_liste_pad != NULL); Module = (MODULE*) Module->Pnext )
{
if( Module->m_ModuleStatus & MODULE_to_PLACE ) continue;
if( Module->m_ModuleStatus & MODULE_to_PLACE )
continue;
PtPad = (D_PAD*) Module->m_Pads;
for( ; PtPad != NULL; PtPad = (D_PAD*) PtPad->Pnext )
{
@ -910,7 +970,8 @@ D_PAD * PtPad;
PtPad->m_physical_connexion = 0;
PtPad->m_logical_connexion = 0;
PtPad->m_Parent = Module;
if(PtPad->m_NetCode) Pcb->m_NbNodes++;
if( PtPad->m_NetCode )
Pcb->m_NbNodes++;
pt_liste_pad++;
}
}
@ -926,10 +987,10 @@ D_PAD * PtPad;
/*****************************************************************/
/* les cellules ( du plan des Distances ) du rectangle x0,y0 a x1,y1 sont
incrementees de la valeur Penalite
celles qui sont externes au rectangle, mais internes au rectangle
x0,y0 -marge a x1,y1 + marge sont incrementees d'une valeur
(Penalite ... 0) decroissante en fonction de leur eloignement
* incrementees de la valeur Penalite
* celles qui sont externes au rectangle, mais internes au rectangle
* x0,y0 -marge a x1,y1 + marge sont incrementees d'une valeur
* (Penalite ... 0) decroissante en fonction de leur eloignement
*/
static void TracePenaliteRectangle( BOARD* Pcb, int ux0, int uy0, int ux1, int uy1,
int marge, int Penalite, int masque_layer )
@ -946,7 +1007,8 @@ int lgain, cgain;
if( (masque_layer & g_TabOneLayerMask[Route_Layer_TOP] ) && Nb_Sides )
trace |= 2; /* Trace sur TOP */
if(trace == 0) return;
if( trace == 0 )
return;
ux0 -= Pcb->m_BoundaryBox.m_Pos.x; uy0 -= Pcb->m_BoundaryBox.m_Pos.y;
ux1 -= Pcb->m_BoundaryBox.m_Pos.x; uy1 -= Pcb->m_BoundaryBox.m_Pos.y;
@ -954,18 +1016,25 @@ int lgain, cgain;
ux0 -= marge; ux1 += marge;
uy0 -= marge; uy1 += marge;
pmarge = marge / g_GridRoutingSize; if (pmarge < 1 ) pmarge = 1;
pmarge = marge / g_GridRoutingSize; if( pmarge < 1 )
pmarge = 1;
/* Calcul des coord limites des cellules appartenant au rectangle */
row_max = uy1 / g_GridRoutingSize;
col_max = ux1 / g_GridRoutingSize;
row_min = uy0 / g_GridRoutingSize; if (uy0 > row_min*g_GridRoutingSize ) row_min++;
col_min = ux0 / g_GridRoutingSize; if (ux0 > col_min*g_GridRoutingSize ) col_min++;
row_min = uy0 / g_GridRoutingSize; if( uy0 > row_min * g_GridRoutingSize )
row_min++;
col_min = ux0 / g_GridRoutingSize; if( ux0 > col_min * g_GridRoutingSize )
col_min++;
if( row_min < 0 ) row_min = 0;
if( row_max >= (Nrows-1)) row_max = Nrows-1;
if( col_min < 0 ) col_min = 0;
if( col_max >= (Ncols-1)) col_max = Ncols-1;
if( row_min < 0 )
row_min = 0;
if( row_max >= (Nrows - 1) )
row_max = Nrows - 1;
if( col_min < 0 )
col_min = 0;
if( col_max >= (Ncols - 1) )
col_max = Ncols - 1;
for( row = row_min; row <= row_max; row++ )
{
@ -985,7 +1054,8 @@ int lgain, cgain;
cgain = ( 256 * (col_max - col) ) / pmarge;
cgain = (cgain * lgain) / 256;
if( cgain != 256 ) LocalPenalite = (LocalPenalite * cgain) / 256;
if( cgain != 256 )
LocalPenalite = (LocalPenalite * cgain) / 256;
if( trace & 1 )
{
data = GetDist( row, col, BOTTOM ) + LocalPenalite;
@ -1001,6 +1071,7 @@ int lgain, cgain;
}
}
/***************************************************/
/* Routines de tri de modules, utilisee par qsort: */
/***************************************************/
@ -1012,11 +1083,14 @@ float ff, ff1, ff2 ;
ff1 = (*pt_ref)->m_Surface * (*pt_ref)->m_PadNum;
ff2 = (*pt_compare)->m_Surface * (*pt_compare)->m_PadNum;
ff = ff1 - ff2;
if( ff < 0 ) return(1) ;
if( ff > 0 ) return(-1) ;
return( 0 );
if( ff < 0 )
return 1;
if( ff > 0 )
return -1;
return 0;
}
static int Tri_RatsModules( MODULE** pt_ref, MODULE** pt_compare )
{
float ff, ff1, ff2;
@ -1024,9 +1098,11 @@ float ff, ff1, ff2 ;
ff1 = (*pt_ref)->m_Surface * (*pt_ref)->flag;
ff2 = (*pt_compare)->m_Surface * (*pt_compare)->flag;
ff = ff1 - ff2;
if( ff < 0 ) return(1) ;
if( ff > 0 ) return(-1) ;
return( 0 );
if( ff < 0 )
return 1;
if( ff > 0 )
return -1;
return 0;
}
@ -1035,9 +1111,9 @@ static MODULE * PickModule(WinEDA_PcbFrame * pcbframe, wxDC * DC)
/***************************************************************/
/* Recherche le "meilleur" module a placer
les criteres de choix sont:
- maximum de chevelus avec les modules deja places
- taille max, et nombre de pads max
* les criteres de choix sont:
* - maximum de chevelus avec les modules deja places
* - taille max, et nombre de pads max
*/
{
MODULE** BaseListeModules, ** pt_Dmod;
@ -1046,12 +1122,13 @@ CHEVELU* pt_local_chevelu;
int NbModules, ii;
BaseListeModules = GenListeModules( pcbframe->m_Pcb, &NbModules );
if( BaseListeModules == NULL ) return(NULL);
if( BaseListeModules == NULL )
return NULL;
Build_PlacedPads_List( pcbframe->m_Pcb );
/* Tri par surface decroissante des modules
(on place les plus gros en 1er), surface ponderee par le nombre de pads */
* (on place les plus gros en 1er), surface ponderee par le nombre de pads */
qsort( BaseListeModules, NbModules, sizeof(MODULE * *),
( int (*)( const void*, const void* ) )Tri_PlaceModules );
@ -1059,7 +1136,8 @@ int NbModules, ii;
for( pt_Dmod = BaseListeModules; *pt_Dmod != NULL; pt_Dmod++ )
{
(*pt_Dmod)->flag = 0;
if( ! ((*pt_Dmod)->m_ModuleStatus & MODULE_to_PLACE) ) continue;
if( !( (*pt_Dmod)->m_ModuleStatus & MODULE_to_PLACE ) )
continue;
pcbframe->m_Pcb->m_Status_Pcb &= ~CHEVELU_LOCAL_OK;
adr_lowmem = buf_work;
(*pt_Dmod)->Display_Infos( pcbframe );
@ -1075,6 +1153,7 @@ int NbModules, ii;
pt_local_chevelu++;
}
}
pcbframe->m_Pcb->m_Status_Pcb &= ~CHEVELU_LOCAL_OK;
qsort( BaseListeModules, NbModules, sizeof(MODULE * *),
@ -1085,15 +1164,19 @@ int NbModules, ii;
Module = NULL;
for( pt_Dmod = BaseListeModules; *pt_Dmod != NULL; pt_Dmod++ )
{
if( ! ((*pt_Dmod)->m_ModuleStatus & MODULE_to_PLACE) ) continue;
if( !( (*pt_Dmod)->m_ModuleStatus & MODULE_to_PLACE ) )
continue;
AltModule = *pt_Dmod;
if( (*pt_Dmod)->flag == 0 ) continue;
if( (*pt_Dmod)->flag == 0 )
continue;
Module = *pt_Dmod; break;
}
MyFree( BaseListeModules );
if ( Module ) return(Module);
else return(AltModule);
if( Module )
return Module;
else
return AltModule;
}
@ -1102,10 +1185,10 @@ bool WinEDA_PcbFrame::SetBoardBoundaryBoxFromEdgesOnly(void)
/*******************************************************/
/* Determine le rectangle d'encadrement du pcb, selon les contours
(couche EDGE) uniquement
Sortie:
m_Pcb->m_BoundaryBox mis a jour
Retourne FALSE si pas de contour
* (couche EDGE) uniquement
* Sortie:
* m_Pcb->m_BoundaryBox mis a jour
* Retourne FALSE si pas de contour
*/
{
int rayon, cx, cy, d;
@ -1114,7 +1197,8 @@ EDA_BaseStruct * PtStruct;
DRAWSEGMENT* ptr;
bool succes = FALSE;
if (m_Pcb == NULL) return FALSE;
if( m_Pcb == NULL )
return FALSE;
m_Pcb->m_BoundaryBox.m_Pos.x = m_Pcb->m_BoundaryBox.m_Pos.y = 0x7FFFFFFFl;
xmax = ymax = -0x7FFFFFFFl;
@ -1123,7 +1207,8 @@ bool succes = FALSE;
PtStruct = m_Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue;
if( PtStruct->m_StructType != TYPEDRAWSEGMENT )
continue;
succes = TRUE;
ptr = (DRAWSEGMENT*) PtStruct;
d = (ptr->m_Width / 2) + 1;
@ -1152,7 +1237,5 @@ bool succes = FALSE;
m_Pcb->m_BoundaryBox.SetWidth( xmax - m_Pcb->m_BoundaryBox.m_Pos.x );
m_Pcb->m_BoundaryBox.SetHeight( ymax - m_Pcb->m_BoundaryBox.m_Pos.y );
return(succes);
return succes;
}

View File

@ -332,9 +332,10 @@ EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer )
public:
EDA_BaseStruct* found;
int layer;
int layer_mask;
PadOrModule( int alayer ) :
found(0), layer(alayer)
found(0), layer(alayer), layer_mask( g_TabOneLayerMask[alayer] )
{}
SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData )
@ -343,23 +344,33 @@ EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer )
if( testItem->m_StructType == TYPEPAD )
{
if( testItem->HitTest( refPos ) )
D_PAD* pad = (D_PAD*) testItem;
if( pad->HitTest( refPos ) )
{
if( layer_mask & pad->m_Masque_Layer )
{
found = testItem;
return SEARCH_QUIT;
}
else if( !found )
{
MODULE* parent = (MODULE*) pad->m_Parent;
if( IsModuleLayerVisible( parent->m_Layer ) )
found = testItem;
}
}
}
else if( testItem->m_StructType == TYPEMODULE )
{
int mlayer = ((MODULE*)testItem)->m_Layer;
MODULE* module = (MODULE*) testItem;
// consider only visible modules
if( IsModuleLayerVisible( mlayer ) )
if( IsModuleLayerVisible( module->m_Layer ) )
{
if( testItem->HitTest( refPos ) )
if( module->HitTest( refPos ) )
{
if( layer == mlayer )
if( layer == module->m_Layer )
{
found = testItem;
return SEARCH_QUIT;

View File

@ -31,7 +31,9 @@ D_PAD::D_PAD( MODULE* parent ) : EDA_BaseStruct( parent, TYPEPAD )
m_Masque_Layer = CUIVRE_LAYER;
m_NetCode = 0; /* Numero de net pour comparaisons rapides */
m_DrillShape = CIRCLE; // Drill shape = circle
m_Size.x = m_Size.y = 500;
if( m_Parent && (m_Parent->m_StructType == TYPEMODULE) )
{
m_Pos = ( (MODULE*) m_Parent )->m_Pos;
@ -91,7 +93,8 @@ const wxPoint D_PAD::ReturnShapePos( void )
wxPoint shape_pos;
int dX, dY;
dX = m_Offset.x; dY = m_Offset.y;
dX = m_Offset.x;
dY = m_Offset.y;
RotatePoint( &dX, &dY, m_Orient );
@ -458,12 +461,13 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int
GRClosedPoly( &panel->m_ClipBox, DC, 4, (int*) coord, 0, color, color );
}
}
break;
default:
break;
}
}
/* Draw the pad hole */
int cx0 = m_Pos.x - offset.x;

View File

@ -41,32 +41,34 @@ static bool s_ConnectToPads = false;
#ifdef CONN2PAD_ENBL
static void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC );
static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC );
#endif
/*****************************************/
void WinEDA_PcbFrame::Clean_Pcb( wxDC* DC )
/*****************************************/
/* Regroupement des segments de meme piste.
Suppression des points inutiles
- via sur pad
- points de couche et coord identiques
- points alignes (supp du pt milieu)
* Suppression des points inutiles
* - via sur pad
* - points de couche et coord identiques
* - points alignes (supp du pt milieu)
*/
{
s_ConnectToPads = false;
WinEDA_CleaningOptionsFrame* frame = new WinEDA_CleaningOptionsFrame( this, DC );
frame->ShowModal(); frame->Destroy();
DrawPanel->Refresh( true );
}
/************************************************************/
void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC )
/************************************************************/
{
frame->MsgPanel->EraseMsgBox();
frame->m_Pcb->GetNumSegmTrack(); /* Met a jour le compte */
/* construction de la liste des coordonnées des pastilles */
/* construction de la liste des coordonn<6E>s des pastilles */
frame->m_Pcb->m_Status_Pcb = 0;
frame->build_liste_pads();
frame->recalcule_pad_net_code();
@ -76,24 +78,30 @@ void Clean_Pcb_Items(WinEDA_PcbFrame * frame, wxDC * DC )
TRACK* track, * next_track;
for( track = frame->m_Pcb->m_Track; track != NULL; track = track->Next() )
{
if( track->m_Shape != VIA_NORMALE ) continue;
if( track->m_Shape != VIA_NORMALE )
continue;
/* Search and delete others vias at same location */
TRACK* alt_track = track->Next();
for( ; alt_track != NULL; alt_track = next_track )
{
next_track = alt_track->Next();
if( alt_track->m_Shape != VIA_NORMALE ) continue;
if ( alt_track->m_Start != track->m_Start ) continue;
if( alt_track->m_Shape != VIA_NORMALE )
continue;
if( alt_track->m_Start != track->m_Start )
continue;
/* delete via */
alt_track->UnLink();
delete alt_track;
}
}
/* Delete Via on pads at same location */
for( track = frame->m_Pcb->m_Track; track != NULL; track = next_track )
{
next_track = track->Next();
if( track->m_Shape != VIA_NORMALE ) continue;
if( track->m_Shape != VIA_NORMALE )
continue;
D_PAD* pad = Fast_Locate_Pad_Connecte( frame->m_Pcb, track->m_Start, ALL_CU_LAYERS );
if( pad && (pad->m_Masque_Layer & EXTERNAL_LAYERS) == EXTERNAL_LAYERS ) // redundant Via
{
@ -111,16 +119,19 @@ void Clean_Pcb_Items(WinEDA_PcbFrame * frame, wxDC * DC )
ConnectDanglingEndToPad( frame, DC );
/* Creation de points de raccordements aux intersections de pistes */
// Gen_Raccord_Track(frame, DC);
}
#endif
/* suppression des segments de longueur nulle et des points intermediaires
alignes */
if ( s_MergeSegments ) clean_segments(frame, DC);
* alignes */
if( s_MergeSegments )
clean_segments( frame, DC );
/* suppression des pistes non connectees ( c.a.d dont 1 extremite est en l'air) */
if ( s_DeleteUnconnectedSegm ) suppression_piste_non_connectee(frame, DC);
if( s_DeleteUnconnectedSegm )
suppression_piste_non_connectee( frame, DC );
frame->Compile_Ratsnest( DC, AFFICHE );
@ -128,15 +139,15 @@ void Clean_Pcb_Items(WinEDA_PcbFrame * frame, wxDC * DC )
}
/*****************************************************************************/
static void suppression_piste_non_connectee( WinEDA_PcbFrame* frame, wxDC* DC )
/*****************************************************************************/
/*
Supprime les segments de piste ayant 1 ou 2 extremites non connectees
Cas des vias:
si une extremite de segment est connectee uniquement a une via, la via
et le segment seront supprimes
* Supprime les segments de piste ayant 1 ou 2 extremites non connectees
* Cas des vias:
* si une extremite de segment est connectee uniquement a une via, la via
* et le segment seront supprimes
*/
{
TRACK* PtSegm, * pt_other, * pt_via;
@ -160,7 +171,8 @@ wxString msg;
NextS = PtSegm->Pnext;
if( PtSegm->m_StructType == TYPEVIA )
{
if( (PtSegm->m_Start.x != PtSegm->m_End.x ) || (PtSegm->m_Start.y != PtSegm->m_End.y ) )
if( (PtSegm->m_Start.x != PtSegm->m_End.x )
|| (PtSegm->m_Start.y != PtSegm->m_End.y ) )
{
PtSegm->m_End.x = PtSegm->m_Start.x;
PtSegm->m_End.y = PtSegm->m_Start.y;
@ -192,7 +204,8 @@ wxString msg;
Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN );
}
if( frame->DrawPanel->m_AbortRequest ) break;
if( frame->DrawPanel->m_AbortRequest )
break;
if( PtSegm->m_NetCode != oldnetcode )
{
@ -226,7 +239,8 @@ wxString msg;
pt_other = Locate_Piste_Connectee( PtSegm, frame->m_Pcb->m_Track,
NULL, START );
if(pt_other == NULL) flag_erase |= 1;
if( pt_other == NULL )
flag_erase |= 1;
else /* Segment ou via connectee a cette extremite */
{
@ -237,7 +251,8 @@ wxString msg;
pt_via = pt_other;
pt_other = Locate_Piste_Connectee( pt_via, frame->m_Pcb->m_Track,
NULL, START );
if(pt_other == NULL) flag_erase |= 2;
if( pt_other == NULL )
flag_erase |= 2;
PtSegm->SetState( BUSY, OFF );
}
}
@ -247,7 +262,8 @@ wxString msg;
{
pt_other = Locate_Piste_Connectee( PtSegm, frame->m_Pcb->m_Track,
NULL, END );
if(pt_other == NULL) flag_erase |= 0x10;
if( pt_other == NULL )
flag_erase |= 0x10;
else /* Segment ou via connectee a cette extremite */
{
PtSegm->end = pt_other;
@ -258,7 +274,8 @@ wxString msg;
pt_other = Locate_Piste_Connectee( pt_via, frame->m_Pcb->m_Track,
NULL, END );
if(pt_other == NULL) flag_erase |= 0x20;
if( pt_other == NULL )
flag_erase |= 0x20;
PtSegm->SetState( BUSY, OFF );
}
}
@ -272,24 +289,25 @@ wxString msg;
Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "NoConn." ), msg, LIGHTRED );
/* rectification du pointeur PtSegm pour repartir en debut
du block des segments de meme net_code */
* du block des segments de meme net_code */
if( PtSegm == PtStartNetCode )
{
NextS = PtSegm->Pnext;
PtStartNetCode = (TRACK*) NextS;
}
else NextS = PtStartNetCode;
else
NextS = PtStartNetCode;
/* Suppression du segment */
PtSegm->Draw( frame->DrawPanel, DC, GR_XOR );
DeleteStructure( PtSegm );
if ( NextS == NULL ) break;
if( NextS == NULL )
break;
}
}
}
/************************************************************/
static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC )
/************************************************************/
@ -317,7 +335,8 @@ wxString msg;
for( PtSegm = frame->m_Pcb->m_Track; PtSegm != NULL; PtSegm = (TRACK*) NextS )
{
NextS = PtSegm->Pnext;
if( ! PtSegm->IsNull() ) continue;
if( !PtSegm->IsNull() )
continue;
/* Lenght segment = 0; delete it */
PtSegm->Draw( frame->DrawPanel, DC, GR_XOR );
@ -349,7 +368,8 @@ wxString msg;
msg.Printf( wxT( "%d" ), ii );
Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN );
if( frame->DrawPanel->m_AbortRequest ) return(-1);
if( frame->DrawPanel->m_AbortRequest )
return -1;
}
for( pt_aux = (TRACK*) PtSegm->Pnext; pt_aux != NULL; pt_aux = (TRACK*) NextS )
@ -357,11 +377,15 @@ wxString msg;
int erase = 0;
NextS = pt_aux->Pnext;
if( PtSegm->m_StructType != pt_aux->m_StructType ) continue;
if( PtSegm->m_Layer != pt_aux->m_Layer ) continue;
if( PtSegm->m_NetCode != pt_aux->m_NetCode ) break;
if( PtSegm->m_StructType != pt_aux->m_StructType )
continue;
if( PtSegm->m_Layer != pt_aux->m_Layer )
continue;
if( PtSegm->m_NetCode != pt_aux->m_NetCode )
break;
if( (PtSegm->m_Start.x == pt_aux->m_Start.x ) && (PtSegm->m_Start.y == pt_aux->m_Start.y) )
if( (PtSegm->m_Start.x == pt_aux->m_Start.x )
&& (PtSegm->m_Start.y == pt_aux->m_Start.y) )
{
if( (PtSegm->m_End.x == pt_aux->m_End.x ) && (PtSegm->m_End.y==pt_aux->m_End.y) )
erase = 1;
@ -415,10 +439,12 @@ wxString msg;
msg.Printf( wxT( "%d" ), ii );
Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN );
if( frame->DrawPanel->m_AbortRequest ) return(-1);
if( frame->DrawPanel->m_AbortRequest )
return -1;
}
if(PtSegm->m_StructType != TYPETRACK) continue;
if( PtSegm->m_StructType != TYPETRACK )
continue;
flag = no_inc = 0;
@ -430,9 +456,12 @@ wxString msg;
if( pt_segm_s )
{
/* les 2 segments doivent avoir meme largeur */
if(PtSegm->m_Width != pt_segm_s->m_Width ) break;
if( PtSegm->m_Width != pt_segm_s->m_Width )
break;
/* Ce ne peut etre une via */
if(pt_segm_s->m_StructType != TYPETRACK) break;
if( pt_segm_s->m_StructType != TYPETRACK )
break;
/* On ne peut avoir que 1 seul segment connecte */
pt_segm_s->SetState( BUSY, ON );
@ -440,7 +469,8 @@ wxString msg;
NULL, START );
pt_segm_s->SetState( BUSY, OFF );
if(pt_aux == NULL) flag = 1; /* OK */
if( pt_aux == NULL )
flag = 1;/* OK */
break;
}
break;
@ -464,19 +494,23 @@ wxString msg;
if( pt_segm_e )
{
/* les 2 segments doivent avoir meme largeur */
if(PtSegm->m_Width != pt_segm_e->m_Width ) break;
if( PtSegm->m_Width != pt_segm_e->m_Width )
break;
/* Ce ne peut etre une via */
if(pt_segm_e->m_StructType != TYPETRACK) break;
if( pt_segm_e->m_StructType != TYPETRACK )
break;
/* On ne peut avoir que 1 seul segment connecte */
pt_segm_e->SetState( BUSY, ON );
pt_aux = Locate_Piste_Connectee( PtSegm, frame->m_Pcb->m_Track,
NULL, END );
pt_segm_e->SetState( BUSY, OFF );
if (pt_aux == NULL) flag |= 2;/* Ok */
if( pt_aux == NULL )
flag |= 2;/* Ok */
break;
}
else break;
else
break;
}
if( flag & 2 ) /* FIN de segment raccorde a un autre segment */
@ -496,19 +530,22 @@ wxString msg;
NextS = PtSegm->Pnext;
}
}
return (0) ;
return 0;
}
/****************************************************************************/
static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extremite )
/****************************************************************************/
/* Routine utilisee par clean_segments.
Verifie l'alignement de pt_segm / pt_ref. et verifie que le point commun
a faire disparaitre n'est pas sur un pad.
l'extremite testee est debut (extremite == START) ou fin (extremite == FIN)
si il y a alignement, modifie les coord d'extremite de pt_ref et retourne
pt_segm.
sinon retourne NULL
* Verifie l'alignement de pt_segm / pt_ref. et verifie que le point commun
* a faire disparaitre n'est pas sur un pad.
* l'extremite testee est debut (extremite == START) ou fin (extremite == FIN)
* si il y a alignement, modifie les coord d'extremite de pt_ref et retourne
* pt_segm.
* sinon retourne NULL
*/
{
int refdx, refdy, segmdx, segmdy;/* projections des segments */
@ -520,73 +557,80 @@ int flag = 0;
/* Tst alignement vertical possible: */
if( refdx == 0 )
{
if (segmdx != 0) return(NULL);
else flag = 1;
if( segmdx != 0 )
return NULL;
else
flag = 1;
}
/* Tst alignement horizontal possible: */
if( refdy == 0 )
{
if (segmdy != 0) return(NULL);
else flag = 2;
if( segmdy != 0 )
return NULL;
else
flag = 2;
}
/* tst si il y a alignement d'angle qcq
il faut que refdy/refdx == (+/-)segmdy/segmdx, c.a.d meme direction */
* il faut que refdy/refdx == (+/-)segmdy/segmdx, c.a.d meme direction */
if( flag == 0 )
{
if( (refdy * segmdx != refdx * segmdy) &&
(refdy * segmdx != -refdx * segmdy) ) return(NULL);
if( (refdy * segmdx != refdx * segmdy)
&& (refdy * segmdx != -refdx * segmdy) )
return NULL;
flag = 4;
}
/* Ici il y a alignement: il faut determiner les positions relatives
pour supprimer le point commun et le remplacer */
* pour supprimer le point commun et le remplacer */
if( extremite == START )
{
/* Ce ne doit pas etre sur un pad */
if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_Start,
g_TabOneLayerMask[pt_ref->m_Layer] ) )
return(NULL);
return NULL;
if( (pt_ref->m_Start.x == pt_segm->m_Start.x) && (pt_ref->m_Start.y == pt_segm->m_Start.y) )
if( (pt_ref->m_Start.x == pt_segm->m_Start.x)
&& (pt_ref->m_Start.y == pt_segm->m_Start.y) )
{
pt_ref->m_Start.x = pt_segm->m_End.x; pt_ref->m_Start.y = pt_segm->m_End.y;
return(pt_segm);
return pt_segm;
}
else /* connexion par la fin de pt_segm */
{
pt_ref->m_Start.x = pt_segm->m_Start.x; pt_ref->m_Start.y = pt_segm->m_Start.y;
return(pt_segm);
return pt_segm;
}
}
else /* extremite == END */
{
/* Ce ne doit pas etre sur un pad */
if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_End, g_TabOneLayerMask[pt_ref->m_Layer] ) )
return(NULL);
return NULL;
if( pt_ref->m_End == pt_segm->m_Start )
{
pt_ref->m_End = pt_segm->m_End;
return(pt_segm);
return pt_segm;
}
else /* connexion par la fin de pt_segm */
{
pt_ref->m_End = pt_segm->m_Start;
return(pt_segm);
return pt_segm;
}
}
return(NULL);
return NULL;
}
/***************************************************************************/
int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche )
/***************************************************************************/
/*
verification des connexions.
Supprime les segments mal connectes, c.a.d. interconnectant des segments
de net_code differents
* verification des connexions.
* Supprime les segments mal connectes, c.a.d. interconnectant des segments
* de net_code differents
*/
{
TRACK* PtSegm, * pt_aux;
@ -604,7 +648,8 @@ wxString msg;
frame->DrawPanel->m_AbortRequest = FALSE;
if(affiche) Affiche_1_Parametre(frame,POS_AFF_VAR, _("NetCtr"), wxT("0 "),a_color);
if( affiche )
Affiche_1_Parametre( frame, POS_AFF_VAR, _( "NetCtr" ), wxT( "0 " ), a_color );
ii = 0;
for( PtSegm = frame->m_Pcb->m_Track; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
@ -621,39 +666,44 @@ wxString msg;
msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack );
Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN );
if( frame->DrawPanel->m_AbortRequest ) return(flag);
if( frame->DrawPanel->m_AbortRequest )
return flag;
}
PtSegm->SetState( FLAG0, OFF );
/* Calcul du net_code des elements raccordes sur le point de debut */
net_code_s = -1;
if( (PtSegm->start != NULL) &&
( ((EDA_BaseStruct*)(PtSegm->start))->m_StructType == TYPEPAD) )
if( (PtSegm->start != NULL)
&& ( ( (EDA_BaseStruct*) (PtSegm->start) )->m_StructType == TYPEPAD ) )
net_code_s = ( (D_PAD*) (PtSegm->start) )->m_NetCode;
else
{
pt_aux = Locate_Piste_Connectee( PtSegm, frame->m_Pcb->m_Track,
NULL, START );
if(pt_aux) net_code_s = pt_aux->m_NetCode;
if( pt_aux )
net_code_s = pt_aux->m_NetCode;
}
if(net_code_s < 0 ) continue ; /* Extremite en l'air */
if( net_code_s < 0 )
continue;/* Extremite en l'air */
/* Calcul du net_code des elements raccordes sur le point de fin */
net_code_e = -1;
if( (PtSegm->end != NULL) &&
( ((EDA_BaseStruct*)(PtSegm->end))->m_StructType == TYPEPAD) )
if( (PtSegm->end != NULL)
&& ( ( (EDA_BaseStruct*) (PtSegm->end) )->m_StructType == TYPEPAD ) )
net_code_e = ( (D_PAD*) (PtSegm->end) )->m_NetCode;
else
{
pt_aux = Locate_Piste_Connectee( PtSegm, frame->m_Pcb->m_Track,
NULL, END );
if(pt_aux) net_code_e = pt_aux->m_NetCode;
if( pt_aux )
net_code_e = pt_aux->m_NetCode;
}
if(net_code_e < 0 ) continue ; /* Extremite en l'air */
if( net_code_e < 0 )
continue;/* Extremite en l'air */
/* Marquage des segments a supprimer */
if( net_code_s != net_code_e )
@ -682,7 +732,8 @@ wxString msg;
}
}
}
return(flag);
return flag;
}
@ -693,10 +744,10 @@ static void Gen_Raccord_Track(WinEDA_PcbFrame * frame, wxDC * DC)
/***************************************************************/
/* Teste les extremites de segments :
si une extremite est sur un segment de piste, mais pas sur une extremite,
le segment est coupe en 2, le point de coupure etant l'extremite du segment
Ceci est fait pour que les tests de connexion qui ne testent que les extremites
de segments voient la connexion
* si une extremite est sur un segment de piste, mais pas sur une extremite,
* le segment est coupe en 2, le point de coupure etant l'extremite du segment
* Ceci est fait pour que les tests de connexion qui ne testent que les extremites
* de segments voient la connexion
*/
{
TRACK* PtSegm, * pt_aux, * NewTrack;
@ -707,7 +758,8 @@ int ii, percent, oldpercent;
wxString msg;
frame->Affiche_Message( wxT( "Gen Raccords sur Pistes:" ) );
if( frame->m_Pcb->GetNumSegmTrack() == 0 ) return;
if( frame->m_Pcb->GetNumSegmTrack() == 0 )
return;
frame->DrawPanel->m_AbortRequest = FALSE;
@ -728,24 +780,33 @@ wxString msg;
Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN );
}
if( frame->DrawPanel->m_AbortRequest ) return;
if( frame->DrawPanel->m_AbortRequest )
return;
masquelayer = PtSegm->ReturnMaskLayer();
/* examen du point de depart du segment de reference */
for( pt_aux = frame->m_Pcb->m_Track; ; pt_aux = (TRACK*) pt_aux->Pnext )
{
if (pt_aux == NULL) break;
if( pt_aux == NULL )
break;
pt_aux = Locate_Pistes( pt_aux, PtSegm->m_Start, masquelayer );
if (pt_aux == NULL) break;
if(pt_aux == PtSegm) continue;
if(pt_aux->m_StructType == TYPEVIA) continue;
if( PtSegm->m_Start == pt_aux->m_Start ) continue;
if( PtSegm->m_Start == pt_aux->m_End ) continue;
if( pt_aux == NULL )
break;
if( pt_aux == PtSegm )
continue;
if( pt_aux->m_StructType == TYPEVIA )
continue;
if( PtSegm->m_Start == pt_aux->m_Start )
continue;
if( PtSegm->m_Start == pt_aux->m_End )
continue;
// Test si autre extremite du segment ne serait pas deja connectee
if( PtSegm->m_End == pt_aux->m_Start ) continue;
if( PtSegm->m_End == pt_aux->m_End ) continue;
if( PtSegm->m_End == pt_aux->m_Start )
continue;
if( PtSegm->m_End == pt_aux->m_End )
continue;
pt_aux->Draw( frame->DrawPanel, DC, GR_XOR );
NewTrack = pt_aux->Copy();
@ -764,15 +825,23 @@ wxString msg;
for( pt_aux = frame->m_Pcb->m_Track; pt_aux != NULL; pt_aux = (TRACK*) pt_aux->Pnext )
{
pt_aux = Locate_Pistes( pt_aux, PtSegm->m_End, masquelayer );
if(pt_aux == NULL) break;
if(pt_aux == PtSegm) continue;
if(pt_aux->m_StructType == TYPEVIA) continue;
if( pt_aux == NULL )
break;
if( pt_aux == PtSegm )
continue;
if( pt_aux->m_StructType == TYPEVIA )
continue;
if( (PtSegm->m_End.x == pt_aux->m_Start.x) && (PtSegm->m_End.y == pt_aux->m_Start.y)) continue;
if( (PtSegm->m_End.x == pt_aux->m_End.x) && (PtSegm->m_End.y == pt_aux->m_End.y)) continue;
if( (PtSegm->m_End.x == pt_aux->m_Start.x) && (PtSegm->m_End.y == pt_aux->m_Start.y) )
continue;
if( (PtSegm->m_End.x == pt_aux->m_End.x) && (PtSegm->m_End.y == pt_aux->m_End.y) )
continue;
if( (PtSegm->m_Start.x == pt_aux->m_Start.x) && (PtSegm->m_Start.y == pt_aux->m_Start.y)) continue;
if( (PtSegm->m_Start.x == pt_aux->m_End.x) && (PtSegm->m_Start.y == pt_aux->m_End.y)) continue;
if( (PtSegm->m_Start.x == pt_aux->m_Start.x)
&& (PtSegm->m_Start.y == pt_aux->m_Start.y) )
continue;
if( (PtSegm->m_Start.x == pt_aux->m_End.x) && (PtSegm->m_Start.y == pt_aux->m_End.y) )
continue;
pt_aux->Draw( frame->DrawPanel, DC, GR_XOR );
@ -790,14 +859,16 @@ wxString msg;
}
}
/***************************************************************/
void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC )
/**************************************************************/
/*
rajoute eventuellement un segment a une extremite de piste connectee
a un pad si cette extremite n'est pas exactement connectee au centre
du pad.
Ceci permet un controle plus rapide des connexions
* rajoute eventuellement un segment a une extremite de piste connectee
* a un pad si cette extremite n'est pas exactement connectee au centre
* du pad.
* Ceci permet un controle plus rapide des connexions
*/
{
TRACK* PtSegm;
@ -830,7 +901,8 @@ wxString msg;
msg.Printf( wxT( "%d" ), ii );
Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, _( "Segm" ), msg, CYAN );
if( frame->DrawPanel->m_AbortRequest ) return;
if( frame->DrawPanel->m_AbortRequest )
return;
}
ptr_pad = Locate_Pad_Connecte( frame->m_Pcb, PtSegm, START );
@ -857,8 +929,8 @@ wxString msg;
ptr_pad = Locate_Pad_Connecte( frame->m_Pcb, PtSegm, END );
if( ptr_pad != NULL )
{ /* Test si point piste "en l'air" */
if( (PtSegm->m_End.x != ptr_pad->m_Pos.x) ||
(PtSegm->m_End.y != ptr_pad->m_Pos.y) )
if( (PtSegm->m_End.x != ptr_pad->m_Pos.x)
|| (PtSegm->m_End.y != ptr_pad->m_Pos.y) )
{
if( Locate_Piste_Connectee( PtSegm, frame->m_Pcb->m_Track,
NULL, END ) == NULL )

View File

@ -336,9 +336,11 @@ void WinEDA_BasePcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse )
bool keep_on_grid = TRUE;
if( m_ID_current_state == ID_PCB_DELETE_ITEM_BUTT )
keep_on_grid = FALSE;
/* Cursor is left off grid if no block in progress and no moving object */
if( GetScreen()->BlockLocate.m_State != STATE_NO_BLOCK )
keep_on_grid = TRUE;
EDA_BaseStruct* DrawStruct = GetScreen()->m_CurrentItem;
if( DrawStruct && DrawStruct->m_Flags )
keep_on_grid = TRUE;

View File

@ -35,7 +35,8 @@ void WinEDA_PcbFrame::InstallFindFrame( const wxPoint& pos, wxDC* DC )
{
WinEDA_PcbFindFrame* frame = new WinEDA_PcbFindFrame( this, DC, pos );
frame->ShowModal(); frame->Destroy();
frame->ShowModal();
frame->Destroy();
}

View File

@ -46,8 +46,8 @@ static void ShowCadreSelf(WinEDA_DrawPanel * panel, wxDC * DC, bool erase)
int deltaX, deltaY;
/* Calcul de l'orientation et de la taille de la fenetre:
- orient = vert ou Horiz ( dimension max)
- Size.x = Size.y / 2
* - orient = vert ou Horiz ( dimension max)
* - Size.x = Size.y / 2
*/
GRSetDrawMode( DC, GR_XOR );
@ -60,7 +60,8 @@ int deltaX, deltaY;
deltaY = (panel->GetScreen()->m_Curseur.y - Mself.m_Start.y) / 4;
Mself.orient = 900;
if( abs(deltaX) > abs(deltaY) ) Mself.orient = 0;
if( abs( deltaX ) > abs( deltaY ) )
Mself.orient = 0;
if( Mself.orient == 0 )
{
@ -98,11 +99,11 @@ void Exit_Self(WinEDA_DrawPanel * Panel, wxDC *DC)
/*******************************************/
void WinEDA_PcbFrame::Begin_Self( wxDC* DC )
/*******************************************/
/*
Routine d'initialisation d'un trace de self
* Routine d'initialisation d'un trace de self
*/
{
if( Self_On )
{
Genere_Self( DC );
@ -125,44 +126,46 @@ Routine d'initialisation d'un trace de self
DrawPanel->ManageCurseur( DrawPanel, DC, 0 ); /* Affiche cadre */
}
/**********************************************/
MODULE* WinEDA_PcbFrame::Genere_Self( wxDC* DC )
/**********************************************/
/* Genere une self en forme de serpentin
- longueur Mself.lng
- Extremites Mself.m_Start et Mself.m_End
- Contrainte: m_Start.x = m_End.x ( self verticale )
ou m_Start.y = m_End.y ( self horizontale )
On doit determiner:
Mself.nbrin = nombre de segments perpendiculaires a la direction
( le serpention aura nbrin + 1 demicercles + 2 1/4 de cercle)
Mself.lbrin = longueur d'un brin
Mself.rayon = rayon des parties arrondies du serpentin
Mself.delta = segments raccord entre extremites et le serpention lui meme
Les equations sont
Mself.m_Size.x = 2*Mself.rayon + Mself.lbrin
Mself.m_Size.y = 2*Mself.delta + 2*Mself.nbrin*Mself.rayon
Mself.lng = 2*Mself.delta // Raccords au serpentin
* - longueur Mself.lng
* - Extremites Mself.m_Start et Mself.m_End
* - Contrainte: m_Start.x = m_End.x ( self verticale )
* ou m_Start.y = m_End.y ( self horizontale )
*
* On doit determiner:
* Mself.nbrin = nombre de segments perpendiculaires a la direction
* ( le serpention aura nbrin + 1 demicercles + 2 1/4 de cercle)
* Mself.lbrin = longueur d'un brin
* Mself.rayon = rayon des parties arrondies du serpentin
* Mself.delta = segments raccord entre extremites et le serpention lui meme
*
* Les equations sont
* Mself.m_Size.x = 2*Mself.rayon + Mself.lbrin
* Mself.m_Size.y = 2*Mself.delta + 2*Mself.nbrin*Mself.rayon
* Mself.lng = 2*Mself.delta // Raccords au serpentin
+ (Mself.nbrin-2) * Mself.lbrin //longueur des brins sauf 1er et dernier
+ (Mself.nbrin+1) * ( PI * Mself.rayon) // longueur des arrondis
+ Mself.lbrin/2 - Melf.rayon*2) // longueur du 1er et dernier brin
Les contraintes sont:
nbrin >= 2
Mself.rayon < Mself.m_Size.x
Mself.m_Size.y = Mself.rayon*4 + 2*Mself.raccord
Mself.lbrin > Mself.rayon *2
Le calcul est conduit de la facon suivante:
Initialement:
nbrin = 2
rayon = 4 * m_Size.x (valeur fixe arbitraire)
puis:
on augmente le nombre de brins jusqu'a la longueur desiree
( le rayon est diminue si necessaire )
*
* Les contraintes sont:
* nbrin >= 2
* Mself.rayon < Mself.m_Size.x
* Mself.m_Size.y = Mself.rayon*4 + 2*Mself.raccord
* Mself.lbrin > Mself.rayon *2
*
* Le calcul est conduit de la facon suivante:
* Initialement:
* nbrin = 2
* rayon = 4 * m_Size.x (valeur fixe arbitraire)
* puis:
* on augmente le nombre de brins jusqu'a la longueur desiree
* ( le rayon est diminue si necessaire )
*
*/
{
EDGE_MODULE* PtSegm, * LastSegm, * FirstSegm, * newedge;
@ -192,15 +195,16 @@ wxString msg;
if( Mself.orient == 0 ) // Self horizontale
{
Mself.m_End.y = Mself.m_Start.y;
if(Mself.m_Start.x > Mself.m_End.x) EXCHG(Mself.m_Start.x,Mself.m_End.x);
if( Mself.m_Start.x > Mself.m_End.x )
EXCHG( Mself.m_Start.x, Mself.m_End.x );
Mself.m_Size.y = Mself.m_End.x - Mself.m_Start.x;
Mself.lng = Mself.m_Size.y;
}
else // Self verticale
{
Mself.m_End.x = Mself.m_Start.x;
if(Mself.m_Start.y > Mself.m_End.y) EXCHG(Mself.m_Start.y,Mself.m_End.y);
if( Mself.m_Start.y > Mself.m_End.y )
EXCHG( Mself.m_Start.y, Mself.m_End.y );
Mself.m_Size.y = Mself.m_End.y - Mself.m_Start.y;
Mself.lng = Mself.m_Size.y;
}
@ -218,7 +222,8 @@ wxString msg;
msg.Printf( wxT( "%2.3f" ), Mself.lng / fcoeff );
abort = Get_Message( _( "Length(mm):" ), msg, this );
}
if ( abort ) return NULL;
if( abort )
return NULL;
double fval;
if( !msg.ToDouble( &fval ) )
@ -238,6 +243,7 @@ wxString msg;
/* Generation du composant: calcul des elements de la self */
Mself.m_Width = g_DesignSettings.m_CurrentTrackWidth;
Mself.m_Size.x = Mself.m_Size.y / 2;
// Choix d'une Valeur de depart raisonnable pour le rayon des arcs de cercle
Mself.rayon = min( Mself.m_Width * 5, Mself.m_Size.x / 4 );
/* Calcul des parametres */
@ -266,11 +272,13 @@ wxString msg;
wxString stlen;
valeur_param( ll, stlen ); msg += stlen;
Affiche_Message( msg );
if ( ll >= Mself.lng) break;
if( ll >= Mself.lng )
break;
}
/* Generation du composant : le calcul est fait self Verticale */
if( Create_1_Module(DC, wxEmptyString) == NULL ) return NULL;
if( Create_1_Module( DC, wxEmptyString ) == NULL )
return NULL;
Module = m_Pcb->m_Modules;
Module->m_LibRef = wxT( "MuSelf" );
@ -281,7 +289,9 @@ wxString msg;
/* Generation des elements speciaux: drawsegments */
LastSegm = (EDGE_MODULE*) Module->m_Drawings;
if( LastSegm ) while( LastSegm->Pnext) LastSegm = (EDGE_MODULE*)LastSegm->Pnext;
if( LastSegm )
while( LastSegm->Pnext )
LastSegm = (EDGE_MODULE*) LastSegm->Pnext;
FirstSegm = PtSegm = new EDGE_MODULE( Module );
if( LastSegm )
@ -328,7 +338,8 @@ wxString msg;
PtSegm->m_Start = PtSegm->m_End;
if( ii & 1 ) /* brin d'ordre impair : cercles de sens > 0 */
arc_angle = 1800;
else arc_angle = -1800;
else
arc_angle = -1800;
PtSegm = gen_arc( PtSegm, PtSegm->m_End.x,
PtSegm->m_End.y + Mself.rayon, arc_angle );
@ -340,8 +351,10 @@ wxString msg;
newedge->AddToChain( PtSegm );
PtSegm = newedge;
PtSegm->m_Start = PtSegm->m_End;
if( ii & 1) PtSegm->m_End.x += Mself.lbrin;
else PtSegm->m_End.x -= Mself.lbrin;
if( ii & 1 )
PtSegm->m_End.x += Mself.lbrin;
else
PtSegm->m_End.x -= Mself.lbrin;
}
}
@ -435,8 +448,10 @@ wxString msg;
/* Modif des positions textes */
Module->Display_Infos( this );
Module->m_Value->m_Pos.x = Module->m_Reference->m_Pos.x = ( FirstSegm->m_Start.x + LastSegm->m_End.x ) /2 ;
Module->m_Value->m_Pos.y = Module->m_Reference->m_Pos.y = ( FirstSegm->m_Start.y + LastSegm->m_End.y ) /2 ;
Module->m_Value->m_Pos.x = Module->m_Reference->m_Pos.x = ( FirstSegm->m_Start.x +
LastSegm->m_End.x ) / 2;
Module->m_Value->m_Pos.y = Module->m_Reference->m_Pos.y = ( FirstSegm->m_Start.y +
LastSegm->m_End.y ) / 2;
Module->m_Reference->m_Pos.y -= Module->m_Reference->m_Size.y;
Module->m_Value->m_Pos.y += Module->m_Value->m_Size.y;
@ -468,11 +483,11 @@ static EDGE_MODULE * gen_arc(EDGE_MODULE * PtSegm, int cX, int cY, int angle)
/**************************************************************************/
/* Genere un arc de EDGE_MODULE :
de centre cX,cY
d'angle "angle"
de point de depart donne dans la structure pointee par PtSegm, qui doit
entre a jour (type,net..)
Retourne un pointeur sur la derniere structure EDGE_MODULE generee
* de centre cX,cY
* d'angle "angle"
* de point de depart donne dans la structure pointee par PtSegm, qui doit
* entre a jour (type,net..)
* Retourne un pointeur sur la derniere structure EDGE_MODULE generee
*/
{
int ii, nb_seg;
@ -483,7 +498,8 @@ EDGE_MODULE * newedge;
angle = -angle;
y0 = PtSegm->m_Start.x - cX; x0 = PtSegm->m_Start.y - cY;
nb_seg = (abs(angle)) / 225 ; if(nb_seg == 0) nb_seg = 1 ;
nb_seg = ( abs( angle ) ) / 225; if( nb_seg == 0 )
nb_seg = 1;
alpha = ( (float) angle * 3.14159 / 1800 ) / nb_seg;
for( ii = 1; ii <= nb_seg; ii++ )
@ -505,6 +521,6 @@ EDGE_MODULE * newedge;
yr0 = (int) (y0 * fcos - x0 * fsin);
PtSegm->m_End.x = cX + yr0; PtSegm->m_End.y = cY + xr0;
}
return( PtSegm );
}
return PtSegm;
}

View File

@ -16,6 +16,7 @@
/* fonctions locales */
EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc );
D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer );
/**
@ -390,10 +391,10 @@ DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc )
}
/*************************************************/
/* D_PAD * Locate_Any_Pad(int typeloc, bool OnlyCurrentLayer) */
/* D_PAD* Locate_Any_Pad(int ref_pos, bool OnlyCurrentLayer) */
/*************************************************/
/*************************************************
* D_PAD * Locate_Any_Pad(int typeloc, bool OnlyCurrentLayer)
* D_PAD* Locate_Any_Pad(int ref_pos, bool OnlyCurrentLayer)
*************************************************/
/*
* localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou

View File

@ -30,15 +30,17 @@ static int ModuleInitLayer; // Lors des moves, val init de la couche (pour annu
/*************************************************************************/
void Show_Pads_On_Off( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* module )
/**************************************************************************/
/* Fonction appelee lors de l'activation/desactivation de la visualisation
des Pads du module en deplacement
Effacement ou visu des Pads selon conditions initiales
* des Pads du module en deplacement
* Effacement ou visu des Pads selon conditions initiales
*/
{
D_PAD* pt_pad;
bool pad_fill_tmp;
if(module == 0 ) return ;
if( module == 0 )
return;
pad_fill_tmp = DisplayOpt.DisplayPadFill;
DisplayOpt.DisplayPadFill = FALSE; /* Trace en SKETCH */
@ -47,9 +49,11 @@ bool pad_fill_tmp;
{
pt_pad->Draw( panel, DC, g_Offset_Module, GR_XOR );
}
DisplayOpt.DisplayPadFill = pad_fill_tmp;
}
/***************************************************************************/
/* Fonction appelee lors de l'activation/desactivation de la visualisation */
/* du rastnest du module en deplacement */
@ -58,13 +62,16 @@ bool pad_fill_tmp;
void Rastnest_On_Off( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* module )
{
WinEDA_BasePcbFrame* frame = (WinEDA_BasePcbFrame*) panel->m_Parent;
frame->build_ratsnest_module( DC, module );
frame->trace_ratsnest_module( DC );
}
/***************************************************/
MODULE* WinEDA_BasePcbFrame::GetModuleByName( void )
/***************************************************/
/* Get a module name from user and return a pointer to the corresponding module
*/
{
@ -77,20 +84,21 @@ MODULE * module = NULL;
module = m_Pcb->m_Modules;
while( module )
{
if ( module->m_Reference->m_Text.CmpNoCase(modulename) == 0 ) break;
if( module->m_Reference->m_Text.CmpNoCase( modulename ) == 0 )
break;
module = module->Next();
}
}
return module;
}
/**********************************************************************/
void WinEDA_PcbFrame::StartMove_Module( MODULE* module, wxDC* DC )
/**********************************************************************/
{
if (module == NULL ) return;
if( module == NULL )
return;
m_CurrentScreen->m_CurrentItem = module;
m_Pcb->m_Status_Pcb &= ~CHEVELU_LOCAL_OK;
@ -99,7 +107,8 @@ void WinEDA_PcbFrame::StartMove_Module(MODULE * module, wxDC * DC)
ModuleInitLayer = module->m_Layer;
/* Effacement chevelu general si necessaire */
if(g_Show_Ratsnest) DrawGeneralRatsnest(DC);
if( g_Show_Ratsnest )
DrawGeneralRatsnest( DC );
if( g_DragSegmentList ) /* Anormal ! */
{
@ -118,10 +127,12 @@ void WinEDA_PcbFrame::StartMove_Module(MODULE * module, wxDC * DC)
// effacement module a l'ecran:
module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
// Reaffichage
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
}
/**************************************************/
void Exit_Module( WinEDA_DrawPanel* Panel, wxDC* DC )
/***************************************************/
@ -162,6 +173,7 @@ WinEDA_BasePcbFrame * pcbframe = (WinEDA_BasePcbFrame*)Panel->m_Parent;
pt_drag->SetInitialValues();
pt_segm->Draw( Panel, DC, GR_OR );
}
EraseDragListe();
module->m_Flags = 0;
}
@ -198,7 +210,8 @@ MODULE * WinEDA_BasePcbFrame::Copie_Module(MODULE * module)
{
MODULE* newmodule;
if (module == NULL ) return NULL;
if( module == NULL )
return NULL;
m_CurrentScreen->SetModify();
@ -217,15 +230,18 @@ MODULE * newmodule;
return newmodule;
}
/**********************************************************************************/
void Montre_Position_Empreinte( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/**********************************************************************************/
/* redessin du contour de l'empreinte lors des deplacements de la souris
*/
{
MODULE* module = (MODULE*) panel->m_Parent->m_CurrentScreen->m_CurrentItem;
if ( module == NULL ) return;
if( module == NULL )
return;
/* efface ancienne position */
if( erase )
@ -245,16 +261,19 @@ MODULE * module = (MODULE *) panel->m_Parent->m_CurrentScreen->m_CurrentItem;
/**************************************************************/
bool WinEDA_PcbFrame::Delete_Module( MODULE* module, wxDC* DC )
/**************************************************************/
/*
Commande Delete Module :
Suppression d'une empreinte
les pointeurs divers sont mis a jour
* Commande Delete Module :
* Suppression d'une empreinte
* les pointeurs divers sont mis a jour
*/
{
EDA_BaseStruct* PtBack, * PtNext;
wxString msg;
/* Si l'empreinte est selectee , on ne peut pas l'effacer ! */
if ( module == NULL ) return FALSE;
if( module == NULL )
return FALSE;
/* Confirmation de l'effacement */
module->Display_Infos( this );
@ -270,10 +289,12 @@ wxString msg;
m_CurrentScreen->SetModify();
/* Erase rastnest if needed */
if(g_Show_Ratsnest) DrawGeneralRatsnest(DC);
if( g_Show_Ratsnest )
DrawGeneralRatsnest( DC );
/* Effacement du module a l'ecran */
if ( DC ) module->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR);
if( DC )
module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
/* Suppression du chainage */
PtBack = module->Pback;
@ -286,7 +307,8 @@ wxString msg;
{
PtBack->Pnext = PtNext;
}
if(PtNext) PtNext->Pback = PtBack;
if( PtNext )
PtNext->Pback = PtBack;
/* Sauvegarde en buffer des undelete */
SaveItemEfface( module, 1 );
@ -297,14 +319,15 @@ wxString msg;
return TRUE;
}
/**********************************************************************/
void WinEDA_BasePcbFrame::Change_Side_Module( MODULE* Module, wxDC* DC )
/**********************************************************************/
/* Change de cote un composant : il y a inversion MIROIR autour de l'axe X
Le changement n'est fait que si la couche est
- CUIVRE ou CMP
Si DC == NULL, il n'y a pas de redessin du composant et du chevelu
* Le changement n'est fait que si la couche est
* - CUIVRE ou CMP
* Si DC == NULL, il n'y a pas de redessin du composant et du chevelu
*/
{
D_PAD* pt_pad;
@ -312,23 +335,27 @@ TEXTE_MODULE* pt_texte;
EDGE_MODULE* pt_edgmod;
EDA_BaseStruct* PtStruct;
if ( Module == NULL ) return;
if( (Module->m_Layer != CMP_N) && (Module->m_Layer != CUIVRE_N) ) return;
if( Module == NULL )
return;
if( (Module->m_Layer != CMP_N) && (Module->m_Layer != CUIVRE_N) )
return;
m_CurrentScreen->SetModify();
if( !(Module->m_Flags & IS_MOVED) )
{
m_Pcb->m_Status_Pcb &= ~( LISTE_CHEVELU_OK | CONNEXION_OK);
if ( DC ) Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR);
if( DC )
Module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
/* Effacement chevelu general si necessaire */
if ( DC && g_Show_Ratsnest) DrawGeneralRatsnest(DC);
if( DC && g_Show_Ratsnest )
DrawGeneralRatsnest( DC );
/* Init des variables utilisees dans la routine Dessine_Drag_segment() */
g_Offset_Module.x = 0;
g_Offset_Module.y = 0;
}
else // Module en deplacement
{
/* efface empreinte ( vue en contours) si elle a ete deja dessinee */
@ -357,6 +384,7 @@ EDA_BaseStruct * PtStruct;
pt_pad->m_Offset.y = -pt_pad->m_Offset.y;
pt_pad->m_DeltaSize.y = -pt_pad->m_DeltaSize.y;
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_pad->m_Orient );
/* change cote pour pastilles surfaciques */
pt_pad->m_Masque_Layer = ChangeSideMaskLayer( pt_pad->m_Masque_Layer );
}
@ -371,10 +399,15 @@ EDA_BaseStruct * PtStruct;
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_texte->m_Orient );
pt_texte->m_Layer = Module->m_Layer;
pt_texte->m_Layer = ChangeSideNumLayer( pt_texte->m_Layer );
if( Module->m_Layer == CUIVRE_N) pt_texte->m_Layer = SILKSCREEN_N_CU;
if( Module->m_Layer == CMP_N) pt_texte->m_Layer = SILKSCREEN_N_CMP;
if( (Module->m_Layer == SILKSCREEN_N_CU) ||
(Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) )
if( Module->m_Layer == CUIVRE_N )
pt_texte->m_Layer = SILKSCREEN_N_CU;
if( Module->m_Layer == CMP_N )
pt_texte->m_Layer = SILKSCREEN_N_CMP;
if( (Module->m_Layer == SILKSCREEN_N_CU)
|| (Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) )
pt_texte->m_Miroir = 0;
/* Inversion miroir de la Valeur et mise en miroir : */
@ -387,10 +420,15 @@ EDA_BaseStruct * PtStruct;
NEGATE_AND_NORMALIZE_ANGLE_POS( pt_texte->m_Orient );
pt_texte->m_Layer = Module->m_Layer;
pt_texte->m_Layer = ChangeSideNumLayer( pt_texte->m_Layer );
if( Module->m_Layer == CUIVRE_N) pt_texte->m_Layer = SILKSCREEN_N_CU;
if( Module->m_Layer == CMP_N) pt_texte->m_Layer = SILKSCREEN_N_CMP;
if( (Module->m_Layer == SILKSCREEN_N_CU) ||
(Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) )
if( Module->m_Layer == CUIVRE_N )
pt_texte->m_Layer = SILKSCREEN_N_CU;
if( Module->m_Layer == CMP_N )
pt_texte->m_Layer = SILKSCREEN_N_CMP;
if( (Module->m_Layer == SILKSCREEN_N_CU)
|| (Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) )
pt_texte->m_Miroir = 0;
/* Inversion miroir des dessins de l'empreinte : */
@ -430,16 +468,21 @@ EDA_BaseStruct * PtStruct;
pt_texte->m_Layer = Module->m_Layer;
pt_texte->m_Layer = ChangeSideNumLayer( pt_texte->m_Layer );
if( Module->m_Layer == CUIVRE_N) pt_texte->m_Layer = SILKSCREEN_N_CU;
if(Module->m_Layer == CMP_N) pt_texte->m_Layer = SILKSCREEN_N_CMP;
if((Module->m_Layer == SILKSCREEN_N_CU) ||
(Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N))
if( Module->m_Layer == CUIVRE_N )
pt_texte->m_Layer = SILKSCREEN_N_CU;
if( Module->m_Layer == CMP_N )
pt_texte->m_Layer = SILKSCREEN_N_CMP;
if( (Module->m_Layer == SILKSCREEN_N_CU)
|| (Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) )
pt_texte->m_Miroir = 0;
break;
default: DisplayError(this, wxT("Unknown Draw Type")); break;
default:
DisplayError( this, wxT( "Unknown Draw Type" ) ); break;
}
}
@ -457,7 +500,6 @@ EDA_BaseStruct * PtStruct;
ReCompile_Ratsnest_After_Changes( DC );
}
}
else
{
if( DC )
@ -470,13 +512,13 @@ EDA_BaseStruct * PtStruct;
}
/*********************************************/
static int ChangeSideMaskLayer( int masque )
/*********************************************/
/* Routine de recalcul du masque-layer lors des
echanges cote cu/cmp pour les couches CU/CMP specialisees
(cuivre, serigr., pate , soudure)
* echanges cote cu/cmp pour les couches CU/CMP specialisees
* (cuivre, serigr., pate , soudure)
*/
{
int newmasque;
@ -488,77 +530,110 @@ int newmasque;
SOLDERPASTE_LAYER_CU | SOLDERPASTE_LAYER_CMP |
ADHESIVE_LAYER_CU | ADHESIVE_LAYER_CMP);
if( masque & CUIVRE_LAYER) newmasque |= CMP_LAYER;
if( masque & CMP_LAYER) newmasque |= CUIVRE_LAYER;
if( masque & CUIVRE_LAYER )
newmasque |= CMP_LAYER;
if( masque & CMP_LAYER )
newmasque |= CUIVRE_LAYER;
if( masque & SILKSCREEN_LAYER_CU) newmasque |= SILKSCREEN_LAYER_CMP;
if( masque & SILKSCREEN_LAYER_CMP) newmasque |= SILKSCREEN_LAYER_CU;
if( masque & SILKSCREEN_LAYER_CU )
newmasque |= SILKSCREEN_LAYER_CMP;
if( masque & SILKSCREEN_LAYER_CMP )
newmasque |= SILKSCREEN_LAYER_CU;
if( masque & ADHESIVE_LAYER_CU) newmasque |= ADHESIVE_LAYER_CMP;
if( masque & ADHESIVE_LAYER_CMP) newmasque |= ADHESIVE_LAYER_CU;
if( masque & ADHESIVE_LAYER_CU )
newmasque |= ADHESIVE_LAYER_CMP;
if( masque & ADHESIVE_LAYER_CMP )
newmasque |= ADHESIVE_LAYER_CU;
if( masque & SOLDERMASK_LAYER_CU) newmasque |= SOLDERMASK_LAYER_CMP;
if( masque & SOLDERMASK_LAYER_CMP) newmasque |= SOLDERMASK_LAYER_CU;
if( masque & SOLDERMASK_LAYER_CU )
newmasque |= SOLDERMASK_LAYER_CMP;
if( masque & SOLDERMASK_LAYER_CMP )
newmasque |= SOLDERMASK_LAYER_CU;
if( masque & SOLDERPASTE_LAYER_CU) newmasque |= SOLDERPASTE_LAYER_CMP;
if( masque & SOLDERPASTE_LAYER_CMP) newmasque |= SOLDERPASTE_LAYER_CU;
if( masque & SOLDERPASTE_LAYER_CU )
newmasque |= SOLDERPASTE_LAYER_CMP;
if( masque & SOLDERPASTE_LAYER_CMP )
newmasque |= SOLDERPASTE_LAYER_CU;
if( masque & ADHESIVE_LAYER_CU) newmasque |= ADHESIVE_LAYER_CMP;
if( masque & ADHESIVE_LAYER_CMP) newmasque |= ADHESIVE_LAYER_CU;
if( masque & ADHESIVE_LAYER_CU )
newmasque |= ADHESIVE_LAYER_CMP;
if( masque & ADHESIVE_LAYER_CMP )
newmasque |= ADHESIVE_LAYER_CU;
return(newmasque);
return newmasque;
}
/*************************************/
int ChangeSideNumLayer( int oldlayer )
/*************************************/
/* Routine de recalcul du numero de couche lors des
echanges cote cu/cmp pour les couches CU/CMP specialisees
(cuivre, serigr., pate , soudure)
* echanges cote cu/cmp pour les couches CU/CMP specialisees
* (cuivre, serigr., pate , soudure)
*/
{
int newlayer;
switch( oldlayer )
{
case CUIVRE_N: newlayer = CMP_N; break;
case CMP_N: newlayer = CUIVRE_N; break;
case CUIVRE_N:
newlayer = CMP_N; break;
case SILKSCREEN_N_CU: newlayer = SILKSCREEN_N_CMP; break;
case SILKSCREEN_N_CMP: newlayer = SILKSCREEN_N_CU; break;
case CMP_N:
newlayer = CUIVRE_N; break;
case ADHESIVE_N_CU: newlayer = ADHESIVE_N_CMP; break;
case ADHESIVE_N_CMP: newlayer = ADHESIVE_N_CU; break;
case SILKSCREEN_N_CU:
newlayer = SILKSCREEN_N_CMP; break;
case SOLDERMASK_N_CU: newlayer = SOLDERMASK_N_CMP; break;
case SOLDERMASK_N_CMP: newlayer = SOLDERMASK_N_CU; break;
case SILKSCREEN_N_CMP:
newlayer = SILKSCREEN_N_CU; break;
case SOLDERPASTE_N_CU: newlayer = SOLDERPASTE_N_CMP; break;
case SOLDERPASTE_N_CMP: newlayer = SOLDERPASTE_N_CU; break;
case ADHESIVE_N_CU:
newlayer = ADHESIVE_N_CMP; break;
default: newlayer = oldlayer;
case ADHESIVE_N_CMP:
newlayer = ADHESIVE_N_CU; break;
case SOLDERMASK_N_CU:
newlayer = SOLDERMASK_N_CMP; break;
case SOLDERMASK_N_CMP:
newlayer = SOLDERMASK_N_CU; break;
case SOLDERPASTE_N_CU:
newlayer = SOLDERPASTE_N_CMP; break;
case SOLDERPASTE_N_CMP:
newlayer = SOLDERPASTE_N_CU; break;
default:
newlayer = oldlayer;
}
return(newlayer);
return newlayer;
}
/*****************************************************************/
void WinEDA_BasePcbFrame::Place_Module( MODULE* module, wxDC* DC )
/*****************************************************************/
/* Place a l'endroit pointe par la souris le module deja existant selectionne
auparavant.
Entree: module = num du module a replacer
DC ( si NULL: pas d'affichage a l'écran
Sortie :
mise a jour des nouvelles coord des differents elements du module
affichage a l'ecran du module
* auparavant.
* Entree: module = num du module a replacer
* DC ( si NULL: pas d'affichage a l'<EFBFBD>ran
* Sortie :
* mise a jour des nouvelles coord des differents elements du module
* affichage a l'ecran du module
*/
{
TRACK* pt_segm;
DRAG_SEGM* pt_drag;
wxPoint newpos;
if ( module == 0 ) return ;
if( module == 0 )
return;
m_CurrentScreen->SetModify();
m_Pcb->m_Status_Pcb &= ~( LISTE_CHEVELU_OK | CONNEXION_OK);
@ -569,7 +644,8 @@ wxPoint newpos;
newpos = m_CurrentScreen->m_Curseur;
module->SetPosition( newpos );
if ( DC ) module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR);
if( DC )
module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_OR );
/* Tracage des segments dragges et liberation memoire */
if( g_DragSegmentList )
@ -579,8 +655,10 @@ wxPoint newpos;
{
pt_segm = pt_drag->m_Segm;
pt_segm->SetState( EDIT, OFF );
if ( DC ) pt_segm->Draw(DrawPanel, DC, GR_OR);
if( DC )
pt_segm->Draw( DrawPanel, DC, GR_OR );
}
EraseDragListe();
}
@ -600,15 +678,17 @@ wxPoint newpos;
void WinEDA_BasePcbFrame::Rotate_Module( wxDC* DC, MODULE* module,
int angle, bool incremental )
/***********************************************************************/
/*
Fait tourner l'empreinte de angle degres, dans le sens < 0.
Si incremental == TRUE, la rotation est faite a partir de la derniere orientation,
sinon le module est mis dans l'orientation absolue angle.
Si DC == NULL, le composant n'est pas redessine.
Sinon, il est efface, tourne et redessine
* Fait tourner l'empreinte de angle degres, dans le sens < 0.
* Si incremental == TRUE, la rotation est faite a partir de la derniere orientation,
* sinon le module est mis dans l'orientation absolue angle.
* Si DC == NULL, le composant n'est pas redessine.
* Sinon, il est efface, tourne et redessine
*/
{
if ( module == NULL ) return;
if( module == NULL )
return;
m_CurrentScreen->SetModify();
@ -619,7 +699,8 @@ void WinEDA_BasePcbFrame::Rotate_Module(wxDC * DC, MODULE * module,
{
module->Draw( DrawPanel, DC, wxPoint( 0, 0 ), GR_XOR );
/* Reaffichage chevelu general si necessaire */
if(g_Show_Ratsnest) DrawGeneralRatsnest(DC);
if( g_Show_Ratsnest )
DrawGeneralRatsnest( DC );
}
}
else
@ -668,7 +749,8 @@ void DrawModuleOutlines(WinEDA_DrawPanel * panel, wxDC * DC, MODULE * module)
int pad_fill_tmp;
D_PAD* pt_pad;
if(module == NULL) return ;
if( module == NULL )
return;
module->DrawEdgesOnly( panel, DC, g_Offset_Module, GR_XOR );
if( g_Show_Pads_Module_in_Move )
@ -681,6 +763,7 @@ D_PAD* pt_pad;
{
pt_pad->Draw( panel, DC, g_Offset_Module, GR_XOR );
}
DisplayOpt.DisplayPadFill = pad_fill_tmp;
}
@ -691,5 +774,3 @@ D_PAD* pt_pad;
frame->trace_ratsnest_module( DC );
}
}

View File

@ -24,6 +24,7 @@ static void Exit_MoveTrack(WinEDA_DrawPanel * Panel, wxDC *DC);
/* Routines Locales */
static void Duplic_Track( COMMAND* Cmd );
static void Place_Dupl_Route( COMMAND* Cmd );
#endif
/* variables locales */
@ -37,9 +38,10 @@ static bool Old_HightLigt_Status;
/**************************************************************/
static void Exit_MoveTrack( WinEDA_DrawPanel* Panel, wxDC* DC )
/***************************************************************/
/* routine d'annulation de la commande drag, copy ou move track si une piste est en cours
de tracage, ou de sortie de l'application EDITRACK.
Appel par la touche ESC
* de tracage, ou de sortie de l'application EDITRACK.
* Appel par la touche ESC
*/
{
TRACK* NextS;
@ -48,6 +50,7 @@ int ii;
/* Effacement du trace en cours */
wxPoint oldpos = Panel->GetScreen()->m_Curseur;
Panel->GetScreen()->m_Curseur = PosInit;
Panel->ManageCurseur( Panel, DC, TRUE );
Panel->GetScreen()->m_Curseur = oldpos;
@ -60,7 +63,8 @@ int ii;
{
for( ii = 0; ii < NbPtNewTrack; ii++, NewTrack = NextS )
{
if(NewTrack == NULL) break;
if( NewTrack == NULL )
break;
NextS = (TRACK*) NewTrack->Pnext;
delete NewTrack;
}
@ -72,14 +76,15 @@ int ii;
int dy = LastPos.y - PosInit.y;
for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext )
{
if( Track == NULL ) break;
if( Track == NULL )
break;
Track->m_Start.x -= dx;
Track->m_Start.y -= dy;
Track->m_End.x -= dx;
Track->m_End.y -= dy;
Track->m_Flags = 0;
}
Trace_Une_Piste( Panel, DC, NewTrack, NbPtNewTrack, GR_OR );
}
@ -111,7 +116,6 @@ int ii;
}
/*************************************************************************/
static void Show_MoveTrack( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/*************************************************************************/
@ -129,7 +133,8 @@ erase = TRUE;
/* efface ancienne position si elle a ete deja dessinee */
if( erase )
{
if ( NewTrack ) Trace_Une_Piste(panel, DC, NewTrack,NbPtNewTrack,GR_XOR) ;
if( NewTrack )
Trace_Une_Piste( panel, DC, NewTrack, NbPtNewTrack, GR_XOR );
}
/* mise a jour des coordonnees des segments de la piste */
@ -158,7 +163,8 @@ erase = TRUE;
for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext )
{
Track = pt_drag->m_Segm;
if ( erase ) Track->Draw(panel, DC, GR_XOR);
if( erase )
Track->Draw( panel, DC, GR_XOR );
if( Track->m_Flags & STARTPOINT )
{
Track->m_Start.x += dx; Track->m_Start.y += dy;
@ -169,11 +175,11 @@ erase = TRUE;
}
Track->Draw( panel, DC, GR_XOR );
}
DisplayOpt.DisplayPcbTrackFill = track_fill_copy;
}
/***********************************************************************************/
void WinEDA_PcbFrame::Start_MoveOneTrackSegment( TRACK* track, wxDC* DC, bool Drag )
/***********************************************************************************/
@ -181,7 +187,8 @@ void WinEDA_PcbFrame::Start_MoveOneTrackSegment(TRACK * track, wxDC * DC, bool D
/* Change hight light net: the new one will be hightlighted */
Old_HightLigt_Status = g_HightLigt_Status;
Old_HightLigth_NetCode = g_HightLigth_NetCode;
if(g_HightLigt_Status) Hight_Light(DC);
if( g_HightLigt_Status )
Hight_Light( DC );
if( Drag && track->m_StructType == TYPEVIA )
{
@ -192,7 +199,6 @@ void WinEDA_PcbFrame::Start_MoveOneTrackSegment(TRACK * track, wxDC * DC, bool D
NbPtNewTrack = 1;
PosInit = track->m_Start;
}
else
{
int diag = track->IsPointOnEnds( GetScreen()->m_Curseur, -1 );
@ -215,7 +221,6 @@ void WinEDA_PcbFrame::Start_MoveOneTrackSegment(TRACK * track, wxDC * DC, bool D
}
/**********************************************************************/
bool WinEDA_PcbFrame::PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC )
/**********************************************************************/
@ -224,19 +229,22 @@ bool WinEDA_PcbFrame::PlaceDraggedTrackSegment(TRACK * Track, wxDC * DC)
int errdrc;
DRAG_SEGM* pt_drag;
if(Track == NULL ) return FALSE;
if( Track == NULL )
return FALSE;
// DRC control:
if( Drc_On )
{
errdrc = Drc( this, DC, Track, m_Pcb->m_Track, 1 );
if(errdrc == BAD_DRC) return FALSE;
if( errdrc == BAD_DRC )
return FALSE;
/* Tracage des segments dragges */
pt_drag = g_DragSegmentList;
for( ; pt_drag; pt_drag = pt_drag->Pnext )
{
errdrc = Drc( this, DC, pt_drag->m_Segm, m_Pcb->m_Track, 1 );
if(errdrc == BAD_DRC) return FALSE;
if( errdrc == BAD_DRC )
return FALSE;
}
}
@ -253,6 +261,7 @@ DRAG_SEGM * pt_drag;
Track->m_Flags = 0;
Track->Draw( DrawPanel, DC, GR_OR );
}
EraseDragListe();
GetScreen()->SetModify();
@ -268,8 +277,9 @@ DRAG_SEGM * pt_drag;
/***********************************************/
void WinEDA_PcbFrame::Place_Dupl_Route( Track* Track, wxDC* DC )
/******************************************/
/*
Routine de placement d'une piste (succession de segments)
* Routine de placement d'une piste (succession de segments)
*/
{
D_PAD* pt_pad;
@ -281,12 +291,13 @@ wxDC * DC = Cmd->DC;
ActiveDrawPanel->ManageCurseur = NULL;
if( NewTrack == NULL ) return ;
if( NewTrack == NULL )
return;
old_net_code = NewTrack->net_code;
/* Placement du flag BUSY de la piste originelle, qui ne doit
pas etre vue dans les recherches de raccordement suivantes */
* pas etre vue dans les recherches de raccordement suivantes */
ii = NbPtNewTrack; pt_track = NewTrack;
for( ; ii > 0; ii--, pt_track = (TRACK*) pt_track->Pnext )
{
@ -313,13 +324,15 @@ wxDC * DC = Cmd->DC;
{
pt_pad = (D_PAD*) LockPoint;
new_net_code = pt_pad->net_code;
if ( new_net_code > 0 ) break;
if( new_net_code > 0 )
break;
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK*) LockPoint;
new_net_code = Track->net_code;
if ( new_net_code > 0 ) break;
if( new_net_code > 0 )
break;
}
}
LockPoint = LocateLockPoint( pt_track->m_End.x, pt_track->m_End.y, masquelayer );
@ -329,13 +342,15 @@ wxDC * DC = Cmd->DC;
{
pt_pad = (D_PAD*) LockPoint;
new_net_code = pt_pad->net_code;
if ( new_net_code > 0 ) break;
if( new_net_code > 0 )
break;
}
else /* debut de piste sur un segment de piste */
{
Track = (TRACK*) LockPoint;
new_net_code = Track->net_code;
if ( new_net_code > 0 ) break;
if( new_net_code > 0 )
break;
}
}
}
@ -354,8 +369,12 @@ wxDC * DC = Cmd->DC;
if( Drc_On == RUN )
if( drc( DC, pt_track, pt_pcb->Track, 1 ) == BAD_DRC )
{
if( confirmation(" Erreur DRC, Place piste:") == YES ) continue;
else { DRC_error = 1; break; }
if( confirmation( " Erreur DRC, Place piste:" ) == YES )
continue;
else
{
DRC_error = 1; break;
}
}
}
@ -373,6 +392,7 @@ wxDC * DC = Cmd->DC;
NextS = (TRACK*) pt_track->Pnext;
DeleteStructure( pt_track );
}
test_1_net_connexion( DC, old_net_code );
}
@ -434,7 +454,6 @@ wxDC * DC = Cmd->DC;
test_1_net_connexion( DC, new_net_code );
ActiveScreen->SetModify();
}
else /* Erreur DRC: Annulation commande */
{
DisplayOpt.DisplayPcbTrackFill = SKETCH;
@ -447,11 +466,13 @@ wxDC * DC = Cmd->DC;
PosInitX -= Track->m_Start.x; PosInitY -= Track->m_Start.y;
for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext )
{
if( Track == NULL ) break;
if( Track == NULL )
break;
Track->m_Start.x += PosInitX; Track->m_Start.y += PosInitY;
Track->m_End.x += PosInitX; Track->m_End.y += PosInitY;
Track->SetState( BUSY, OFF );
}
Trace_Une_Piste( DC, NewTrack, NbPtNewTrack, GR_OR );
}
@ -459,7 +480,8 @@ wxDC * DC = Cmd->DC;
{ /* Suppression copie */
for( ii = 0; ii < NbPtNewTrack; NewTrack = NextS )
{
if(NewTrack == NULL) break;
if( NewTrack == NULL )
break;
NextS = (TRACK*) NewTrack->Pnext;
delete NewTrack;
}
@ -467,12 +489,15 @@ wxDC * DC = Cmd->DC;
}
NewTrack = NULL;
Affiche_Infos_Status_Pcb( Cmd );
if(Etat_Surbrillance) Hight_Light(DC);
if( Etat_Surbrillance )
Hight_Light( DC );
}
/************************************************/
void WinEDA_PcbFrame::Start_CopieMove_Route( TRACK* track, wxDC* DC, bool Drag )
/************************************************/
/* Routine permettant la recopie d'une piste (suite de segments) deja tracee
*/
{
@ -481,7 +506,8 @@ TRACK *pt_segm, *pt_track;
int masquelayer = tab_layer[ActiveScreen->Active_Layer];
wxDC* DC = Cmd->DC;
if( NewTrack ) return;
if( NewTrack )
return;
FlagState = (int) Cmd->Menu->param_inf;
@ -489,7 +515,8 @@ wxDC * DC = Cmd->DC;
for( pt_segm = pt_pcb->Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
{
pt_segm = Locate_Pistes( pt_segm, masquelayer, CURSEUR_OFF_GRILLE );
if( pt_segm == NULL ) break ;
if( pt_segm == NULL )
break;
break;
}
@ -497,7 +524,8 @@ wxDC * DC = Cmd->DC;
{
if( FlagState == COPY_ROUTE )
pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, 0 );
else pt_track = Marque_Une_Piste(DC, pt_segm, &NbPtNewTrack, GR_XOR);
else
pt_track = Marque_Une_Piste( DC, pt_segm, &NbPtNewTrack, GR_XOR );
if( NbPtNewTrack ) /* Il y a NbPtNewTrack segments de piste a traiter */
{
@ -510,7 +538,8 @@ wxDC * DC = Cmd->DC;
if( FlagState == COPY_ROUTE )
NewTrack = pt_track->Copy( NbPtNewTrack );
else NewTrack = pt_track;
else
NewTrack = pt_track;
Affiche_Infos_Piste( Cmd, pt_track );
@ -532,15 +561,16 @@ wxDC * DC = Cmd->DC;
/************************************************************************/
EDA_BaseStruct* LocateLockPoint( BOARD* Pcb, wxPoint pos, int LayerMask )
/************************************************************************/
/* Routine trouvant le point " d'accrochage " d'une extremite de piste.
Ce point peut etre un PAD ou un autre segment de piste
Retourne:
- pointeur sur ce PAD ou:
- pointeur sur le segment ou:
- NULL
Parametres d'appel:
coord pX, pY du point tst
masque des couches a tester
* Ce point peut etre un PAD ou un autre segment de piste
* Retourne:
* - pointeur sur ce PAD ou:
* - pointeur sur le segment ou:
* - NULL
* Parametres d'appel:
* coord pX, pY du point tst
* masque des couches a tester
*/
{
D_PAD* pt_pad;
@ -553,7 +583,8 @@ MODULE * Module;
for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
{
pt_pad = Locate_Pads( Module, pos, LayerMask );
if (pt_pad) return(pt_pad);
if( pt_pad )
return pt_pad;
}
/* ici aucun pad n'a ete localise: detection d'un segment de piste */
@ -561,27 +592,28 @@ MODULE * Module;
ptsegm = Fast_Locate_Piste( Pcb->m_Track, NULL, pos, LayerMask );
if( ptsegm == NULL )
ptsegm = Locate_Pistes( Pcb->m_Track, pos, LayerMask );
return(ptsegm);
return ptsegm;
}
/******************************************************************************/
TRACK* CreateLockPoint( int* pX, int* pY, TRACK* ptsegm, TRACK* refsegm )
/******************************************************************************/
/* Routine de creation d'un point intermediaire sur un segment
le segment ptsegm est casse en 2 segments se raccordant au point pX, pY
retourne:
NULL si pas de nouveau point ( c.a.d si pX, pY correspondait deja
a une extremite ou:
pointeur sur le segment cree
si refsegm != NULL refsegm est pointeur sur le segment incident,
et le point cree est l'intersection des 2 axes des segments ptsegm et
refsegm
retourne la valeur exacte de pX et pY
Si ptsegm pointe sur une via:
retourne la valeur exacte de pX et pY et ptsegm,
mais ne cree pas de point supplementaire
/* Routine de creation d'un point intermediaire sur un segment
* le segment ptsegm est casse en 2 segments se raccordant au point pX, pY
* retourne:
* NULL si pas de nouveau point ( c.a.d si pX, pY correspondait deja
* a une extremite ou:
* pointeur sur le segment cree
* si refsegm != NULL refsegm est pointeur sur le segment incident,
* et le point cree est l'intersection des 2 axes des segments ptsegm et
* refsegm
* retourne la valeur exacte de pX et pY
* Si ptsegm pointe sur une via:
* retourne la valeur exacte de pX et pY et ptsegm,
* mais ne cree pas de point supplementaire
*
*/
{
int cX, cY;
@ -589,17 +621,20 @@ int dx, dy; /* Coord de l'extremite du segm ptsegm / origine */
int ox, oy, fx, fy; /* coord de refsegm / origine de prsegm */
TRACK* NewTrack;
if( (ptsegm->m_Start.x == *pX) && (ptsegm->m_Start.y == *pY) ) return(NULL);
if( (ptsegm->m_End.x == *pX) && (ptsegm->m_End.y == *pY) ) return(NULL);
if( (ptsegm->m_Start.x == *pX) && (ptsegm->m_Start.y == *pY) )
return NULL;
if( (ptsegm->m_End.x == *pX) && (ptsegm->m_End.y == *pY) )
return NULL;
/* le point n'est pas sur une extremite de piste */
if( ptsegm->m_StructType == TYPEVIA )
{
*pX = ptsegm->m_Start.x; *pY = ptsegm->m_Start.y;
return(ptsegm);
return ptsegm;
}
/* calcul des coord vraies du point intermediaire dans le repere d'origine
= origine de ptsegm */
* = origine de ptsegm */
cX = *pX - ptsegm->m_Start.x;
cY = *pY - ptsegm->m_Start.y;
dx = ptsegm->m_End.x - ptsegm->m_Start.x;
@ -615,11 +650,13 @@ TRACK * NewTrack;
}
/* pour que le point soit sur le segment ptsegm: cY/cX = dy/dx */
if ( dx == 0 ) cX = 0; /* segm horizontal */
else cY = (cX * dy) / dx;
if( dx == 0 )
cX = 0; /* segm horizontal */
else
cY = (cX * dy) / dx;
/* creation du point intermediaire ( c'est a dire creation d'un nouveau
segment, debutant au point intermediaire */
* segment, debutant au point intermediaire */
cX += ptsegm->m_Start.x; cY += ptsegm->m_Start.y;
NewTrack = ptsegm->Copy();
@ -638,8 +675,5 @@ TRACK * NewTrack;
ptsegm->SetState( BEGIN_ONPAD, OFF );
*pX = cX; *pY = cY;
return(ptsegm);
return ptsegm;
}

View File

@ -40,8 +40,9 @@ bool s_StartSegmentPresent, s_EndSegmentPresent;
/**************************************************************/
static void Abort_MoveTrack( WinEDA_DrawPanel* Panel, wxDC* DC )
/***************************************************************/
/* routine d'annulation de la commande drag, copy ou move track si une piste est en cours
de tracage, ou de sortie de l'application EDITRACK.
* de tracage, ou de sortie de l'application EDITRACK.
*/
{
TRACK* NextS;
@ -50,8 +51,10 @@ int ii;
/* Erase the current drawings */
wxPoint oldpos = Panel->GetScreen()->m_Curseur;
Panel->GetScreen()->m_Curseur = PosInit;
if ( Panel->ManageCurseur ) Panel->ManageCurseur(Panel, DC, TRUE);
if( Panel->ManageCurseur )
Panel->ManageCurseur( Panel, DC, TRUE );
Panel->GetScreen()->m_Curseur = oldpos;
g_HightLigt_Status = FALSE;
( (WinEDA_PcbFrame*) Panel->m_Parent )->DrawHightLight( DC, g_HightLigth_NetCode );
@ -62,7 +65,8 @@ int ii;
{
for( ii = 0; ii < NbPtNewTrack; ii++, NewTrack = NextS )
{
if(NewTrack == NULL) break;
if( NewTrack == NULL )
break;
NextS = (TRACK*) NewTrack->Pnext;
delete NewTrack;
}
@ -74,14 +78,15 @@ int ii;
int dy = s_LastPos.y - PosInit.y;
for( ii = 0; ii < NbPtNewTrack; ii++, Track = (TRACK*) Track->Pnext )
{
if( Track == NULL ) break;
if( Track == NULL )
break;
Track->m_Start.x -= dx;
Track->m_Start.y -= dy;
Track->m_End.x -= dx;
Track->m_End.y -= dy;
Track->m_Flags = 0;
}
Trace_Une_Piste( Panel, DC, NewTrack, NbPtNewTrack, GR_OR );
}
@ -112,6 +117,7 @@ int ii;
EraseDragListe();
}
/*************************************************************************/
static void Show_MoveNode( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/*************************************************************************/
@ -130,7 +136,8 @@ erase = TRUE;
/* erase the current moved track segments from screen */
if( erase )
{
if ( NewTrack ) Trace_Une_Piste(panel, DC, NewTrack,NbPtNewTrack,draw_mode) ;
if( NewTrack )
Trace_Une_Piste( panel, DC, NewTrack, NbPtNewTrack, draw_mode );
}
/* set the new track coordinates */
@ -158,7 +165,8 @@ erase = TRUE;
for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext )
{
Track = pt_drag->m_Segm;
if ( erase ) Track->Draw(panel, DC, draw_mode);
if( erase )
Track->Draw( panel, DC, draw_mode );
if( Track->m_Flags & STARTPOINT )
{
Track->m_Start.x += dx; Track->m_Start.y += dy;
@ -169,49 +177,50 @@ erase = TRUE;
}
Track->Draw( panel, DC, draw_mode );
}
DisplayOpt.DisplayPcbTrackFill = track_fill_copy;
}
/*************************************************************************/
static void Show_Drag_Track_Segment_With_Cte_Slope( WinEDA_DrawPanel* panel,
wxDC* DC, bool erase )
/*************************************************************************/
/* drawing the track segment movement
> s_MovingSegmentSlope slope = moving track segment slope
> s_StartSegmentSlope slope = slope of the segment connected to the start point of the moving segment
> s_EndSegmentSlope slope = slope of the segment connected to the end point of the moving segment
moved segment function :
yt=s_MovingSegmentSlope * x + s_MovingSegment_Yorg
segment connected to moved segment's start:
y1 = s_StartSegmentSlope * x + s_StartSegment_Yorg
segment connected to moved segment's end:
y2=s_EndSegmentSlope * x + s_EndSegment_Yorg
first intersection point will be located at
y1=yt ->
xi1=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_StartSegmentSlope-s_MovingSegmentSlope)
yi1=s_MovingSegmentSlope*xi1+s_MovingSegment_Yorg
or yi1=s_StartSegmentSlope*xi1+s_MovingSegment_Yorg
second intersection point
y2=yt ->
xi2=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_MovingSegmentSlope-s_MovingSegmentSlope)
yi2=s_MovingSegmentSlope*xi2+s_MovingSegment_Yorg
or yi1=s_EndSegmentSlope*xi2+s_MovingSegment_Yorg
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!! special attention to vertical segments because
!!!!! their slope=infinite
!!!!! intersection point will be calculated using the
!!!!! segment intersecting it
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Slope parametres are computed once, because they can become undetermined when moving segments
(i.e. when a segment lenght is 0) and we want keep them constant
* > s_MovingSegmentSlope slope = moving track segment slope
* > s_StartSegmentSlope slope = slope of the segment connected to the start point of the moving segment
* > s_EndSegmentSlope slope = slope of the segment connected to the end point of the moving segment
*
* moved segment function :
* yt=s_MovingSegmentSlope * x + s_MovingSegment_Yorg
*
* segment connected to moved segment's start:
* y1 = s_StartSegmentSlope * x + s_StartSegment_Yorg
*
* segment connected to moved segment's end:
* y2=s_EndSegmentSlope * x + s_EndSegment_Yorg
*
* first intersection point will be located at
* y1=yt ->
* xi1=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_StartSegmentSlope-s_MovingSegmentSlope)
* yi1=s_MovingSegmentSlope*xi1+s_MovingSegment_Yorg
* or yi1=s_StartSegmentSlope*xi1+s_MovingSegment_Yorg
*
* second intersection point
* y2=yt ->
* xi2=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_MovingSegmentSlope-s_MovingSegmentSlope)
* yi2=s_MovingSegmentSlope*xi2+s_MovingSegment_Yorg
* or yi1=s_EndSegmentSlope*xi2+s_MovingSegment_Yorg
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* !!!!! special attention to vertical segments because
* !!!!! their slope=infinite
* !!!!! intersection point will be calculated using the
* !!!!! segment intersecting it
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* Slope parametres are computed once, because they can become undetermined when moving segments
* (i.e. when a segment lenght is 0) and we want keep them constant
*/
{
@ -224,8 +233,10 @@ TRACK * Track;
DRAG_SEGM* TrackSegWrapper = g_DragSegmentList;
TRACK* tSegmentToStart = NULL, * tSegmentToEnd = NULL;
if ( TrackSegWrapper == NULL ) return;
Track = TrackSegWrapper->m_Segm; if (Track == NULL ) return;
if( TrackSegWrapper == NULL )
return;
Track = TrackSegWrapper->m_Segm; if( Track == NULL )
return;
TrackSegWrapper = TrackSegWrapper->Pnext;
if( TrackSegWrapper )
@ -244,11 +255,14 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
int draw_mode = GR_XOR | GR_SURBRILL;
/* Undraw the current moved track segments before modification*/
// if( erase )
{
Track->Draw( panel, DC, draw_mode );
if ( tSegmentToStart ) tSegmentToStart->Draw(panel, DC, draw_mode);
if ( tSegmentToEnd ) tSegmentToEnd->Draw(panel, DC, draw_mode);
if( tSegmentToStart )
tSegmentToStart->Draw( panel, DC, draw_mode );
if( tSegmentToEnd )
tSegmentToEnd->Draw( panel, DC, draw_mode );
}
/* Compute the new track segment position */
@ -256,6 +270,7 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
dx = Pos.x - s_LastPos.x;
dy = Pos.y - s_LastPos.y;
//move the line by dx and dy
tx1 = (double) (Track->m_Start.x + dx);
ty1 = (double) (Track->m_Start.y + dy);
@ -265,20 +280,31 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
// recalculate the segments new parameters and intersection points
// only the intercept will change, segment slopes does not change
// because we are moving parallel with is initial state
if (!s_MovingSegmentVertical) {
if( !s_MovingSegmentVertical )
{
s_MovingSegment_Yorg = ty1 - (s_MovingSegmentSlope * tx1);
}
if ((!s_EndPointVertical) && (!s_MovingSegmentVertical)) {
xi2 = (s_MovingSegment_Yorg - s_EndSegment_Yorg) / (s_EndSegmentSlope - s_MovingSegmentSlope);
} else {
if (!s_EndPointVertical) {
if( (!s_EndPointVertical) && (!s_MovingSegmentVertical) )
{
xi2 = (s_MovingSegment_Yorg -
s_EndSegment_Yorg) / (s_EndSegmentSlope - s_MovingSegmentSlope);
}
else
{
if( !s_EndPointVertical )
{
xi2 = tx2;
} else {
}
else
{
//P1=P2
if (!s_EndPointHorizontal) {
if( !s_EndPointHorizontal )
{
xi2 = tx2 - dx;
} else {
}
else
{
update = false;
}
}
@ -290,15 +316,18 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
}
else
{
if (!s_EndPointVertical) {
if( !s_EndPointVertical )
{
yi2 = s_EndSegmentSlope * (xi2) + s_EndSegment_Yorg;
}
else
{
if (!s_EndPointHorizontal) {
if( !s_EndPointHorizontal )
{
update = false;
}
else {
else
{
yi2 = s_MovingSegmentSlope * (xi2) + s_MovingSegment_Yorg;
}
}
@ -306,38 +335,50 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
if( (!s_StartPointVertical) && (!s_MovingSegmentVertical) )
{
xi1 = (s_MovingSegment_Yorg - s_StartSegment_Yorg) / (s_StartSegmentSlope - s_MovingSegmentSlope);
xi1 = (s_MovingSegment_Yorg -
s_StartSegment_Yorg) / (s_StartSegmentSlope - s_MovingSegmentSlope);
}
else
{
if (!s_StartPointVertical) {
if( !s_StartPointVertical )
{
xi1 = tx1;
}
else
{
//P1=P2
if (!s_StartPointHorizontal) {
if( !s_StartPointHorizontal )
{
xi1 = tx1 - dx;
}
else
{
if (!s_StartPointHorizontal) {
if( !s_StartPointHorizontal )
{
update = false;
}
}
}
}
if (!s_MovingSegmentVertical) {
if( !s_MovingSegmentVertical )
{
yi1 = s_MovingSegmentSlope * (xi1) + s_MovingSegment_Yorg;
}
else {
if (!s_StartPointVertical) {
else
{
if( !s_StartPointVertical )
{
yi1 = s_StartSegmentSlope * (xi1) + s_StartSegment_Yorg;
} else {
if (!s_StartPointHorizontal) {
}
else
{
if( !s_StartPointHorizontal )
{
update = false;
} else {
}
else
{
yi2 = s_MovingSegmentSlope * (xi1) + s_MovingSegment_Yorg;
}
}
@ -365,28 +406,33 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
{
if( tSegmentToEnd->m_Flags & STARTPOINT )
tSegmentToEnd->m_Start = Track->m_End;
else tSegmentToEnd->m_End = Track->m_End;
else
tSegmentToEnd->m_End = Track->m_End;
}
if( tSegmentToStart )
{
if( tSegmentToStart->m_Flags & STARTPOINT )
tSegmentToStart->m_Start = Track->m_Start;
else tSegmentToStart->m_End = Track->m_Start;
else
tSegmentToStart->m_End = Track->m_Start;
}
}
Track->Draw( panel, DC, draw_mode );
if ( tSegmentToStart ) tSegmentToStart->Draw(panel, DC, draw_mode);
if ( tSegmentToEnd ) tSegmentToEnd->Draw(panel, DC, draw_mode);
if( tSegmentToStart )
tSegmentToStart->Draw( panel, DC, draw_mode );
if( tSegmentToEnd )
tSegmentToEnd->Draw( panel, DC, draw_mode );
}
/**********************************/
bool InitialiseDragParameters( void )
/**********************************/
/* Init variables (slope, Y intersect point, flags) for Show_Drag_Track_Segment_With_Cte_Slope()
return TRUE if Ok, FALSE if dragging is not possible
(2 colinear segments)
* return TRUE if Ok, FALSE if dragging is not possible
* (2 colinear segments)
*/
{
double tx1, tx2, ty1, ty2; // temporary storage of points
@ -394,9 +440,11 @@ TRACK * Track;
DRAG_SEGM* TrackSegWrapper = g_DragSegmentList;
TRACK* tSegmentToStart = NULL, * tSegmentToEnd = NULL;
if ( TrackSegWrapper == NULL ) return FALSE;
if( TrackSegWrapper == NULL )
return FALSE;
Track = TrackSegWrapper->m_Segm;
if (Track == NULL ) return FALSE;
if( Track == NULL )
return FALSE;
TrackSegWrapper = TrackSegWrapper->Pnext;
if( TrackSegWrapper )
@ -447,13 +495,17 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
ty2 = (double) Track->m_End.y;
RotatePoint( &tx2, &ty2, tx1, ty1, 900 );
}
if (tx1!=tx2) {
if( tx1!=tx2 )
{
s_StartSegmentSlope = (ty2 - ty1) / (tx2 - tx1);
s_StartSegment_Yorg = ty1 - (ty2 - ty1) * tx1 / (tx2 - tx1);
} else {
}
else
{
s_StartPointVertical = true; //signal first segment vertical
}
if (ty1==ty2) {
if( ty1==ty2 )
{
s_StartPointHorizontal = true;
}
@ -486,55 +538,69 @@ TRACK * tSegmentToStart = NULL, * tSegmentToEnd = NULL;
RotatePoint( &tx2, &ty2, tx1, ty1, -900 );
}
if (tx2!=tx1) {
if( tx2!=tx1 )
{
s_EndSegmentSlope = (ty2 - ty1) / (tx2 - tx1);
s_EndSegment_Yorg = ty1 - (ty2 - ty1) * tx1 / (tx2 - tx1);
} else {
}
else
{
s_EndPointVertical = true; //signal second segment vertical
}
if (ty1==ty2) {
if( ty1==ty2 )
{
s_EndPointHorizontal = true;
}
// Init parameters for the moved segment
tx1 = (double) Track->m_Start.x;
ty1 = (double) Track->m_Start.y;
tx2 = (double) Track->m_End.x;
ty2 = (double) Track->m_End.y;
if (tx2 != tx1) {
if( tx2 != tx1 )
{
s_MovingSegmentSlope = (ty2 - ty1) / (tx2 - tx1);
} else {
}
else
{
s_MovingSegmentVertical = true; //signal vertical line
}
if (ty1==ty2) {
if( ty1==ty2 )
{
s_MovingSegmentHorizontal = true;
}
// Test if drag is possible:
if( s_MovingSegmentVertical )
{
if ( s_EndPointVertical || s_StartPointVertical ) return false;
if( s_EndPointVertical || s_StartPointVertical )
return false;
}
else
{ if ( ! s_EndPointVertical && (s_MovingSegmentSlope == s_EndSegmentSlope) ) return false;
if ( ! s_StartPointVertical && (s_MovingSegmentSlope == s_StartSegmentSlope) ) return false;
{
if( !s_EndPointVertical && (s_MovingSegmentSlope == s_EndSegmentSlope) )
return false;
if( !s_StartPointVertical && (s_MovingSegmentSlope == s_StartSegmentSlope) )
return false;
}
return TRUE;
}
/*************************************************************************************/
void WinEDA_PcbFrame::Start_MoveOneNodeOrSegment( TRACK* track, wxDC* DC, int command )
/*************************************************************************************/
/* Init parametres to move one node:
a via or/and a terminal point of a track segment
The terminal point of other connected segments (if any) are moved too.
* a via or/and a terminal point of a track segment
* The terminal point of other connected segments (if any) are moved too.
*/
{
if ( ! track ) return;
if( !track )
return;
NewTrack = NULL;
NbPtNewTrack = 0;
@ -543,7 +609,8 @@ void WinEDA_PcbFrame::Start_MoveOneNodeOrSegment(TRACK * track, wxDC * DC, int c
/* Change hight light net: the new one will be hightlighted */
Old_HightLigt_Status = g_HightLigt_Status;
Old_HightLigth_NetCode = g_HightLigth_NetCode;
if(g_HightLigt_Status) Hight_Light(DC);
if( g_HightLigt_Status )
Hight_Light( DC );
PosInit = GetScreen()->m_Curseur;
if( track->m_StructType == TYPEVIA )
@ -558,11 +625,11 @@ void WinEDA_PcbFrame::Start_MoveOneNodeOrSegment(TRACK * track, wxDC * DC, int c
NbPtNewTrack = 1;
PosInit = track->m_Start;
}
else
{
int diag = track->IsPointOnEnds( GetScreen()->m_Curseur, -1 );
wxPoint pos;
switch( command )
{
case ID_POPUP_PCB_MOVE_TRACK_SEGMENT:
@ -586,8 +653,8 @@ void WinEDA_PcbFrame::Start_MoveOneNodeOrSegment(TRACK * track, wxDC * DC, int c
track->ReturnMaskLayer(), track->m_NetCode );
PosInit = pos;
break;
}
track->m_Flags |= IS_DRAGGED;
}
s_LastPos = PosInit;
@ -601,8 +668,6 @@ void WinEDA_PcbFrame::Start_MoveOneNodeOrSegment(TRACK * track, wxDC * DC, int c
}
/***********************************************************************************/
void WinEDA_PcbFrame::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC )
/***********************************************************************************/
@ -611,27 +676,32 @@ TRACK * TrackToStartPoint = NULL;
TRACK* TrackToEndPoint = NULL;
bool error = FALSE;
if ( ! track ) return;
if( !track )
return;
s_StartSegmentPresent = s_EndSegmentPresent = TRUE;
if( (track->start == NULL) || (track->start->m_StructType == TYPETRACK) )
TrackToStartPoint = (TRACK*) Locate_Piste_Connectee( track, m_Pcb->m_Track, NULL, START );
// Test if more than one segment is connected to this point
if( TrackToStartPoint )
{
TrackToStartPoint->SetState( BUSY, ON );
if ( Locate_Piste_Connectee( track, m_Pcb->m_Track, NULL, START) ) error = TRUE;
if( Locate_Piste_Connectee( track, m_Pcb->m_Track, NULL, START ) )
error = TRUE;
TrackToStartPoint->SetState( BUSY, OFF );
}
if( (track->end == NULL) || (track->end->m_StructType == TYPETRACK) )
TrackToEndPoint = (TRACK*) Locate_Piste_Connectee( track, m_Pcb->m_Track, NULL, END );
// Test if more than one segment is connected to this point
if( TrackToEndPoint )
{
TrackToEndPoint->SetState( BUSY, ON );
if ( Locate_Piste_Connectee( track, m_Pcb->m_Track, NULL, END) ) error = TRUE;
if( Locate_Piste_Connectee( track, m_Pcb->m_Track, NULL, END ) )
error = TRUE;
TrackToEndPoint->SetState( BUSY, OFF );
}
@ -650,7 +720,8 @@ bool error = FALSE;
/* Change hight light net: the new one will be hightlighted */
Old_HightLigt_Status = g_HightLigt_Status;
Old_HightLigth_NetCode = g_HightLigth_NetCode;
if(g_HightLigt_Status) Hight_Light(DC);
if( g_HightLigt_Status )
Hight_Light( DC );
EraseDragListe();
@ -661,14 +732,16 @@ bool error = FALSE;
if( TrackToStartPoint )
{
int flag = STARTPOINT;
if ( track->m_Start != TrackToStartPoint->m_Start ) flag = ENDPOINT;
if( track->m_Start != TrackToStartPoint->m_Start )
flag = ENDPOINT;
AddSegmentToDragList( DrawPanel, DC, flag, TrackToStartPoint );
track->m_Flags |= STARTPOINT;
}
if( TrackToEndPoint )
{
int flag = STARTPOINT;
if ( track->m_End != TrackToEndPoint->m_Start ) flag = ENDPOINT;
if( track->m_End != TrackToEndPoint->m_Start )
flag = ENDPOINT;
AddSegmentToDragList( DrawPanel, DC, flag, TrackToEndPoint );
track->m_Flags |= ENDPOINT;
}
@ -702,7 +775,9 @@ bool WinEDA_PcbFrame::PlaceDraggedTrackSegment(TRACK * Track, wxDC * DC)
{
int errdrc;
DRAG_SEGM* pt_drag;
if(Track == NULL ) return FALSE;
if( Track == NULL )
return FALSE;
int current_net_code = Track->m_NetCode;
@ -710,13 +785,15 @@ int current_net_code = Track->m_NetCode;
if( Drc_On )
{
errdrc = Drc( this, DC, Track, m_Pcb->m_Track, 1 );
if(errdrc == BAD_DRC) return FALSE;
if( errdrc == BAD_DRC )
return FALSE;
/* Redraw the dragged segments */
pt_drag = g_DragSegmentList;
for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext )
{
errdrc = Drc( this, DC, pt_drag->m_Segm, m_Pcb->m_Track, 1 );
if(errdrc == BAD_DRC) return FALSE;
if( errdrc == BAD_DRC )
return FALSE;
}
}
@ -735,8 +812,9 @@ int current_net_code = Track->m_NetCode;
Track->SetState( EDIT, OFF );
Track->m_Flags = 0;
Track->Draw( DrawPanel, DC, draw_mode );
/* Test the connections modified by the move
(only pad connection must be tested, track connection will be tested by test_1_net_connexion() ) */
* (only pad connection must be tested, track connection will be tested by test_1_net_connexion() ) */
int masque_layer = g_TabOneLayerMask[Track->m_Layer];
Track->start = Fast_Locate_Pad_Connecte( m_Pcb, Track->m_Start, masque_layer );
Track->end = Fast_Locate_Pad_Connecte( m_Pcb, Track->m_End, masque_layer );
@ -748,7 +826,8 @@ int current_net_code = Track->m_NetCode;
DrawPanel->ManageCurseur = NULL;
DrawPanel->ForceCloseManageCurseur = NULL;
if ( current_net_code > 0 ) test_1_net_connexion(DC, current_net_code);
if( current_net_code > 0 )
test_1_net_connexion( DC, current_net_code );
return TRUE;
}
@ -757,15 +836,16 @@ int current_net_code = Track->m_NetCode;
/************************************************************************/
EDA_BaseStruct* LocateLockPoint( BOARD* Pcb, wxPoint pos, int LayerMask )
/************************************************************************/
/* Routine trouvant le point " d'accrochage " d'une extremite de piste.
Ce point peut etre un PAD ou un autre segment de piste
Retourne:
- pointeur sur ce PAD ou:
- pointeur sur le segment ou:
- NULL
Parametres d'appel:
coord pX, pY du point tst
masque des couches a tester
* Ce point peut etre un PAD ou un autre segment de piste
* Retourne:
* - pointeur sur ce PAD ou:
* - pointeur sur le segment ou:
* - NULL
* Parametres d'appel:
* coord pX, pY du point tst
* masque des couches a tester
*/
{
D_PAD* pt_pad;
@ -778,7 +858,8 @@ MODULE * Module;
for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
{
pt_pad = Locate_Pads( Module, pos, LayerMask );
if (pt_pad) return(pt_pad);
if( pt_pad )
return pt_pad;
}
/* ici aucun pad n'a ete localise: detection d'un segment de piste */
@ -786,27 +867,28 @@ MODULE * Module;
ptsegm = Fast_Locate_Piste( Pcb->m_Track, NULL, pos, LayerMask );
if( ptsegm == NULL )
ptsegm = Locate_Pistes( Pcb->m_Track, pos, LayerMask );
return(ptsegm);
return ptsegm;
}
/******************************************************************************/
TRACK* CreateLockPoint( int* pX, int* pY, TRACK* ptsegm, TRACK* refsegm )
/******************************************************************************/
/* Routine de creation d'un point intermediaire sur un segment
le segment ptsegm est casse en 2 segments se raccordant au point pX, pY
retourne:
NULL si pas de nouveau point ( c.a.d si pX, pY correspondait deja
a une extremite ou:
pointeur sur le segment cree
si refsegm != NULL refsegm est pointeur sur le segment incident,
et le point cree est l'intersection des 2 axes des segments ptsegm et
refsegm
retourne la valeur exacte de pX et pY
Si ptsegm pointe sur une via:
retourne la valeur exacte de pX et pY et ptsegm,
mais ne cree pas de point supplementaire
/* Routine de creation d'un point intermediaire sur un segment
* le segment ptsegm est casse en 2 segments se raccordant au point pX, pY
* retourne:
* NULL si pas de nouveau point ( c.a.d si pX, pY correspondait deja
* a une extremite ou:
* pointeur sur le segment cree
* si refsegm != NULL refsegm est pointeur sur le segment incident,
* et le point cree est l'intersection des 2 axes des segments ptsegm et
* refsegm
* retourne la valeur exacte de pX et pY
* Si ptsegm pointe sur une via:
* retourne la valeur exacte de pX et pY et ptsegm,
* mais ne cree pas de point supplementaire
*
*/
{
int cX, cY;
@ -814,17 +896,20 @@ int dx, dy; /* Coord de l'extremite du segm ptsegm / origine */
int ox, oy, fx, fy; /* coord de refsegm / origine de prsegm */
TRACK* NewTrack;
if( (ptsegm->m_Start.x == *pX) && (ptsegm->m_Start.y == *pY) ) return(NULL);
if( (ptsegm->m_End.x == *pX) && (ptsegm->m_End.y == *pY) ) return(NULL);
if( (ptsegm->m_Start.x == *pX) && (ptsegm->m_Start.y == *pY) )
return NULL;
if( (ptsegm->m_End.x == *pX) && (ptsegm->m_End.y == *pY) )
return NULL;
/* le point n'est pas sur une extremite de piste */
if( ptsegm->m_StructType == TYPEVIA )
{
*pX = ptsegm->m_Start.x; *pY = ptsegm->m_Start.y;
return(ptsegm);
return ptsegm;
}
/* calcul des coord vraies du point intermediaire dans le repere d'origine
= origine de ptsegm */
* = origine de ptsegm */
cX = *pX - ptsegm->m_Start.x;
cY = *pY - ptsegm->m_Start.y;
dx = ptsegm->m_End.x - ptsegm->m_Start.x;
@ -840,11 +925,13 @@ TRACK * NewTrack;
}
/* pour que le point soit sur le segment ptsegm: cY/cX = dy/dx */
if ( dx == 0 ) cX = 0; /* segm horizontal */
else cY = (cX * dy) / dx;
if( dx == 0 )
cX = 0; /* segm horizontal */
else
cY = (cX * dy) / dx;
/* creation du point intermediaire ( c'est a dire creation d'un nouveau
segment, debutant au point intermediaire */
* segment, debutant au point intermediaire */
cX += ptsegm->m_Start.x; cY += ptsegm->m_Start.y;
NewTrack = ptsegm->Copy();
@ -863,8 +950,5 @@ TRACK * NewTrack;
ptsegm->SetState( BEGIN_ONPAD, OFF );
*pX = cX; *pY = cY;
return(ptsegm);
return ptsegm;
}

View File

@ -19,6 +19,7 @@ enum layer_sel_id {
ID_LAYER_SELECT_TOP,
ID_LAYER_SELECT_BOTTOM,
ID_LAYER_SELECT
};
@ -34,6 +35,7 @@ private:
int m_LayerId[NB_LAYERS];
public:
// Constructor and destructor
WinEDA_SelLayerFrame( WinEDA_BasePcbFrame* parent, int default_layer,
int min_layer, int max_layer );
@ -42,9 +44,10 @@ public:
private:
void Sel_Layer( wxCommandEvent& event );
void Cancel( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
DECLARE_EVENT_TABLE()
};
/* Table des evenements pour WinEDA_SelLayerFrame */
BEGIN_EVENT_TABLE( WinEDA_SelLayerFrame, wxDialog )
EVT_BUTTON( ID_LAYER_OK, WinEDA_SelLayerFrame::Sel_Layer )
@ -52,18 +55,21 @@ BEGIN_EVENT_TABLE(WinEDA_SelLayerFrame, wxDialog)
EVT_RADIOBOX( ID_LAYER_SELECT, WinEDA_SelLayerFrame::Sel_Layer )
END_EVENT_TABLE()
/***********************************************************************************/
int WinEDA_BasePcbFrame::SelectLayer( int default_layer, int min_layer, int max_layer )
/***********************************************************************************/
/* Install the dialog box for layer selection
default_layer = Preselection
min_layer = val min de layer selectionnable (-1 si pas de val mini)
max_layer = val max de layer selectionnable (-1 si pas de val maxi)
* default_layer = Preselection
* min_layer = val min de layer selectionnable (-1 si pas de val mini)
* max_layer = val max de layer selectionnable (-1 si pas de val maxi)
*/
{
int layer;
WinEDA_SelLayerFrame* frame =
new WinEDA_SelLayerFrame( this, default_layer, min_layer, max_layer );
layer = frame->ShowModal(); frame->Destroy();
return layer;
}
@ -86,7 +92,7 @@ int LayerCount, LayerSelect = -1;
m_Parent = parent;
SetFont( *g_DialogFont );
/* Construction de la liste des couches autorisées */
/* Construction de la liste des couches autoris<69>s */
LayerCount = 0;
int Masque_Layer = g_TabAllCopperLayerMask[g_DesignSettings.m_CopperLayerCount - 1];
Masque_Layer += ALL_NO_CU_LAYERS;
@ -95,10 +101,16 @@ int LayerCount, LayerSelect = -1;
m_LayerId[ii] = 0;
if( (g_TabOneLayerMask[ii] & Masque_Layer) )
{
if ( min_layer > ii ) continue;
if ( (max_layer >= 0) && (max_layer < ii) ) break;
if( min_layer > ii )
continue;
if( (max_layer >= 0) && (max_layer < ii) )
break;
LayerList[LayerCount] = ReturnPcbLayerName( ii );
if ( ii == default_layer ) LayerSelect = LayerCount;
if( ii == default_layer )
LayerSelect = LayerCount;
m_LayerId[LayerCount] = ii;
LayerCount++;
}
@ -110,7 +122,8 @@ int LayerCount, LayerSelect = -1;
pos, wxSize( -1, -1 ), LayerCount, LayerList,
(LayerCount < 8) ? LayerCount : 8, wxRA_SPECIFY_ROWS );
if ( LayerSelect >= 0 ) m_LayerList->SetSelection(LayerSelect);
if( LayerSelect >= 0 )
m_LayerList->SetSelection( LayerSelect );
m_LayerList->GetSize( &xx, &yy );
pos.x += xx + 12;
@ -134,9 +147,11 @@ void WinEDA_SelLayerFrame::Sel_Layer(wxCommandEvent& event)
/***************************************************************/
{
int ii = m_LayerId[m_LayerList->GetSelection()];
EndModal( ii );
}
/***************************************************************/
void WinEDA_SelLayerFrame::Cancel( wxCommandEvent& event )
/***************************************************************/
@ -166,9 +181,11 @@ public:
private:
void Sel_Layer( wxCommandEvent& event );
void Cancel( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
DECLARE_EVENT_TABLE()
};
/* Table des evenements pour WinEDA_SelLayerPairFrame */
BEGIN_EVENT_TABLE( WinEDA_SelLayerPairFrame, wxDialog )
EVT_BUTTON( ID_LAYER_OK, WinEDA_SelLayerPairFrame::Sel_Layer )
@ -179,12 +196,14 @@ END_EVENT_TABLE()
/***********************************************/
void WinEDA_BasePcbFrame::SelectLayerPair( void )
/***********************************************/
/* Affiche une double liste de layers cuivre pour selection d'une paire de layers
pour autorutage, vias...
* pour autorutage, vias...
*/
{
WinEDA_SelLayerPairFrame* frame =
new WinEDA_SelLayerPairFrame( this );
frame->ShowModal(); frame->Destroy();
DrawPanel->MouseToCursorSchema();
SetToolbars();
@ -208,7 +227,7 @@ int LayerTopSelect = 0, LayerBottomSelect = 0 ;
SetFont( *g_DialogFont );
PCB_SCREEN* screen = (PCB_SCREEN*) m_Parent->m_CurrentScreen;
/* Construction de la liste des couches autorisées */
/* Construction de la liste des couches autoris<69>s */
int Masque_Layer = g_TabAllCopperLayerMask[g_DesignSettings.m_CopperLayerCount - 1];
Masque_Layer += ALL_NO_CU_LAYERS;
for( ii = 0, LayerCount = 0; ii < NB_COPPER_LAYERS; ii++ )
@ -241,13 +260,11 @@ PCB_SCREEN * screen = (PCB_SCREEN *) m_Parent->m_CurrentScreen;
m_LayerListBOTTOM->GetSize( &xx, &yy );
pos.x += xx + 12;
Button = new wxButton(this,ID_LAYER_OK,
_("OK"), pos);
Button = new wxButton( this, ID_LAYER_OK, _( "OK" ), pos );
Button->SetForegroundColour( *wxBLUE );
pos.y += Button->GetSize().y + 5;
Button = new wxButton(this,ID_LAYER_CANCEL,
_("Cancel"), pos);
Button = new wxButton( this, ID_LAYER_CANCEL, _( "Cancel" ), pos );
Button->SetForegroundColour( *wxRED );
/* Redimensionnement de la boite de dialogue: */
@ -267,11 +284,10 @@ PCB_SCREEN * screen = (PCB_SCREEN *) m_Parent->m_CurrentScreen;
EndModal( 0 );
}
/***************************************************************/
void WinEDA_SelLayerPairFrame::Cancel( wxCommandEvent& event )
/***************************************************************/
{
EndModal( -1 );
}

View File

@ -21,8 +21,9 @@ static int draw_mode ;
/*********************************************************/
void WinEDA_PcbFrame::Liste_Equipot( wxCommandEvent& event )
/*********************************************************/
/* Display a filtered list of equipot names
if an equipot is selected the corresponding tracks and pads are highlighted
* if an equipot is selected the corresponding tracks and pads are highlighted
*/
{
EQUIPOT* Equipot;
@ -32,7 +33,8 @@ int ii, jj;
msg = wxT( "*" );
Get_Message( _( "Filter for net names:" ), msg, this );
if ( msg.IsEmpty() ) return;
if( msg.IsEmpty() )
return;
List = new WinEDA_TextFrame( this, _( "List Nets" ) );
@ -41,21 +43,25 @@ int ii, jj;
{
wxString Line;
/* calcul adr relative du nom de la pastille reference de la piste */
if( ! WildCompareString(msg, Equipot->m_Netname, FALSE ) ) continue ;
if( !WildCompareString( msg, Equipot->m_Netname, FALSE ) )
continue;
Line.Printf( wxT( "net_code = %3.3d [%.16s] " ), Equipot->m_NetCode,
Equipot->m_Netname.GetData() );
List->Append( Line );
}
ii = List->ShowModal(); List->Destroy();
if (ii < 0) return;
/* Recherche du numero de net rellement selectionné */
ii = List->ShowModal(); List->Destroy();
if( ii < 0 )
return;
/* Recherche du numero de net rellement selectionn<6E>*/
Equipot = (EQUIPOT*) m_Pcb->m_Equipots;
for( jj = 0; Equipot != NULL; Equipot = (EQUIPOT*) Equipot->Pnext )
{
/* calcul adr relative du nom de la pastille reference de la piste */
if( ! WildCompareString(msg, Equipot->m_Netname, FALSE) ) continue ;
if( !WildCompareString( msg, Equipot->m_Netname, FALSE ) )
continue;
if( ii == jj )
{
ii = Equipot->m_NetCode;
@ -64,11 +70,12 @@ int ii, jj;
jj++;
}
wxClientDC dc( DrawPanel );
DrawPanel->PrepareGraphicContext( &dc );
if(g_HightLigt_Status) Hight_Light(&dc);
if( g_HightLigt_Status )
Hight_Light( &dc );
g_HightLigth_NetCode = ii;
Hight_Light( &dc );
}
@ -77,15 +84,17 @@ wxClientDC dc(DrawPanel);
/**************************************************/
int WinEDA_PcbFrame::Select_High_Light( wxDC* DC )
/**************************************************/
/* Localise track ou pad et met en surbrillance le net correspondant
Retourne le netcode, ou -1 si pas de net localisé */
* Retourne le netcode, ou -1 si pas de net localis<EFBFBD>*/
{
TRACK* pt_piste;
D_PAD* pt_pad;
int masquelayer = g_TabOneLayerMask[GetScreen()->m_Active_Layer];
int code = -1;
if ( g_HightLigt_Status ) Hight_Light(DC);
if( g_HightLigt_Status )
Hight_Light( DC );
pt_piste = Locate_Pistes( m_Pcb->m_Track, masquelayer, CURSEUR_OFF_GRILLE );
if( pt_piste )
{
@ -109,9 +118,10 @@ int code = -1;
/*******************************************/
void WinEDA_PcbFrame::Hight_Light( wxDC* DC )
/*******************************************/
/*
fonction d'appel de Surbrillance a partir du menu
Met ou supprime la surbrillance d'un net pointe par la souris
* fonction d'appel de Surbrillance a partir du menu
* Met ou supprime la surbrillance d'un net pointe par la souris
*/
{
g_HightLigt_Status = !g_HightLigt_Status;
@ -119,18 +129,20 @@ void WinEDA_PcbFrame::Hight_Light(wxDC * DC)
}
/****************************************************************/
void WinEDA_PcbFrame::DrawHightLight( wxDC* DC, int NetCode )
/****************************************************************/
/* Turn On or OFF the HightLight for trcak and pads with the netcode "NetCode'
*/
{
TRACK* pts;
MODULE* Module;
if(g_HightLigt_Status ) draw_mode = GR_SURBRILL | GR_OR;
else draw_mode = GR_AND | GR_SURBRILL;
if( g_HightLigt_Status )
draw_mode = GR_SURBRILL | GR_OR;
else
draw_mode = GR_AND | GR_SURBRILL;
Module = m_Pcb->m_Modules;
@ -168,4 +180,3 @@ D_PAD * pt_pad ;
}
}
}

View File

@ -51,7 +51,7 @@
/* Data to build the layer pair indicator button */
static wxBitmap* LayerPairBitmap = NULL;
static char s_BitmapLayerIcon[16][16] = {
static const char s_BitmapLayerIcon[16][16] = {
// 0 = draw pixel with active layer color
// 1 = draw pixel with top layer color (top/bottom layer used in autoroute and place via)
// 2 = draw pixel with bottom layer color

View File

@ -1,4 +1,5 @@
/////////////////////////////////////////////////////////////////////////////
// Name: zones.cpp
// Purpose:
// Author: jean-pierre Charras
@ -80,17 +81,29 @@ WinEDA_ZoneFrame::WinEDA_ZoneFrame( )
{
}
WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{
m_Parent = parent;
Create( parent, id, caption, pos, size, style );
}
/*!
* WinEDA_ZoneFrame creator
*/
bool WinEDA_ZoneFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
bool WinEDA_ZoneFrame::Create( wxWindow* parent,
wxWindowID id,
const wxString& caption,
const wxPoint& pos,
const wxSize& size,
long style )
{
////@begin WinEDA_ZoneFrame member initialisation
m_GridCtrl = NULL;
@ -98,6 +111,7 @@ bool WinEDA_ZoneFrame::Create( wxWindow* parent, wxWindowID id, const wxString&
m_ZoneClearanceCtrl = NULL;
m_FillOpt = NULL;
m_OrientEdgesOpt = NULL;
////@end WinEDA_ZoneFrame member initialisation
////@begin WinEDA_ZoneFrame creation
@ -108,11 +122,13 @@ bool WinEDA_ZoneFrame::Create( wxWindow* parent, wxWindowID id, const wxString&
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
Centre();
////@end WinEDA_ZoneFrame creation
return true;
}
/*!
* Control creation for WinEDA_ZoneFrame
*/
@ -132,19 +148,28 @@ void WinEDA_ZoneFrame::CreateControls()
wxBoxSizer* itemBoxSizer3 = new wxBoxSizer( wxVERTICAL );
itemBoxSizer2->Add( itemBoxSizer3, 0, wxGROW | wxALL, 5 );
wxString m_GridCtrlStrings[] = {
static const wxString m_GridCtrlStrings[] = {
_( "0.00000" ),
_( "0.00000" ),
_( "0.00000" ),
_( "0.00000" )
};
m_GridCtrl = new wxRadioBox( itemDialog1, ID_RADIOBOX, _("Grid size:"), wxDefaultPosition, wxDefaultSize, 4, m_GridCtrlStrings, 1, wxRA_SPECIFY_COLS );
m_GridCtrl = new wxRadioBox( itemDialog1, ID_RADIOBOX, _(
"Grid size:" ), wxDefaultPosition, wxDefaultSize, 4,
m_GridCtrlStrings, 1, wxRA_SPECIFY_COLS );
itemBoxSizer3->Add( m_GridCtrl, 0, wxALIGN_LEFT | wxALL, 5 );
m_ClearanceValueTitle = new wxStaticText( itemDialog1, wxID_STATIC, _("Zone clearance value (mm):"), wxDefaultPosition, wxDefaultSize, 0 );
itemBoxSizer3->Add(m_ClearanceValueTitle, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5);
m_ClearanceValueTitle = new wxStaticText( itemDialog1, wxID_STATIC,
_("Zone clearance value (mm):"),
wxDefaultPosition, wxDefaultSize, 0 );
itemBoxSizer3->Add( m_ClearanceValueTitle,
0,
wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP | wxADJUST_MINSIZE,
5 );
m_ZoneClearanceCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
m_ZoneClearanceCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL, _T(
"" ), wxDefaultPosition, wxDefaultSize, 0 );
itemBoxSizer3->Add( m_ZoneClearanceCtrl, 0, wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
itemBoxSizer2->Add( 5, 5, 0, wxGROW | wxALL, 5 );
@ -152,19 +177,27 @@ void WinEDA_ZoneFrame::CreateControls()
wxBoxSizer* itemBoxSizer8 = new wxBoxSizer( wxVERTICAL );
itemBoxSizer2->Add( itemBoxSizer8, 0, wxGROW | wxALL, 5 );
wxString m_FillOptStrings[] = {
static const wxString m_FillOptStrings[] = {
_( "Include Pads" ),
_( "Thermal" ),
_( "Exclude Pads" )
};
m_FillOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX1, _("Pad options:"), wxDefaultPosition, wxDefaultSize, 3, m_FillOptStrings, 1, wxRA_SPECIFY_COLS );
m_FillOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX1, _(
"Pad options:" ), wxDefaultPosition, wxDefaultSize, 3,
m_FillOptStrings, 1, wxRA_SPECIFY_COLS );
itemBoxSizer8->Add( m_FillOpt, 0, wxALIGN_LEFT | wxALL, 5 );
wxString m_OrientEdgesOptStrings[] = {
static const wxString m_OrientEdgesOptStrings[] = {
_( "Any" ),
_( "H , V and 45 deg" )
};
m_OrientEdgesOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX2, _("Zone edges orient:"), wxDefaultPosition, wxDefaultSize, 2, m_OrientEdgesOptStrings, 1, wxRA_SPECIFY_COLS );
m_OrientEdgesOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX2,
_("Zone edges orient:" ), wxDefaultPosition,
wxDefaultSize, 2, m_OrientEdgesOptStrings, 1,
wxRA_SPECIFY_COLS );
itemBoxSizer8->Add( m_OrientEdgesOpt, 0, wxALIGN_RIGHT | wxALL, 5 );
itemBoxSizer2->Add( 5, 5, 0, wxGROW | wxALL, 5 );
@ -172,16 +205,22 @@ void WinEDA_ZoneFrame::CreateControls()
wxBoxSizer* itemBoxSizer12 = new wxBoxSizer( wxVERTICAL );
itemBoxSizer2->Add( itemBoxSizer12, 0, wxALIGN_TOP | wxALL, 5 );
wxButton* itemButton13 = new wxButton( itemDialog1, ID_FILL_ZONE, _("Fill"), wxDefaultPosition, wxDefaultSize, 0 );
wxButton* itemButton13 = new wxButton( itemDialog1, ID_FILL_ZONE,
_("Fill"), wxDefaultPosition, wxDefaultSize, 0 );
itemButton13->SetDefault();
itemButton13->SetForegroundColour( wxColour( 204, 0, 0 ) );
itemBoxSizer12->Add( itemButton13, 0, wxGROW | wxALL, 5 );
wxButton* itemButton14 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
wxButton* itemButton14 = new wxButton( itemDialog1, wxID_CANCEL,
_("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
itemButton14->SetForegroundColour( wxColour( 0, 0, 255 ) );
itemBoxSizer12->Add( itemButton14, 0, wxGROW | wxALL, 5 );
wxButton* itemButton15 = new wxButton( itemDialog1, ID_SET_OPTIONS_ZONE, _("Update Options"), wxDefaultPosition, wxDefaultSize, 0 );
wxButton* itemButton15 = new wxButton( itemDialog1, ID_SET_OPTIONS_ZONE,
_("Update Options" ), wxDefaultPosition, wxDefaultSize, 0 );
itemButton15->SetForegroundColour( wxColour( 0, 100, 0 ) );
itemBoxSizer12->Add( itemButton15, 0, wxGROW | wxALL, 5 );
@ -196,27 +235,38 @@ wxString title = _("Zone clearance value:") + ReturnUnitSymbol(g_UnitMetric);
if( g_DesignSettings.m_ZoneClearence == 0 )
g_DesignSettings.m_ZoneClearence = g_DesignSettings.m_TrackClearence;
title = ReturnStringFromValue( g_UnitMetric, g_DesignSettings.m_ZoneClearence, m_Parent->m_InternalUnits);
title = ReturnStringFromValue( g_UnitMetric,
g_DesignSettings.m_ZoneClearence,
m_Parent->m_InternalUnits );
m_ZoneClearanceCtrl->SetValue( title );
if ( Zone_45_Only ) m_OrientEdgesOpt->SetSelection(1);
if( Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 );
static const int GridList[4] = { 50, 100, 250, 500 };
int selection = 0;
int GridList[4] = { 50,100,250,500}, selection = 0;
for( unsigned ii = 0; ii < m_GridCtrl->GetCount(); ii++ )
{
wxString msg = ReturnStringFromValue(g_UnitMetric, GridList[ii], m_Parent->m_InternalUnits);
wxString msg = ReturnStringFromValue( g_UnitMetric,
GridList[ii],
m_Parent->m_InternalUnits );
m_GridCtrl->SetString( ii, msg );
if ( g_GridRoutingSize == GridList[ii] ) selection = ii;
if( g_GridRoutingSize == GridList[ii] )
selection = ii;
}
m_GridCtrl->SetSelection( selection );
if( Zone_Exclude_Pads )
{
if ( Zone_Genere_Freins_Thermiques ) m_FillOpt->SetSelection(1);
else m_FillOpt->SetSelection(2);
if( Zone_Genere_Freins_Thermiques )
m_FillOpt->SetSelection( 1 );
else
m_FillOpt->SetSelection( 2 );
}
}
}
/*!
* Should we show tooltips?
@ -227,6 +277,7 @@ bool WinEDA_ZoneFrame::ShowToolTips()
return true;
}
/*!
* Get bitmap resources
*/
@ -237,9 +288,11 @@ wxBitmap WinEDA_ZoneFrame::GetBitmapResource( const wxString& name )
////@begin WinEDA_ZoneFrame bitmap retrieval
wxUnusedVar( name );
return wxNullBitmap;
////@end WinEDA_ZoneFrame bitmap retrieval
}
/*!
* Get icon resources
*/
@ -250,9 +303,11 @@ wxIcon WinEDA_ZoneFrame::GetIconResource( const wxString& name )
////@begin WinEDA_ZoneFrame icon retrieval
wxUnusedVar( name );
return wxNullIcon;
////@end WinEDA_ZoneFrame icon retrieval
}
/*!
* wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL
*/
@ -262,6 +317,7 @@ void WinEDA_ZoneFrame::OnCancelClick( wxCommandEvent& event )
////@begin wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame.
// Before editing this code, remove the block markers.
event.Skip();
////@end wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame.
}
@ -313,18 +369,24 @@ void WinEDA_ZoneFrame::ExecFillZone( wxCommandEvent & event)
wxString txtvalue = m_ZoneClearanceCtrl->GetValue();
g_DesignSettings.m_ZoneClearence =
ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits );
if ( m_OrientEdgesOpt->GetSelection() == 0) Zone_45_Only = FALSE;
else Zone_45_Only = TRUE;
if( m_OrientEdgesOpt->GetSelection() == 0 )
Zone_45_Only = FALSE;
else
Zone_45_Only = TRUE;
if ( event.GetId() == ID_SET_OPTIONS_ZONE ) EndModal(1);
else EndModal(0);
if( event.GetId() == ID_SET_OPTIONS_ZONE )
EndModal( 1 );
else
EndModal( 0 );
}
/**************************************************************/
void WinEDA_PcbFrame::Edit_Zone_Width( wxDC* DC, SEGZONE* Zone )
/**************************************************************/
/* Edite (change la largeur des segments) la zone Zone.
La zone est constituee des segments zones de meme TimeStamp
* La zone est constituee des segments zones de meme TimeStamp
*/
{
SEGZONE* pt_segm, * NextS;
@ -335,16 +397,22 @@ int w_tmp;
wxString Line;
wxString Msg( _( "New zone segment width: " ) );
if ( Zone == NULL ) return;
if( Zone == NULL )
return;
f_new_width = To_User_Unit( g_UnitMetric, Zone->m_Width, GetScreen()->GetInternalUnits() );
Line.Printf( wxT( "%.4f" ), f_new_width );
Msg += g_UnitMetric ? wxT( "(mm)" ) : wxT( "(\")" );
if ( Get_Message(Msg, Line, this) != 0 ) return;
if( Get_Message( Msg, Line, this ) != 0 )
return;
w_tmp = g_DesignSettings.m_CurrentTrackWidth;
Line.ToDouble( &f_new_width );
g_DesignSettings.m_CurrentTrackWidth = From_User_Unit(g_UnitMetric, f_new_width, GetScreen()->GetInternalUnits());
g_DesignSettings.m_CurrentTrackWidth = From_User_Unit( g_UnitMetric,
f_new_width, GetScreen()->GetInternalUnits() );
TimeStamp = Zone->m_TimeStamp;
@ -367,12 +435,12 @@ wxString Msg( _("New zone segment width: ") );
}
/**********************************************************/
void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* Zone )
/**********************************************************/
/* Efface la zone Zone.
La zone est constituee des segments zones de meme TimeStamp
* La zone est constituee des segments zones de meme TimeStamp
*/
{
SEGZONE* pt_segm, * NextS;
@ -409,10 +477,13 @@ EDGE_ZONE * WinEDA_PcbFrame::Del_SegmEdgeZone(wxDC * DC, EDGE_ZONE * edge_zone)
{
EDGE_ZONE* Segm, * previous_segm;
if (m_Pcb->m_CurrentLimitZone) Segm = m_Pcb->m_CurrentLimitZone;
else Segm = edge_zone;
if( m_Pcb->m_CurrentLimitZone )
Segm = m_Pcb->m_CurrentLimitZone;
else
Segm = edge_zone;
if( Segm == NULL) return NULL;
if( Segm == NULL )
return NULL;
Trace_DrawSegmentPcb( DrawPanel, DC, Segm, GR_XOR );
@ -442,8 +513,9 @@ EDGE_ZONE * Segm, * previous_segm;
/*********************************************/
void WinEDA_PcbFrame::CaptureNetName( wxDC* DC )
/*********************************************/
/* routine permettant de capturer le nom net net (netcode) d'un pad
ou d'une piste pour l'utiliser comme netcode de zone
* ou d'une piste pour l'utiliser comme netcode de zone
*/
{
D_PAD* pt_pad = 0;
@ -478,9 +550,10 @@ int netcode;
}
// Mise en surbrillance du net
if(g_HightLigt_Status) Hight_Light(DC);
g_HightLigth_NetCode = netcode;
if( g_HightLigt_Status )
Hight_Light( DC );
g_HightLigth_NetCode = netcode;
if( g_HightLigth_NetCode >= 0 )
{
Hight_Light( DC );
@ -490,11 +563,13 @@ int netcode;
Display_Zone_Netname( this );
}
/*******************************************************/
static void Display_Zone_Netname( WinEDA_PcbFrame* frame )
/*******************************************************/
/*
Affiche le net_code et le nom de net couramment selectionne
* Affiche le net_code et le nom de net couramment selectionne
*/
{
EQUIPOT* pt_equipot;
@ -506,14 +581,17 @@ wxString line;
{
for( ; pt_equipot != NULL; pt_equipot = (EQUIPOT*) pt_equipot->Pnext )
{
if( pt_equipot->m_NetCode == g_HightLigth_NetCode) break;
if( pt_equipot->m_NetCode == g_HightLigth_NetCode )
break;
}
if( pt_equipot )
{
line.Printf( wxT( "Zone: Net[%d] <%s>" ), g_HightLigth_NetCode,
pt_equipot->m_Netname.GetData() );
}
else line.Printf( wxT("Zone: NetCode[%d], Equipot not found"),
else
line.Printf( wxT( "Zone: NetCode[%d], Equipot not found" ),
g_HightLigth_NetCode );
}
@ -522,12 +600,14 @@ wxString line;
frame->Affiche_Message( line );
}
/********************************************************/
static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC )
/********************************************************/
/* routine d'annulation de la Commande Begin_Zone si une piste est en cours
de tracage, ou de sortie de l'application SEGZONES.
Appel par la touche ESC
* de tracage, ou de sortie de l'application SEGZONES.
* Appel par la touche ESC
*/
{
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
@ -544,28 +624,32 @@ WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*)Panel->m_Parent;
Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL;
pcbframe->GetScreen()->m_CurrentItem = NULL;
}
/**************************************************************/
void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw )
/**************************************************************/
/* Supprime la liste des segments constituant la frontiere courante
Libere la memoire correspondante
* Libere la memoire correspondante
*/
{
EDGE_ZONE* segment, * Next;
if( m_Pcb->m_CurrentLimitZone == NULL ) return;
if( m_Pcb->m_CurrentLimitZone == NULL )
return;
if( !IsOK( this, _( "Delete Current Zone Edges" ) ) )
return;
if ( ! IsOK(this, _("Delete Current Zone Edges")) ) return;
/* efface ancienne limite de zone */
segment = m_Pcb->m_CurrentLimitZone;
for( ; segment != NULL; segment = Next )
{
Next = (EDGE_ZONE*) segment->Pback;
if ( Redraw ) Trace_DrawSegmentPcb(DrawPanel, DC, segment,GR_XOR);
if( Redraw )
Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR );
segment->Pnext = NULL; delete segment;
}
@ -573,26 +657,29 @@ EDGE_ZONE * segment, * Next;
m_Pcb->m_CurrentLimitZone = NULL;
}
/********************************************/
EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone( void )
/********************************************/
/*
Routine d'initialisation d'un trace de Limite de Zone ou
de placement d'un point intermediaire
* Routine d'initialisation d'un trace de Limite de Zone ou
* de placement d'un point intermediaire
*/
{
EDGE_ZONE* oldedge, * newedge = NULL;
oldedge = m_Pcb->m_CurrentLimitZone;
if( (m_Pcb->m_CurrentLimitZone == NULL ) || /* debut reel du trace */
(DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */
if( (m_Pcb->m_CurrentLimitZone == NULL ) /* debut reel du trace */
|| (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */
{
m_Pcb->m_CurrentLimitZone = newedge = new EDGE_ZONE( m_Pcb );
newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED;
newedge->Pback = oldedge;
if(oldedge) oldedge->Pnext = newedge;
if( oldedge )
oldedge->Pnext = newedge;
newedge->m_Layer = GetScreen()->m_Active_Layer;
newedge->m_Width = 2; /* Largeur minimum tracable */
newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur;
@ -601,12 +688,11 @@ EDGE_ZONE * oldedge, * newedge = NULL;
DrawPanel->ManageCurseur = Show_Zone_Edge_While_MoveMouse;
DrawPanel->ForceCloseManageCurseur = Exit_Zones;
}
else /* piste en cours : les coord du point d'arrivee ont ete mises
a jour par la routine Show_Zone_Edge_While_MoveMouse*/
* a jour par la routine Show_Zone_Edge_While_MoveMouse*/
{
if( (oldedge->m_Start.x != oldedge->m_End.x) ||
(oldedge->m_Start.y != oldedge->m_End.y) )
if( (oldedge->m_Start.x != oldedge->m_End.x)
|| (oldedge->m_Start.y != oldedge->m_End.y) )
{
newedge = new EDGE_ZONE( oldedge );
newedge->Pback = oldedge;
@ -621,11 +707,13 @@ EDGE_ZONE * oldedge, * newedge = NULL;
return newedge;
}
/*********************************************/
void WinEDA_PcbFrame::End_Zone( wxDC* DC )
/*********************************************/
/*
Routine de fin de trace d'une zone (succession de segments)
* Routine de fin de trace d'une zone (succession de segments)
*/
{
EDGE_ZONE* PtLim;
@ -641,7 +729,8 @@ EDGE_ZONE * PtLim;
while( PtLim && PtLim->Pback )
{
PtLim = (EDGE_ZONE*) PtLim->Pback;
if ( PtLim->m_Flags & STARTPOINT) break;
if( PtLim->m_Flags & STARTPOINT )
break;
PtLim->m_Flags &= ~(IS_NEW | IS_MOVED);
}
@ -661,13 +750,15 @@ EDGE_ZONE * PtLim;
/******************************************************************************************/
static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
/******************************************************************************************/
/* redessin du contour de la piste lors des deplacements de la souris
*/
{
EDGE_ZONE* PtLim, * edgezone;
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent;
if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL ) return ;
if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL )
return;
/* efface ancienne position si elle a ete deja dessinee */
if( erase )
@ -689,7 +780,7 @@ WinEDA_PcbFrame * pcbframe = (WinEDA_PcbFrame *) panel->m_Parent;
/* dessin de la nouvelle piste : mise a jour du point d'arrivee */
if( Zone_45_Only )
{/* Calcul de l'extremite de la piste pour orientations permises:
horiz,vertical ou 45 degre */
* horiz,vertical ou 45 degre */
edgezone->m_End = pcbframe->GetScreen()->m_Curseur;
Calcule_Coord_Extremite_45( edgezone->m_Start.x, edgezone->m_Start.y,
&edgezone->m_End.x, &edgezone->m_End.y );
@ -710,19 +801,20 @@ WinEDA_PcbFrame * pcbframe = (WinEDA_PcbFrame *) panel->m_Parent;
/**********************************************/
void WinEDA_PcbFrame::Fill_Zone( wxDC* DC )
/**********************************************/
/*
Fonction generale de creation de zone
Un contour de zone doit exister, sinon l'ensemble du PCB est utilise
ce qui permet de creer des obstacles et donc des parties non remplies.
Le remplissage s'effectue a partir du point d'ancrage, jusque ves les limites
On place la zone sur la couche (layer) active.
"Hight Light" la zone fera partie de ce net
* Fonction generale de creation de zone
* Un contour de zone doit exister, sinon l'ensemble du PCB est utilise
*
* ce qui permet de creer des obstacles et donc des parties non remplies.
*
* Le remplissage s'effectue a partir du point d'ancrage, jusque ves les limites
*
*
* On place la zone sur la couche (layer) active.
*
*
* "Hight Light" la zone fera partie de ce net
*/
{
int ii, jj;
@ -744,7 +836,8 @@ wxString msg;
ii = frame->ShowModal(); frame->Destroy();
DrawPanel->MouseToCursorSchema();
DrawPanel->m_IgnoreMouseEvents = FALSE;
if ( ii ) return;
if( ii )
return;
g_DesignSettings.m_TrackClearence = g_DesignSettings.m_ZoneClearence;
@ -760,18 +853,25 @@ wxString msg;
s_TimeStamp = time( NULL );
/* Calcul du pas de routage fixe a 5 mils et plus */
E_scale = g_GridRoutingSize / 50 ; if (g_GridRoutingSize < 1 ) g_GridRoutingSize = 1 ;
E_scale = g_GridRoutingSize / 50; if( g_GridRoutingSize < 1 )
g_GridRoutingSize = 1;
/* calcule de Ncols et Nrow, taille de la matrice de routage */
ComputeMatriceSize( this, g_GridRoutingSize );
/* Determination de la cellule pointee par la souris */
ZoneStartFill.x = (GetScreen()->m_Curseur.x - m_Pcb->m_BoundaryBox.m_Pos.x + (g_GridRoutingSize/2) ) / g_GridRoutingSize;
ZoneStartFill.y = (GetScreen()->m_Curseur.y - m_Pcb->m_BoundaryBox.m_Pos.y + (g_GridRoutingSize/2) ) / g_GridRoutingSize;
if(ZoneStartFill.x < 0) ZoneStartFill.x = 0;
if(ZoneStartFill.x >= Ncols) ZoneStartFill.x = Ncols-1;
if(ZoneStartFill.y < 0) ZoneStartFill.y = 0;
if(ZoneStartFill.y >= Nrows) ZoneStartFill.y = Nrows-1;
ZoneStartFill.x = ( GetScreen()->m_Curseur.x - m_Pcb->m_BoundaryBox.m_Pos.x +
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
ZoneStartFill.y = ( GetScreen()->m_Curseur.y - m_Pcb->m_BoundaryBox.m_Pos.y +
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
if( ZoneStartFill.x < 0 )
ZoneStartFill.x = 0;
if( ZoneStartFill.x >= Ncols )
ZoneStartFill.x = Ncols - 1;
if( ZoneStartFill.y < 0 )
ZoneStartFill.y = 0;
if( ZoneStartFill.y >= Nrows )
ZoneStartFill.y = Nrows - 1;
/* Creation du mapping de la matrice de routage */
Nb_Sides = ONE_SIDE;
@ -792,7 +892,8 @@ wxString msg;
lay_tmp_TOP = Route_Layer_TOP;
Route_Layer_BOTTOM = Route_Layer_TOP = GetScreen()->m_Active_Layer;
lp_tmp = g_DesignSettings.m_CurrentTrackWidth; g_DesignSettings.m_CurrentTrackWidth = g_GridRoutingSize;
lp_tmp = g_DesignSettings.m_CurrentTrackWidth;
g_DesignSettings.m_CurrentTrackWidth = g_GridRoutingSize;
/* Affichage du NetName */
if( g_HightLigth_NetCode > 0 )
@ -800,22 +901,28 @@ wxString msg;
pt_equipot = GetEquipot( m_Pcb, g_HightLigth_NetCode );
if( pt_equipot == NULL )
{
if(g_HightLigth_NetCode > 0 ) DisplayError(this, wxT("Equipot Error"));
if( g_HightLigth_NetCode > 0 )
DisplayError( this, wxT( "Equipot Error" ) );
}
else msg = pt_equipot->m_Netname;
else
msg = pt_equipot->m_Netname;
}
else msg = _("No Net");
else
msg = _( "No Net" );
Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED );
/* Init des points d'accrochage possibles de la zone:
les pistes du net sont des points d'accrochage convenables*/
* les pistes du net sont des points d'accrochage convenables*/
TRACK* pt_segm = m_Pcb->m_Track;
for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext )
{
if(g_HightLigth_NetCode != pt_segm->m_NetCode) continue;
if ( pt_segm->m_Layer != GetScreen()->m_Active_Layer ) continue;
if (pt_segm->m_StructType != TYPETRACK ) continue;
if( g_HightLigth_NetCode != pt_segm->m_NetCode )
continue;
if( pt_segm->m_Layer != GetScreen()->m_Active_Layer )
continue;
if( pt_segm->m_StructType != TYPETRACK )
continue;
TraceSegmentPcb( m_Pcb, pt_segm, CELL_is_FRIEND, 0, WRITE_CELL );
}
@ -836,7 +943,6 @@ wxString msg;
TraceLignePcb( ux0, uy0, ux1, uy1, -1, HOLE | CELL_is_EDGE, WRITE_CELL );
}
OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE );
/* Marquage des cellules faisant partie de la zone*/
@ -862,18 +968,20 @@ wxString msg;
}
}
/* Maintenant, toutes les cellules candidates sont marquees */
/* Placement des cellules (pads, tracks, vias, edges pcb ou segments)
faisant des obsctacles sur la matrice de routage */
* faisant des obsctacles sur la matrice de routage */
ii = 0;
if( Zone_Exclude_Pads ) ii = FORCE_PADS;
if( Zone_Exclude_Pads )
ii = FORCE_PADS;
Affiche_1_Parametre( this, 42, wxT( "GenZone" ), wxEmptyString, RED );
PlaceCells( m_Pcb, g_HightLigth_NetCode, ii );
Affiche_1_Parametre( this, -1, wxEmptyString, _( "Ok" ), RED );
/* Trace des limites de la zone sur la matrice de routage
(a pu etre detruit par PlaceCells()) : */
* (a pu etre detruit par PlaceCells()) : */
PtLim = m_Pcb->m_CurrentLimitZone;
for( ; PtLim != NULL; PtLim = (EDGE_ZONE*) PtLim->Pback )
{
@ -885,12 +993,12 @@ wxString msg;
TraceLignePcb( ux0, uy0, ux1, uy1, -1, HOLE | CELL_is_EDGE, WRITE_CELL );
}
/* Init du point d'accrochage de la zone donné par la position souris
(a pu etre detruit par PlaceCells()) : */
* (a pu etre detruit par PlaceCells()) : */
OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE );
if(Zone_Debug) DisplayBoard(DrawPanel, DC);
if( Zone_Debug )
DisplayBoard( DrawPanel, DC );
/* Remplissage des cellules (creation effective de la zone)*/
ii = 1; jj = 1;
@ -901,12 +1009,14 @@ wxString msg;
ii = Propagation( this );
}
if(Zone_Debug) DisplayBoard(DrawPanel, DC);
if( Zone_Debug )
DisplayBoard( DrawPanel, DC );
/* Generation des segments de piste type Zone correspondants*/
if( g_HightLigth_NetCode < 0 )
Genere_Segments_Zone( this, DC, 0 );
else Genere_Segments_Zone(this, DC, g_HightLigth_NetCode);
else
Genere_Segments_Zone( this, DC, g_HightLigth_NetCode );
/* Trace des connexions type frein thermique */
g_DesignSettings.m_CurrentTrackWidth = lp_tmp;
@ -929,15 +1039,16 @@ wxString msg;
/*******************************************************************************/
static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code )
/*******************************************************************************/
/* Genere les segments de piste dans les limites de la zone a remplir
Algorithme:
procede en 2 balayages
- Gauche->droite
- Haut->Bas
Parametres:
net_code = net_code a attribuer au segment de zone
TimeStamp(global): signature temporelle d'identification
(mis en .start)
* Algorithme:
* procede en 2 balayages
* - Gauche->droite
* - Haut->Bas
* Parametres:
* net_code = net_code a attribuer au segment de zone
* TimeStamp(global): signature temporelle d'identification
* (mis en .start)
*/
{
int row, col;
@ -962,13 +1073,15 @@ wxString msg;
if( current_cell ) /* ce point doit faire partie d'un segment */
{
ux1 = (col * g_GridRoutingSize) + Xmin;
if( old_cell == 0 ) ux0 = ux1;
if( old_cell == 0 )
ux0 = ux1;
}
if( !current_cell || (col == Ncols - 1) ) /* peut etre fin d'un segment */
{
if( (old_cell) && (ux0 != ux1) )
{ /* un segment avait debute de longueur > 0 */
{
/* un segment avait debute de longueur > 0 */
pt_track = new SEGZONE( frame->m_Pcb );
pt_track->m_Layer = layer;
pt_track->m_NetCode = net_code;
@ -983,6 +1096,7 @@ wxString msg;
}
old_cell = current_cell;
}
msg.Printf( wxT( "%d" ), nbsegm );
Affiche_1_Parametre( frame, -1, wxEmptyString, msg, BROWN );
}
@ -998,12 +1112,14 @@ wxString msg;
if( current_cell ) /* ce point doit faire partie d'un segment */
{
uy1 = (row * g_GridRoutingSize) + Ymin;
if( old_cell == 0 ) uy0 = uy1;
if( old_cell == 0 )
uy0 = uy1;
}
if( !current_cell || (row == Nrows - 1) ) /* peut etre fin d'un segment */
{
if( (old_cell) && (uy0 != uy1) )
{ /* un segment avait debute de longueur > 0 */
{
/* un segment avait debute de longueur > 0 */
pt_track = new SEGZONE( frame->m_Pcb );
pt_track->m_Layer = layer;
pt_track->m_Width = g_GridRoutingSize;
@ -1018,6 +1134,7 @@ wxString msg;
}
old_cell = current_cell;
}
msg.Printf( wxT( "%d" ), nbsegm );
Affiche_1_Parametre( frame, -1, wxEmptyString, msg, BROWN );
}
@ -1027,30 +1144,32 @@ wxString msg;
/********************************************/
int Propagation( WinEDA_PcbFrame* frame )
/********************************************/
/* Determine les cellules inscrites dans les limites de la zone a remplir
Algorithme:
Si une cellule disponible a un voisin faisant partie de la zone, elle
devient elle meme partie de la zone
On procede en 4 balayages de la matrice des cellules
- Gauche->droite de Haut->bas
- Droite->gauche de Haut->bas
- Bas->Haut de Droite->gauche
- Bas->Haut de Gauche->Droite
et pour chaque balayage, on considere des 2 cellules voisines de
la cellule courants: cellule precedente sur la ligne et cellule precedente
sur la colonne.
La routine peut demander plusieurs iterations
les iterations doivent continuer juqu'a ce que la routine ne trouve plus
de cellules a modifier.
Retourne:
Nombre de cellules modifiees (c.a.d mises a la valeur CELL_is_ZONE.
/* Determine les cellules inscrites dans les limites de la zone a remplir
* Algorithme:
* Si une cellule disponible a un voisin faisant partie de la zone, elle
* devient elle meme partie de la zone
* On procede en 4 balayages de la matrice des cellules
* - Gauche->droite de Haut->bas
* - Droite->gauche de Haut->bas
* - Bas->Haut de Droite->gauche
* - Bas->Haut de Gauche->Droite
* et pour chaque balayage, on considere des 2 cellules voisines de
* la cellule courants: cellule precedente sur la ligne et cellule precedente
* sur la colonne.
*
* La routine peut demander plusieurs iterations
* les iterations doivent continuer juqu'a ce que la routine ne trouve plus
* de cellules a modifier.
* Retourne:
* Nombre de cellules modifiees (c.a.d mises a la valeur CELL_is_ZONE.
*/
{
int row, col, nn;
long current_cell, old_cell_H;
int long* pt_cell_V;
int nbpoints = 0;
#define NO_CELL_ZONE (HOLE | CELL_is_EDGE | CELL_is_ZONE)
wxString msg;
@ -1061,6 +1180,7 @@ wxString msg;
// Reservation memoire pour stockahe de 1 ligne ou une colonne de cellules
nn = MAX( Nrows, Ncols ) * sizeof(*pt_cell_V);
pt_cell_V = (long*) MyMalloc( nn );
memset( pt_cell_V, 0, nn );
for( row = 0; row < Nrows; row++ )
{
@ -1153,16 +1273,16 @@ wxString msg;
MyFree( pt_cell_V );
return(nbpoints);
return nbpoints;
}
/*****************************************************************************/
static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer )
/*****************************************************************************/
/* Generation des segments de zone de connexion zone / pad pour constitution
de freins thermiques
* de freins thermiques
*/
{
int ii, jj, Npads;
@ -1174,7 +1294,8 @@ int cX, cY, dx, dy;
int sommet[4][2];
wxString msg;
if( frame->m_Pcb->m_Zone == NULL ) return FALSE; /* pas de zone */
if( frame->m_Pcb->m_Zone == NULL )
return FALSE; /* pas de zone */
if( frame->m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* c'est une autre zone */
return FALSE;
@ -1184,12 +1305,17 @@ wxString msg;
for( ii = 0, Npads = 0; ii < frame->m_Pcb->m_NbPads; ii++, pt_liste_pad++ )
{
pt_pad = *pt_liste_pad;
/* la pastille doit etre du meme net */
if(pt_pad->m_NetCode != g_HightLigth_NetCode) continue;
if( pt_pad->m_NetCode != g_HightLigth_NetCode )
continue;
/* la pastille doit exister sur la couche */
if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 ) continue;
if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 )
continue;
Npads++;
}
msg.Printf( wxT( "%d" ), Npads );
Affiche_1_Parametre( frame, -1, wxEmptyString, msg, CYAN );
@ -1200,9 +1326,11 @@ wxString msg;
pt_pad = *pt_liste_pad;
/* la pastille doit etre du meme net */
if(pt_pad->m_NetCode != g_HightLigth_NetCode) continue;
if( pt_pad->m_NetCode != g_HightLigth_NetCode )
continue;
/* la pastille doit exister sur la couche */
if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 ) continue;
if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 )
continue;
/* traitement du pad en cours */
Npads++; msg.Printf( wxT( "%d" ), Npads );
@ -1258,7 +1386,6 @@ wxString msg;
pt_track->Draw( frame->DrawPanel, DC, GR_OR );
}
}
return TRUE;
}