1312 lines
44 KiB
C++
1312 lines
44 KiB
C++
/*****************************/
|
|
/* Localisation des elements */
|
|
/*****************************/
|
|
|
|
#include "fctsys.h"
|
|
#include "gr_basic.h"
|
|
|
|
#include "common.h"
|
|
#include "pcbnew.h"
|
|
#include "trigo.h"
|
|
#include "autorout.h"
|
|
|
|
#include "protos.h"
|
|
|
|
|
|
/* variables locales */
|
|
int ux0 , uy0 ,dx, dy, spot_cX, spot_cY; /* Variables utilisees pour
|
|
la localisation des segments */
|
|
/* fonctions locales */
|
|
EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch, int typeloc);
|
|
/**/
|
|
|
|
/* Macro de calcul de la coord de pointage selon le curseur
|
|
(ON/OFF grille) choisi
|
|
*/
|
|
#define SET_REF_POS(ref_pos) if(typeloc == CURSEUR_ON_GRILLE) \
|
|
{ ref_pos = ActiveScreen->m_Curseur;} \
|
|
else { ref_pos = ActiveScreen->m_MousePosition; }
|
|
|
|
|
|
/**
|
|
* Function IsModuleLayerVisible
|
|
* expects either of the two layers on which a module can reside, and returns
|
|
* whether that layer is visible.
|
|
* @param layer One of the two allowed layers for modules: CMP_N or CUIVRE_N
|
|
* @return bool - true if the layer is visible, else false.
|
|
*/
|
|
bool inline IsModuleLayerVisible( int layer )
|
|
{
|
|
if( layer==CMP_N )
|
|
return DisplayOpt.Show_Modules_Cmp;
|
|
|
|
else if( layer==CUIVRE_N )
|
|
return DisplayOpt.Show_Modules_Cu;
|
|
|
|
else
|
|
return true;
|
|
}
|
|
|
|
|
|
/*************************************************************/
|
|
MODULE * ReturnModule(BOARD * pcb, const wxString & reference)
|
|
/*************************************************************/
|
|
/*
|
|
Recherche d'un module par sa reference
|
|
Retourne:
|
|
un pointeur sur le module
|
|
Null si pas localisé
|
|
*/
|
|
{
|
|
MODULE * Module = pcb->m_Modules;
|
|
|
|
for( ; Module != NULL ; Module = (MODULE *) Module->Pnext )
|
|
{
|
|
if( reference.CmpNoCase(Module->m_Reference->m_Text) == 0 )
|
|
return Module;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/********************************************************/
|
|
D_PAD * ReturnPad(MODULE * module, const wxString & name)
|
|
/********************************************************/
|
|
/* Recherche d'un pad par son nom, pour le module Module
|
|
*/
|
|
{
|
|
D_PAD * pt_pad ;
|
|
wxString buf;
|
|
|
|
if( module == NULL ) return NULL;
|
|
|
|
pt_pad = module->m_Pads;
|
|
|
|
for ( ; pt_pad != NULL; pt_pad = (D_PAD*)pt_pad->Pnext )
|
|
{
|
|
pt_pad->ReturnStringPadName(buf);
|
|
if( buf.CmpNoCase(name) == 0 )
|
|
return pt_pad;
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************************************************/
|
|
EDA_BaseStruct * WinEDA_BasePcbFrame::Locate( int typeloc, int LayerSearch )
|
|
/*******************************************************************************/
|
|
/* General locate function
|
|
Display infos relatives to the item found
|
|
return a pointer to this item ( or NULL )
|
|
*/
|
|
{
|
|
TEXTE_PCB * pt_texte_pcb;
|
|
TRACK * Track , * TrackLocate ;
|
|
DRAWSEGMENT * DrawSegm;
|
|
MODULE * module;
|
|
D_PAD* pt_pad;
|
|
int masque_layer;
|
|
EDA_BaseStruct * item;
|
|
|
|
pt_texte_pcb = Locate_Texte_Pcb(m_Pcb->m_Drawings, LayerSearch, typeloc);
|
|
if(pt_texte_pcb ) // a PCB text is found
|
|
{
|
|
Affiche_Infos_PCB_Texte(this, pt_texte_pcb);
|
|
return pt_texte_pcb;
|
|
}
|
|
|
|
if ( (DrawSegm = Locate_Segment_Pcb(m_Pcb, LayerSearch, typeloc)) != NULL)
|
|
{
|
|
Affiche_Infos_DrawSegment(this, DrawSegm);
|
|
return DrawSegm;
|
|
}
|
|
|
|
if ( (item = Locate_Cotation(m_Pcb, LayerSearch, typeloc)) != NULL) return item;
|
|
|
|
if ( (item = Locate_MirePcb(m_Pcb->m_Drawings, LayerSearch, typeloc)) != NULL) return item;
|
|
|
|
/* Search for tracks and vias, with via priority */
|
|
if ( LayerSearch == -1 ) masque_layer = ALL_LAYERS;
|
|
else masque_layer = g_TabOneLayerMask[LayerSearch];
|
|
Track = Locate_Pistes( m_Pcb->m_Track, masque_layer,typeloc );
|
|
if ( Track != NULL )
|
|
{
|
|
TrackLocate = Track ; /* a track or a via is found*/
|
|
/* Search for a via */
|
|
while((TrackLocate = Locate_Pistes(TrackLocate,
|
|
masque_layer,typeloc)) != NULL )
|
|
{
|
|
Track = TrackLocate;
|
|
if(TrackLocate->m_StructType == TYPEVIA) break ;
|
|
TrackLocate = (TRACK*) TrackLocate->Pnext;
|
|
}
|
|
Affiche_Infos_Piste(this, Track) ;
|
|
return Track;
|
|
}
|
|
|
|
|
|
/* Search for Pads */
|
|
if( (pt_pad = Locate_Any_Pad(m_Pcb, typeloc)) != NULL )
|
|
{
|
|
pt_pad->Display_Infos(this); return pt_pad;
|
|
}
|
|
|
|
/* Search for a footprint text */
|
|
// First search: locate texts for footprints on copper or component layer
|
|
// Priority to the active layer (component or copper.
|
|
// this is useful for small smd components when 2 texts overlap but are not on the same layer
|
|
if ( (LayerSearch == LAYER_CUIVRE_N) || (LayerSearch == CMP_N ))
|
|
{
|
|
for (module = m_Pcb->m_Modules; module != NULL; module = (MODULE*)module->Pnext)
|
|
{
|
|
TEXTE_MODULE * pt_texte;
|
|
if ( module->m_Layer != LayerSearch) continue;
|
|
pt_texte = LocateTexteModule(m_Pcb, &module, typeloc | VISIBLE_ONLY);
|
|
if( pt_texte != NULL )
|
|
{
|
|
Affiche_Infos_E_Texte(this, module, pt_texte);
|
|
return pt_texte;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now Search footprint texts on all layers
|
|
module = NULL;
|
|
{
|
|
TEXTE_MODULE * pt_texte;
|
|
pt_texte = LocateTexteModule(m_Pcb, &module, typeloc | VISIBLE_ONLY);
|
|
if( pt_texte != NULL )
|
|
{
|
|
Affiche_Infos_E_Texte(this, module, pt_texte);
|
|
return pt_texte;
|
|
}
|
|
}
|
|
|
|
/* Search for a footprint */
|
|
if ( (module = Locate_Prefered_Module(m_Pcb, typeloc | VISIBLE_ONLY)) != NULL)
|
|
{
|
|
module->Display_Infos(this);
|
|
return module;
|
|
}
|
|
|
|
/* Search for zones */
|
|
if( (TrackLocate = Locate_Zone((TRACK*)m_Pcb->m_Zone,
|
|
GetScreen()->m_Active_Layer,typeloc)) != NULL )
|
|
{
|
|
Affiche_Infos_Piste(this, TrackLocate) ; return TrackLocate;
|
|
}
|
|
|
|
MsgPanel->EraseMsgBox();
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*******************************************************************/
|
|
TRACK * Locate_Via(BOARD * Pcb, const wxPoint & pos, int layer)
|
|
/*******************************************************************/
|
|
|
|
/* Localise une via au point pX,pY
|
|
Si layer < 0 la via sera localisee quelle que soit la couche
|
|
Si layer = 0 .. 15 la via sera localisee selon son type:
|
|
- traversante : toutes couches
|
|
- aveugle = entre couches utiles
|
|
- borgnes idem
|
|
Entree : coord du point de reference, couche
|
|
Sortie: NULL si pas de via
|
|
(TRACK*) adresse de la via
|
|
*/
|
|
{
|
|
TRACK * Track;
|
|
|
|
for(Track = Pcb->m_Track; Track != NULL; Track = Track->Next())
|
|
{
|
|
if( Track->m_StructType != TYPEVIA) continue;
|
|
if( Track->m_Start != pos) continue;
|
|
if( Track->GetState(BUSY|DELETED) ) continue;
|
|
if(layer < 0 ) return(Track);
|
|
if ( ((SEGVIA *)Track)->IsViaOnLayer(layer) )
|
|
return(Track);
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/********************************************************************/
|
|
D_PAD * Locate_Pad_Connecte(BOARD * Pcb, TRACK * ptr_piste, int extr)
|
|
/********************************************************************/
|
|
/* localisation de la pastille connectee au point de piste a tester
|
|
entree : ptr_piste: pointeur sur le segment de piste
|
|
extr = flag = START -> debut du segment a tester
|
|
= END -> fin du segment a tester
|
|
retourne:
|
|
un pointeur sur la description de la pastille si localisation
|
|
pointeur NULL si pastille non trouvee
|
|
*/
|
|
{
|
|
D_PAD * ptr_pad = NULL;
|
|
int masque_layer;
|
|
MODULE * module;
|
|
wxPoint ref_pos;
|
|
|
|
masque_layer = g_TabOneLayerMask[ptr_piste->m_Layer];
|
|
if( extr == START)
|
|
{
|
|
ref_pos = ptr_piste->m_Start;
|
|
}
|
|
else
|
|
{
|
|
ref_pos = ptr_piste->m_End;
|
|
}
|
|
module = Pcb->m_Modules;
|
|
for(; module != NULL; module = (MODULE*) module->Pnext)
|
|
{
|
|
ptr_pad = Locate_Pads(module, ref_pos, masque_layer) ;
|
|
if ( ptr_pad != NULL ) break ;
|
|
}
|
|
return(ptr_pad);
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************/
|
|
EDGE_MODULE * Locate_Edge_Module(MODULE * module, int typeloc)
|
|
/****************************************************************/
|
|
/* Localisation de segments de contour du type edge MODULE
|
|
Les contours sont de differents type:
|
|
simple : succession de droites
|
|
Arcs de cercles : on a alors debut arc, fin arc , centre
|
|
si debut arc = fin arc : cercle complet
|
|
|
|
Retourne:
|
|
Pointeur sur le segment localise
|
|
NULL si rien trouve
|
|
*/
|
|
{
|
|
EDGE_MODULE * edge_mod;
|
|
EDA_BaseStruct * PtStruct;
|
|
int uxf, uyf, type_trace;
|
|
int rayon, dist;
|
|
wxPoint ref_pos; /* coord du point de localisation */
|
|
int StAngle, EndAngle, MouseAngle; /* pour localisation d'arcs,
|
|
angle du point de debut, de fin et du point
|
|
de reference */
|
|
|
|
if ( ! module ) return NULL;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
PtStruct = module->m_Drawings;
|
|
for ( ;PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
|
{
|
|
if( PtStruct->m_StructType != TYPEEDGEMODULE ) continue;
|
|
edge_mod = (EDGE_MODULE *) PtStruct;
|
|
type_trace = edge_mod->m_Shape ;
|
|
ux0 = edge_mod->m_Start.x; uy0 = edge_mod->m_Start.y;
|
|
uxf = edge_mod->m_End.x; uyf = edge_mod->m_End.y;
|
|
|
|
switch(type_trace)
|
|
{
|
|
case S_SEGMENT :
|
|
/* recalcul des coordonnees avec ux0,uy0 = origine des coord. */
|
|
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
|
|
dx = uxf - ux0 ; dy = uyf - uy0 ;
|
|
/* detection : */
|
|
if( distance(edge_mod->m_Width/2) ) return( edge_mod) ;
|
|
break;
|
|
|
|
case S_CIRCLE:
|
|
rayon = (int)hypot((double)(uxf-ux0),(double)(uyf-uy0) );
|
|
dist = (int)hypot((double)(ref_pos.x - ux0),(double)(ref_pos.y - uy0) );
|
|
|
|
if(abs(rayon-dist) <= edge_mod->m_Width) return(edge_mod);
|
|
break;
|
|
|
|
case S_ARC:
|
|
rayon = (int)hypot((double)(uxf-ux0),(double)(uyf-uy0) );
|
|
dist = (int)hypot((double)(ref_pos.x - ux0),(double)(ref_pos.y - uy0) );
|
|
|
|
if(abs(rayon-dist) > edge_mod->m_Width) break;
|
|
|
|
/* pour un arc, controle complementaire */
|
|
MouseAngle = (int) ArcTangente(ref_pos.y - uy0, ref_pos.x - ux0);
|
|
StAngle = (int) ArcTangente(uyf - uy0, uxf - ux0);
|
|
EndAngle = StAngle + edge_mod->m_Angle;
|
|
|
|
if( EndAngle > 3600 )
|
|
{
|
|
StAngle -= 3600; EndAngle -= 3600;
|
|
}
|
|
|
|
if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) )
|
|
return(edge_mod);
|
|
|
|
break;
|
|
}
|
|
}
|
|
return(NULL) ;
|
|
}
|
|
|
|
|
|
/*************************************************************************/
|
|
EDA_BaseStruct * Locate_Cotation(BOARD * Pcb, int LayerSearch, int typeloc)
|
|
/*************************************************************************/
|
|
/* Serach for a cotation item , on LayerSearch,
|
|
(if LayerSearch == -1 , no yaere restriction )
|
|
return a pointer to the located item, or NULL
|
|
*/
|
|
{
|
|
EDA_BaseStruct * PtStruct;
|
|
COTATION * Cotation;
|
|
TEXTE_PCB* pt_txt;
|
|
wxPoint ref_pos;
|
|
int ux0, uy0;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
PtStruct = Pcb->m_Drawings;
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
|
{
|
|
if( PtStruct->m_StructType != TYPECOTATION ) continue;
|
|
Cotation = (COTATION*) PtStruct;
|
|
if( (Cotation->m_Layer != LayerSearch) && (LayerSearch != -1) )
|
|
continue;
|
|
|
|
/* Localisation du texte ? */
|
|
pt_txt = Cotation->m_Text;
|
|
if( pt_txt )
|
|
{
|
|
if( pt_txt->Locate(ref_pos) ) return(PtStruct);
|
|
}
|
|
|
|
/* Localisation des SEGMENTS ?) */
|
|
ux0 = Cotation->Barre_ox ; uy0 = Cotation->Barre_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx =Cotation->Barre_fx - ux0 ; dy = Cotation->Barre_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
|
|
ux0 = Cotation->TraitG_ox ; uy0 = Cotation->TraitG_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = Cotation->TraitG_fx - ux0 ; dy = Cotation->TraitG_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
|
|
ux0 = Cotation->TraitD_ox ; uy0 = Cotation->TraitD_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = Cotation->TraitD_fx - ux0 ; dy = Cotation->TraitD_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
|
|
ux0 = Cotation->FlecheD1_ox ; uy0 = Cotation->FlecheD1_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = Cotation->FlecheD1_fx - ux0 ; dy = Cotation->FlecheD1_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
|
|
ux0 = Cotation->FlecheD2_ox ; uy0 = Cotation->FlecheD2_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = Cotation->FlecheD2_fx - ux0 ; dy = Cotation->FlecheD2_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
|
|
ux0 = Cotation->FlecheG1_ox ; uy0 = Cotation->FlecheG1_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = Cotation->FlecheG1_fx - ux0 ; dy = Cotation->FlecheG1_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
|
|
ux0 = Cotation->FlecheG2_ox ; uy0 = Cotation->FlecheG2_oy;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = Cotation->FlecheG2_fx - ux0 ; dy = Cotation->FlecheG2_fy - uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( distance( Cotation->m_Width/2 )) return( PtStruct );
|
|
}
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
DRAWSEGMENT * Locate_Segment_Pcb(BOARD * Pcb, int LayerSearch, int typeloc)
|
|
/*************************************************************************/
|
|
/* Localisation de segments de contour du type drawing
|
|
Retourne:
|
|
Pointeur sur DEBUT du segment localise
|
|
NULL si rien trouve
|
|
Le segment sur la couche active est détecté en priorite
|
|
*/
|
|
{
|
|
EDA_BaseStruct * PtStruct;
|
|
DRAWSEGMENT * pts, *locate_segm = NULL;
|
|
wxPoint ref_pos;
|
|
PCB_SCREEN *screen = (PCB_SCREEN *)ActiveScreen;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
PtStruct = Pcb->m_Drawings;
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
|
{
|
|
if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue;
|
|
pts = ( DRAWSEGMENT * ) PtStruct;
|
|
if ( (pts->m_Layer != LayerSearch) && (LayerSearch != -1) )
|
|
continue;
|
|
ux0 = pts->m_Start.x ; uy0 = pts->m_Start.y;
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx = pts->m_End.x - ux0 ; dy = pts->m_End.y - uy0 ;
|
|
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
/* detection : */
|
|
if( (pts->m_Shape == S_CIRCLE) || (pts->m_Shape == S_ARC) )
|
|
{
|
|
int rayon, dist, StAngle, EndAngle, MouseAngle;
|
|
rayon = (int) hypot((double)(dx),(double)(dy) );
|
|
dist = (int) hypot((double)(spot_cX),(double)(spot_cY) );
|
|
if( abs(rayon-dist) <= (pts->m_Width/2) )
|
|
{
|
|
if(pts->m_Shape == S_CIRCLE)
|
|
{
|
|
if(pts->m_Layer == screen->m_Active_Layer)
|
|
return( pts ) ;
|
|
else if ( ! locate_segm ) locate_segm = pts;
|
|
}
|
|
/* pour un arc, controle complementaire */
|
|
MouseAngle = (int) ArcTangente(spot_cY, spot_cX);
|
|
StAngle = (int) ArcTangente(dy, dx);
|
|
EndAngle = StAngle + pts->m_Angle;
|
|
|
|
if( EndAngle > 3600 )
|
|
{
|
|
StAngle -= 3600; EndAngle -= 3600;
|
|
}
|
|
if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) )
|
|
{
|
|
if(pts->m_Layer == screen->m_Active_Layer)
|
|
return( pts ) ;
|
|
else if ( ! locate_segm ) locate_segm = pts;
|
|
}
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
if( distance( pts->m_Width /2 ) )
|
|
{
|
|
if(pts->m_Layer == screen->m_Active_Layer)
|
|
return( pts ) ;
|
|
else if ( ! locate_segm ) locate_segm = pts;
|
|
}
|
|
}
|
|
}
|
|
return(locate_segm) ;
|
|
}
|
|
|
|
|
|
/*************************************************/
|
|
/* 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
|
|
par la souris, recherche faite sur toutes les empreintes.
|
|
entree :
|
|
- coord souris
|
|
ou ref_pos
|
|
retourne:
|
|
pointeur sur la description de la pastille si localisation
|
|
pointeur NULL si pastille non trouvee
|
|
num_empr = numero d'empreinte du pad
|
|
|
|
la priorité est donnée a la couche active
|
|
*/
|
|
|
|
D_PAD * Locate_Any_Pad(BOARD * Pcb, int typeloc, bool OnlyCurrentLayer)
|
|
{
|
|
wxPoint ref_pos;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
return(Locate_Any_Pad(Pcb, ref_pos, OnlyCurrentLayer)) ;
|
|
}
|
|
|
|
D_PAD * Locate_Any_Pad(BOARD * Pcb, const wxPoint & ref_pos, bool OnlyCurrentLayer)
|
|
{
|
|
D_PAD * pt_pad ;
|
|
MODULE * module;
|
|
int layer_mask = g_TabOneLayerMask[ ((PCB_SCREEN*)ActiveScreen)->m_Active_Layer];
|
|
module = Pcb->m_Modules;
|
|
for( ; module != NULL ; module = (MODULE *) module->Pnext )
|
|
{
|
|
/* First: Search a pad on the active layer: */
|
|
if ( (pt_pad = Locate_Pads(module, ref_pos,layer_mask) ) != NULL )
|
|
return(pt_pad) ;
|
|
|
|
/* If not found, search on other layers: */
|
|
if ( ! OnlyCurrentLayer )
|
|
{
|
|
if ( (pt_pad = Locate_Pads(module, ref_pos,ALL_LAYERS) ) != NULL )
|
|
return(pt_pad) ;
|
|
}
|
|
}
|
|
return(NULL) ;
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
/* D_PAD* Locate_Pads(MODULE * module, int masque_layer,int typeloc) */
|
|
/* D_PAD* Locate_Pads(MODULE * module, const wxPoint & ref_pos,int masque_layer) */
|
|
/******************************************************************************/
|
|
|
|
/* localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
|
|
par la souris, concernant l'empreinte en cours.
|
|
entree :
|
|
- parametres generaux de l'empreinte mise a jour par caract()
|
|
- masque_layer = couche(s) (bit_masque)sur laquelle doit etre la pastille
|
|
retourne:
|
|
un pointeur sur la description de la pastille si localisation
|
|
pointeur NULL si pastille non trouvee
|
|
*/
|
|
|
|
D_PAD * Locate_Pads(MODULE * module, int masque_layer,int typeloc)
|
|
{
|
|
wxPoint ref_pos;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
return(Locate_Pads(module, ref_pos, masque_layer) );
|
|
}
|
|
|
|
|
|
D_PAD * Locate_Pads(MODULE * module, const wxPoint & ref_pos, int masque_layer)
|
|
{
|
|
D_PAD * pt_pad ;
|
|
int deltaX, deltaY;
|
|
wxPoint shape_pos;
|
|
double dist;
|
|
|
|
pt_pad = module->m_Pads;
|
|
for ( ; pt_pad != NULL; pt_pad = (D_PAD*)pt_pad->Pnext )
|
|
{
|
|
shape_pos = pt_pad->ReturnShapePos();
|
|
ux0 = shape_pos.x; uy0 = shape_pos.y; /* pos x,y du centre du pad */
|
|
|
|
deltaX = ref_pos.x - ux0; deltaY = ref_pos.y - uy0;
|
|
|
|
/* Test rapide: le point a tester doit etre a l'interieur du cercle
|
|
exinscrit ... */
|
|
if ( (abs(deltaX) > pt_pad->m_Rayon ) ||
|
|
(abs(deltaY) > pt_pad->m_Rayon) )
|
|
continue;
|
|
|
|
/* ... et sur la bonne couche */
|
|
if( (pt_pad->m_Masque_Layer & masque_layer) == 0) continue ;
|
|
|
|
/* calcul des demi dim dx et dy */
|
|
dx = pt_pad->m_Size.x >> 1; // dx also is the radius for rounded pads
|
|
dy = pt_pad->m_Size.y >> 1;
|
|
|
|
/* localisation ? */
|
|
switch (pt_pad->m_PadShape & 0x7F)
|
|
{
|
|
case CIRCLE :
|
|
dist = hypot(deltaX, deltaY);
|
|
if ( (int)(round(dist)) <= dx ) return(pt_pad) ;
|
|
break;
|
|
|
|
default:
|
|
/* calcul des coord du point test dans le repere du Pad */
|
|
RotatePoint(&deltaX, &deltaY, - pt_pad->m_Orient);
|
|
if ( (abs(deltaX) <= dx ) && (abs(deltaY) <= dy) )
|
|
return(pt_pad) ;
|
|
break;
|
|
}
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/********************************************************/
|
|
MODULE * Locate_Prefered_Module(BOARD * Pcb, int typeloc)
|
|
/********************************************************/
|
|
/*
|
|
localisation d'une empreinte par son rectangle d'encadrement
|
|
Si plusieurs empreintes sont possibles, la priorite est:
|
|
- sur la couche active
|
|
- la plus petite
|
|
*/
|
|
{
|
|
MODULE* pt_module;
|
|
int lx, ly; /* dimensions du rectangle d'encadrement du module */
|
|
MODULE* module = NULL; /* module localise sur la couche active */
|
|
MODULE* Altmodule = NULL; /* module localise sur les couches non actives */
|
|
int min_dim = 0x7FFFFFFF; /* dim mini du module localise sur la couche active */
|
|
int alt_min_dim = 0x7FFFFFFF; /* dim mini du module localise sur les couches non actives */
|
|
int layer; /* pour calcul de couches prioritaires */
|
|
wxPoint ref_pos; /* coord du point de reference pour la localisation */
|
|
|
|
SET_REF_POS(ref_pos);
|
|
pt_module = Pcb->m_Modules;
|
|
for( ; pt_module; pt_module = (MODULE*) pt_module->Pnext )
|
|
{
|
|
/* calcul des dimensions du cadre :*/
|
|
lx = pt_module->m_BoundaryBox.GetWidth();
|
|
ly = pt_module->m_BoundaryBox.GetHeight();
|
|
|
|
/* Calcul des coord souris dans le repere module */
|
|
spot_cX = ref_pos.x - pt_module->m_Pos.x;
|
|
spot_cY = ref_pos.y - pt_module->m_Pos.y;
|
|
RotatePoint(&spot_cX, &spot_cY, - pt_module->m_Orient);
|
|
|
|
/* la souris est-elle dans ce rectangle : */
|
|
if( ! pt_module->m_BoundaryBox.Inside(spot_cX, spot_cY) )
|
|
continue;
|
|
|
|
// if caller wants to ignore locked modules, and this one is locked, skip it.
|
|
if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() )
|
|
continue;
|
|
|
|
/* Localisation: test des dimensions minimales, choix du meilleur candidat */
|
|
|
|
/* calcul de priorite: la priorite est donnee a la couche
|
|
d'appartenance du module et a la couche cuivre si le module
|
|
est sur couche serigr,adhesive cuivre, a la couche cmp si le module
|
|
est sur couche serigr,adhesive composant */
|
|
layer = pt_module->m_Layer;
|
|
|
|
if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU )
|
|
layer = CUIVRE_N;
|
|
|
|
else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
|
|
layer = CMP_N;
|
|
|
|
if( ((PCB_SCREEN*)ActiveScreen)->m_Active_Layer == layer )
|
|
{
|
|
if( min(lx,ly) <= min_dim )
|
|
{
|
|
/* meilleure empreinte localisee sur couche active */
|
|
module = pt_module ; min_dim = min(lx,ly) ;
|
|
}
|
|
}
|
|
|
|
else if( !(typeloc & MATCH_LAYER)
|
|
&& ( !(typeloc & VISIBLE_ONLY) || IsModuleLayerVisible( layer )) )
|
|
{
|
|
if( min(lx,ly) <= alt_min_dim )
|
|
{
|
|
/* meilleure empreinte localisee sur autres couches */
|
|
Altmodule = pt_module;
|
|
alt_min_dim = min(lx,ly);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( module )
|
|
{
|
|
return module;
|
|
}
|
|
|
|
if( Altmodule )
|
|
{
|
|
return Altmodule;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
TEXTE_MODULE * LocateTexteModule(BOARD * Pcb, MODULE ** PtModule, int typeloc)
|
|
/*****************************************************************************/
|
|
/* localisation du texte pointe par la souris (texte sur empreinte)
|
|
|
|
si * PtModule == NULL; recherche sur tous les modules
|
|
sinon sur le module pointe par module
|
|
|
|
retourne
|
|
- pointeur sur le texte localise ( ou NULL )
|
|
- si Ptmodule != NULL: pointeur sur module module ( non modifie sinon )
|
|
|
|
if typeloc bas the flag VISIBLE_ONLY set, only footprints which are "visible" are considered
|
|
*/
|
|
{
|
|
EDA_BaseStruct * PtStruct;
|
|
TEXTE_MODULE * pt_txt_mod ;
|
|
MODULE * module;
|
|
wxPoint ref_pos;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
module = * PtModule;
|
|
if( module == NULL )
|
|
{
|
|
module = Pcb->m_Modules;
|
|
}
|
|
|
|
for( ; module != NULL; module = (MODULE*)module->Pnext )
|
|
{
|
|
if ( (typeloc & VISIBLE_ONLY) )
|
|
{
|
|
int layer = module->m_Layer;
|
|
if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU ) layer = CUIVRE_N;
|
|
else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP ) layer = CMP_N;
|
|
if ( ! IsModuleLayerVisible( layer ) ) continue;
|
|
}
|
|
pt_txt_mod = module->m_Reference;
|
|
/* la souris est-elle dans le rectangle autour du texte*/
|
|
if( pt_txt_mod->Locate(ref_pos) )
|
|
{
|
|
if( PtModule) *PtModule = module;
|
|
return(pt_txt_mod);
|
|
}
|
|
pt_txt_mod = module->m_Value;
|
|
/* la souris est-elle dans le rectangle autour du texte*/
|
|
if( pt_txt_mod->Locate(ref_pos) )
|
|
{
|
|
if( PtModule) *PtModule = module;
|
|
return(pt_txt_mod);
|
|
}
|
|
|
|
PtStruct = module->m_Drawings;
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
|
{
|
|
if( PtStruct->m_StructType != TYPETEXTEMODULE ) continue;
|
|
pt_txt_mod = (TEXTE_MODULE*) PtStruct;
|
|
/* la souris est-elle dans le rectangle autour du texte*/
|
|
if( pt_txt_mod->Locate(ref_pos) )
|
|
{
|
|
if( PtModule) *PtModule = module;
|
|
return(pt_txt_mod);
|
|
}
|
|
}
|
|
if( *PtModule != NULL ) break; /* Recherche limitee a 1 seul module */
|
|
}
|
|
return(NULL) ;
|
|
}
|
|
|
|
|
|
/**************************************************************/
|
|
TRACK * Locate_Piste_Connectee( TRACK * PtRefSegm, TRACK * pt_base,
|
|
TRACK * pt_lim, int extr)
|
|
/**************************************************************/
|
|
/* recherche le segment connecte au segment pointe par
|
|
PtRefSegm:
|
|
si int extr = START, le point de debut du segment est utilise
|
|
si int extr = END, le point de fin du segment est utilise
|
|
La recherche ne se fait que sur les EXTREMITES des segments
|
|
|
|
La recherche se fait de l'adresse :
|
|
pt_base a pt_lim (borne finale comprise)
|
|
si pt_lim = NULL, la recherche se fait jusqu'a la fin de la liste
|
|
Afin d'accelerer la recherche, une 1ere passe est faite, avec une recherche
|
|
realisee sur un ensemble de +/- 100 points autour du point courant.
|
|
Si echec: recherche generale
|
|
*/
|
|
{
|
|
TRACK * PtSegmB, * PtSegmN;
|
|
int Reflayer;
|
|
wxPoint pos_ref;
|
|
int ii;
|
|
|
|
if ( extr == START) pos_ref = PtRefSegm->m_Start;
|
|
else pos_ref = PtRefSegm->m_End;
|
|
|
|
Reflayer = PtRefSegm->ReturnMaskLayer();
|
|
|
|
/* 1ere passe */
|
|
PtSegmB = PtSegmN = PtRefSegm;
|
|
|
|
for ( ii = 0; ii < 50; ii++ )
|
|
{
|
|
if( (PtSegmN == NULL) && (PtSegmB == NULL) ) break;
|
|
if( PtSegmN )
|
|
{
|
|
if( PtSegmN->GetState(BUSY|DELETED) ) goto suite;
|
|
if (PtSegmN == PtRefSegm) goto suite;
|
|
if( pos_ref == PtSegmN->m_Start )
|
|
{ /* Test des couches */
|
|
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
|
|
}
|
|
|
|
if( pos_ref == PtSegmN->m_End )
|
|
{ /* Test des couches */
|
|
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
|
|
}
|
|
suite:
|
|
if( PtSegmN == pt_lim ) PtSegmN = NULL;
|
|
else PtSegmN = (TRACK*)PtSegmN->Pnext;
|
|
}
|
|
|
|
if( PtSegmB )
|
|
{
|
|
if(PtSegmB->GetState(BUSY|DELETED) ) goto suite1;
|
|
if (PtSegmB == PtRefSegm) goto suite1;
|
|
if( pos_ref == PtSegmB->m_Start )
|
|
{ /* Test des couches */
|
|
if(Reflayer & PtSegmB->ReturnMaskLayer() )return(PtSegmB);
|
|
}
|
|
|
|
if( pos_ref == PtSegmB->m_End )
|
|
{ /* Test des couches */
|
|
if(Reflayer & PtSegmB->ReturnMaskLayer() )return(PtSegmB);
|
|
}
|
|
suite1:
|
|
if( PtSegmB == pt_base ) PtSegmB = NULL;
|
|
else if( PtSegmB->m_StructType != TYPEPCB) PtSegmB = (TRACK*)PtSegmB->Pback;
|
|
else PtSegmB = NULL;
|
|
}
|
|
}
|
|
|
|
/* Recherche generale */
|
|
for ( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = (TRACK*) PtSegmN->Pnext )
|
|
{
|
|
if(PtSegmN->GetState(DELETED|BUSY))
|
|
{
|
|
if (PtSegmN == pt_lim ) break;
|
|
continue;
|
|
}
|
|
if (PtSegmN == PtRefSegm)
|
|
{
|
|
if (PtSegmN == pt_lim ) break;
|
|
continue;
|
|
}
|
|
|
|
if( pos_ref == PtSegmN->m_Start )
|
|
{ /* Test des couches */
|
|
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
|
|
}
|
|
|
|
if( pos_ref == PtSegmN->m_End )
|
|
{ /* Test des couches */
|
|
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
|
|
}
|
|
if (PtSegmN == pt_lim ) break;
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/* TRACK *Locate_Pistes(TRACK * start_adresse, int MasqueLayer,int typeloc) */
|
|
/* TRACK *Locate_Pistes(TRACK * start_adresse, int ref_pos.x, int ref_pos.y,*/
|
|
/* int MasqueLayer) */
|
|
/****************************************************************************/
|
|
|
|
/*
|
|
1 - routine de localisation du segment de piste pointe par la souris.
|
|
2 - routine de localisation du segment de piste pointe par le point
|
|
ref_pos.x , ref_pos.y.r
|
|
|
|
La recherche commence a l'adresse start_adresse
|
|
*/
|
|
|
|
TRACK * Locate_Pistes(TRACK * start_adresse,int MasqueLayer, int typeloc )
|
|
{
|
|
wxPoint ref_pos;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
return( Locate_Pistes(start_adresse, ref_pos,MasqueLayer) );
|
|
}
|
|
|
|
|
|
TRACK * Locate_Pistes(TRACK * start_adresse, const wxPoint & ref_pos,int MasqueLayer)
|
|
{
|
|
TRACK * Track; /* pointeur sur les pistes */
|
|
int l_piste ; /* demi-largeur de la piste */
|
|
|
|
for( Track = start_adresse; Track != NULL; Track = (TRACK*) Track->Pnext)
|
|
{
|
|
if( Track->GetState(BUSY|DELETED) ) continue;
|
|
if ( (g_DesignSettings.m_LayerColor[Track->m_Layer] & ITEM_NOT_SHOW) )
|
|
continue;
|
|
/* calcul des coordonnees du segment teste */
|
|
l_piste = Track->m_Width >> 1; /* l_piste = demi largeur piste */
|
|
ux0 = Track->m_Start.x ; uy0 = Track->m_Start.y ; /* coord de depart */
|
|
dx = Track->m_End.x ; dy = Track->m_End.y ; /* coord d'arrivee */
|
|
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx -= ux0 ; dy -= uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
if ( Track->m_StructType == TYPEVIA ) /* VIA rencontree */
|
|
{
|
|
if ((abs(spot_cX) <= l_piste ) && (abs(spot_cY) <=l_piste))
|
|
{
|
|
return(Track) ;
|
|
}
|
|
continue ;
|
|
}
|
|
|
|
if(MasqueLayer != -1)
|
|
if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0)
|
|
continue; /* Segments sur couches differentes */
|
|
if( distance(l_piste) ) return(Track) ;
|
|
}
|
|
return(NULL) ;
|
|
}
|
|
|
|
/****************************************************************/
|
|
/* TRACK * Locate_Zone(TRACK * start_adresse, int layer, */
|
|
/* int typeloc) */
|
|
/* TRACK * Locate_Zone(TRACK * start_adresse, */
|
|
/* const wxPoint & ref_pos, */
|
|
/* int layer) */
|
|
/****************************************************************/
|
|
|
|
/*
|
|
1 - routine de localisation du segment de zone pointe par la souris.
|
|
2 - routine de localisation du segment de zone pointe par le point
|
|
ref_pos.x , ref_pos.y.r
|
|
|
|
Si layer == -1 , le tst de la couche n'est pas fait
|
|
|
|
La recherche commence a l'adresse start_adresse
|
|
*/
|
|
|
|
TRACK * Locate_Zone(TRACK * start_adresse,int layer, int typeloc )
|
|
{
|
|
wxPoint ref_pos;
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
return( Locate_Zone(start_adresse, ref_pos, layer) );
|
|
}
|
|
|
|
|
|
TRACK * Locate_Zone(TRACK * start_adresse, const wxPoint & ref_pos, int layer)
|
|
{
|
|
TRACK * Zone; /* pointeur sur les pistes */
|
|
int l_segm ; /* demi-largeur de la piste */
|
|
|
|
for( Zone = start_adresse; Zone != NULL; Zone = (TRACK *) Zone->Pnext)
|
|
{
|
|
/* calcul des coordonnees du segment teste */
|
|
l_segm = Zone->m_Width >> 1; /* l_piste = demi largeur piste */
|
|
ux0 = Zone->m_Start.x ; uy0 = Zone->m_Start.y ; /* coord de depart */
|
|
dx = Zone->m_End.x ; dy = Zone->m_End.y ; /* coord d'arrivee */
|
|
|
|
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
|
|
dx -= ux0 ; dy -= uy0 ;
|
|
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
|
|
|
|
if((layer != -1) && (Zone->m_Layer != layer)) continue;
|
|
if( distance(l_segm) ) return(Zone) ;
|
|
}
|
|
return(NULL) ;
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************************/
|
|
TEXTE_PCB * Locate_Texte_Pcb(EDA_BaseStruct * PtStruct, int LayerSearch, int typeloc)
|
|
/************************************************************************************/
|
|
/* localisation des inscriptions sur le Pcb:
|
|
entree : EDA_BaseStruct pointeur sur le debut de la zone de recherche
|
|
retour : pointeur sur la description du texte localise
|
|
*/
|
|
{
|
|
wxPoint ref;
|
|
|
|
SET_REF_POS(ref);
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
|
|
{
|
|
if( PtStruct->m_StructType != TYPETEXTE ) continue;
|
|
TEXTE_PCB * pt_txt_pcb = (TEXTE_PCB *) PtStruct;
|
|
if( pt_txt_pcb->Locate(ref) )
|
|
{
|
|
if ( pt_txt_pcb->m_Layer == LayerSearch )
|
|
return pt_txt_pcb;
|
|
}
|
|
}
|
|
return(NULL) ;
|
|
}
|
|
|
|
|
|
|
|
/*****************************/
|
|
int distance(int seuil)
|
|
/*****************************/
|
|
|
|
/*
|
|
Calcul de la distance du curseur souris a un segment de droite :
|
|
( piste, edge, contour module ..
|
|
retourne:
|
|
0 si distance > seuil
|
|
1 si distance <= seuil
|
|
Variables utilisees ( doivent etre initialisees avant appel , et
|
|
sont ramenees au repere centre sur l'origine du segment)
|
|
dx, dy = coord de l'extremite segment.
|
|
spot_cX,spot_cY = coord du curseur souris
|
|
la recherche se fait selon 4 cas:
|
|
segment horizontal
|
|
segment vertical
|
|
segment 45
|
|
segment quelconque
|
|
*/
|
|
{
|
|
int cXrot, cYrot , /* coord du point (souris) dans le repere tourne */
|
|
segX, segY; /* coord extremite segment tj >= 0 */
|
|
int pointX, pointY; /* coord point a tester dans repere modifie dans lequel
|
|
segX et segY sont >=0 */
|
|
|
|
segX = dx ; segY = dy; pointX = spot_cX ; pointY = spot_cY ;
|
|
|
|
/*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/
|
|
if (segX < 0) /* mise en >0 par symetrie par rapport a l'axe Y */
|
|
{
|
|
segX = -segX ; pointX = - pointX ;
|
|
}
|
|
if (segY < 0) /* mise en > 0 par symetrie par rapport a l'axe X */
|
|
{
|
|
segY = -segY ; pointY = -pointY ;
|
|
}
|
|
|
|
|
|
if ( segY == 0 ) /* piste Horizontale */
|
|
{
|
|
if(abs(pointY) <= seuil )
|
|
{
|
|
if((pointX >= 0) && (pointX <= segX) ) return(1);
|
|
/* Etude des extremites : cercle de rayon seuil */
|
|
if( (pointX < 0) && (pointX >= -seuil) )
|
|
{
|
|
if( ((pointX * pointX) + (pointY*pointY)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
if( (pointX > segX) && (pointX <= (segX+seuil)) )
|
|
{
|
|
if( (((pointX-segX) * (pointX-segX)) + (pointY*pointY)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
else if ( segX == 0 ) /* piste verticale */
|
|
{
|
|
if( abs(pointX) <= seuil)
|
|
{
|
|
if((pointY >= 0 ) && (pointY <= segY) ) return(1);
|
|
if( (pointY < 0) && (pointY >= -seuil) )
|
|
{
|
|
if( ((pointY * pointY) + (pointX*pointX)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
if( (pointY > segY) && (pointY <= (segY+seuil)) )
|
|
{
|
|
if( ( ((pointY-segY) * (pointY-segY)) + (pointX*pointX)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
else if ( segX == segY ) /* piste a 45 degre */
|
|
{
|
|
/* on fait tourner les axes de 45 degre. la souris a alors les
|
|
coord : x1 = x*cos45 + y*sin45
|
|
y1 = y*cos45 - x*sin45
|
|
et le segment de piste est alors horizontal.
|
|
recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10
|
|
remarque : sin ou cos45 = .707, et lors du recalcul des coord
|
|
dx45 et dy45, lec coeff .707 est neglige, dx et dy sont en fait .707 fois
|
|
trop grands. (c.a.d trop petits)
|
|
spot_cX,Y doit etre * par .707 * .707 = 0.5 */
|
|
|
|
cXrot = (pointX + pointY) >> 1 ;
|
|
cYrot = (pointY - pointX) >> 1 ;
|
|
|
|
/* recalcul des coord de l'extremite du segment , qui sera vertical
|
|
suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY)
|
|
et est en fait 1,414 plus grand , et dy45 = 0 */
|
|
|
|
// seuil doit etre * .707 pour tenir compte du coeff de reduction sur dx,dy
|
|
seuil *= 7 ; seuil /= 10 ;
|
|
if ( abs(cYrot) <= seuil) /* ok sur axe vertical) */
|
|
{
|
|
if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ;
|
|
|
|
/* Etude des extremites : cercle de rayon seuil */
|
|
if( (cXrot < 0) && (cXrot >= -seuil) )
|
|
{
|
|
if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
if( (cXrot > segX) && (cXrot <= (segX+seuil)) )
|
|
{
|
|
if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
}
|
|
}
|
|
else /* orientation quelconque */
|
|
{
|
|
/* On fait un changement d'axe (rotation) de facon a ce que le segment
|
|
de piste soit horizontal dans le nouveau repere */
|
|
int angle;
|
|
|
|
angle = (int)( atan2((float)segY, (float)segX) * 1800 / M_PI) ;
|
|
cXrot = pointX; cYrot = pointY;
|
|
RotatePoint(&cXrot, &cYrot, angle); /* Rotation du point a tester */
|
|
RotatePoint(&segX, &segY, angle) ; /* Rotation du segment */
|
|
|
|
/*la piste est Horizontale , par suite des modifs de coordonnes
|
|
et d'axe, donc segX = longueur du segment */
|
|
|
|
if ( abs(cYrot) <= seuil ) /* ok sur axe vertical) */
|
|
{
|
|
if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ;
|
|
/* Etude des extremites : cercle de rayon seuil */
|
|
if( (cXrot < 0) && (cXrot >= -seuil) )
|
|
{
|
|
if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
if( (cXrot > segX) && (cXrot <= (segX+seuil)) )
|
|
{
|
|
if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) )
|
|
return(1);
|
|
}
|
|
}
|
|
}
|
|
return(0) ;
|
|
}
|
|
|
|
/*******************************************************************************/
|
|
D_PAD * Fast_Locate_Pad_Connecte(BOARD * Pcb, const wxPoint & ref_pos, int masque_layer)
|
|
/*******************************************************************************/
|
|
/* Routine cherchant le pad de centre px,py,
|
|
sur la couche indiquee par masque_layer (bit a bit)
|
|
( extremite de piste )
|
|
La liste des pads doit deja exister.
|
|
|
|
retourne :
|
|
NULL si pas de pad localise.
|
|
pointeur sur la structure descr_pad correspondante si pad trouve
|
|
(bonne position ET bonne couche).
|
|
*/
|
|
{
|
|
D_PAD * pad;
|
|
LISTE_PAD * ptr_pad , * lim;
|
|
|
|
lim = (LISTE_PAD*)Pcb->m_Pads + Pcb->m_NbPads;
|
|
for (ptr_pad = (LISTE_PAD*)Pcb->m_Pads; ptr_pad < lim ; ptr_pad++)
|
|
{
|
|
pad = * ptr_pad;
|
|
if( pad->m_Pos != ref_pos ) continue ;
|
|
|
|
/* Pad peut-etre trouve ici : il doit etre sur la bonne couche */
|
|
if (pad->m_Masque_Layer & masque_layer) return(pad) ;
|
|
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************************/
|
|
TRACK * Fast_Locate_Piste(TRACK *start_adr, TRACK* end_adr,
|
|
const wxPoint & ref_pos, int MaskLayer)
|
|
/***********************************************************************************/
|
|
/* Localiste le segment dont une extremite coincide avec le point x,y
|
|
sur les couches donnees par masklayer
|
|
la recherche se fait de l'adresse start_adr a end_adr
|
|
si end_adr = NULL, recherche jusqu'a la fin de la liste
|
|
Les segments de piste marques avec le flag DELETED ne sont pas
|
|
pris en compte
|
|
*/
|
|
{
|
|
TRACK * PtSegm;
|
|
|
|
if( start_adr == NULL ) return(NULL);
|
|
for ( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
|
|
{
|
|
if( PtSegm->GetState(DELETED|BUSY) == 0)
|
|
{
|
|
if( ref_pos == PtSegm->m_Start )
|
|
{ /* Test des couches */
|
|
if(MaskLayer & PtSegm->ReturnMaskLayer() ) return(PtSegm);
|
|
}
|
|
|
|
if( ref_pos == PtSegm->m_End )
|
|
{ /* Test des couches */
|
|
if(MaskLayer & PtSegm->ReturnMaskLayer() ) return(PtSegm);
|
|
}
|
|
}
|
|
if( PtSegm == end_adr) break;
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
/*******************************************************************/
|
|
TRACK * Fast_Locate_Via(TRACK *start_adr, TRACK* end_adr,
|
|
const wxPoint & pos, int MaskLayer)
|
|
/*******************************************************************/
|
|
|
|
/* Localise la via de centre le point x,y , sur les couches donnees
|
|
par masklayer
|
|
la recherche se fait de l'adresse start_adr a end_adr.
|
|
si end_adr = NULL, recherche jusqu'a la fin de la liste
|
|
les vias dont le parametre State a le bit DELETED ou BUSY = 1 sont ignorees
|
|
*/
|
|
{
|
|
TRACK * PtSegm;
|
|
|
|
for ( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*)PtSegm->Pnext )
|
|
{
|
|
if(PtSegm->m_StructType == TYPEVIA)
|
|
{
|
|
if( pos == PtSegm->m_Start )
|
|
{
|
|
if( PtSegm->GetState(BUSY|DELETED) == 0)
|
|
{/* Test des couches */
|
|
if( MaskLayer & PtSegm->ReturnMaskLayer() )return(PtSegm);
|
|
}
|
|
}
|
|
}
|
|
if( PtSegm == end_adr ) break;
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
/***********************************************************************/
|
|
EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch,
|
|
int typeloc)
|
|
/***********************************************************************/
|
|
/* Serach for a photo target
|
|
*/
|
|
{
|
|
wxPoint ref_pos; /* coord du point de localisation */
|
|
int dX, dY, rayon;
|
|
|
|
if(PtStruct == NULL ) return(NULL);
|
|
|
|
SET_REF_POS(ref_pos);
|
|
|
|
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext)
|
|
{
|
|
MIREPCB* item;
|
|
if( PtStruct->m_StructType != TYPEMIRE ) continue;
|
|
item = (MIREPCB*) PtStruct;
|
|
if( LayerSearch != -1 && item->m_Layer != LayerSearch ) continue;
|
|
|
|
dX = ref_pos.x - item->m_Pos.x;
|
|
dY = ref_pos.y - item->m_Pos.y;
|
|
rayon = item->m_Size / 2;
|
|
if( (abs(dX) <= rayon ) && ( abs(dY) <= rayon ) )
|
|
break; /* Mire Localisee */
|
|
}
|
|
return(PtStruct);
|
|
}
|
|
|