kicad/pcbnew/locate.cpp

1059 lines
31 KiB
C++
Raw Normal View History

2007-08-03 18:59:14 +00:00
/*****************************/
/* 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"
2007-08-08 20:51:08 +00:00
/* fonctions locales */
2007-08-03 18:59:14 +00:00
EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc );
/**
* Function RefPos
* returns the reference position, coming from either the mouse position or the
* the cursor position, based on whether the typeloc has the CURSEUR_OFF_GRILLE
* flag ORed in or not.
* @param typeloc int with possible CURSEUR_OFF_GRILLE bit on.
* @return wxPoint - The reference point, either the mouse position or
* the cursor position.
2007-08-03 18:59:14 +00:00
*/
wxPoint inline RefPos( int typeloc )
{
2007-08-08 03:50:44 +00:00
return ActiveScreen->RefPos( (typeloc & CURSEUR_OFF_GRILLE) != 0 );
}
2007-08-03 18:59:14 +00:00
/*************************************************************/
2007-08-03 18:59:14 +00:00
MODULE* ReturnModule( BOARD* pcb, const wxString& reference )
/*************************************************************/
2007-08-03 18:59:14 +00:00
/*
2007-08-03 18:59:14 +00:00
* Recherche d'un module par sa reference
* Retourne:
* un pointeur sur le module
* Null si pas localis<EFBFBD>
*/
{
2007-08-03 18:59:14 +00:00
MODULE* Module = pcb->m_Modules;
2007-08-03 18:59:14 +00:00
for( ; Module != NULL; Module = (MODULE*) Module->Pnext )
{
if( reference.CmpNoCase( Module->m_Reference->m_Text ) == 0 )
return Module;
2007-08-03 18:59:14 +00:00
}
return NULL;
}
/********************************************************/
2007-08-03 18:59:14 +00:00
D_PAD* ReturnPad( MODULE* module, const wxString& name )
/********************************************************/
2007-08-03 18:59:14 +00:00
/* Recherche d'un pad par son nom, pour le module Module
2007-08-03 18:59:14 +00:00
*/
{
2007-08-03 18:59:14 +00:00
D_PAD* pt_pad;
wxString buf;
2007-08-03 18:59:14 +00:00
if( module == NULL )
return NULL;
pt_pad = module->m_Pads;
2007-08-03 18:59:14 +00:00
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
{
pt_pad->ReturnStringPadName( buf );
if( buf.CmpNoCase( name ) == 0 )
return pt_pad;
2007-08-03 18:59:14 +00:00
}
2007-08-03 18:59:14 +00:00
return NULL;
}
/*******************************************************************************/
2007-08-03 18:59:14 +00:00
EDA_BaseStruct* WinEDA_BasePcbFrame::Locate( int typeloc, int LayerSearch )
/*******************************************************************************/
2007-08-03 18:59:14 +00:00
/* General locate function
* Display infos relatives to the item found
* return a pointer to this item ( or NULL )
2007-08-03 18:59:14 +00:00
*/
{
2007-08-03 18:59:14 +00:00
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
{
2007-08-03 18:59:14 +00:00
Affiche_Infos_PCB_Texte( this, pt_texte_pcb );
return pt_texte_pcb;
}
2007-08-03 18:59:14 +00:00
DrawSegm = Locate_Segment_Pcb( m_Pcb, LayerSearch, typeloc );
if( DrawSegm != NULL )
{
2007-08-03 18:59:14 +00:00
Affiche_Infos_DrawSegment( this, DrawSegm );
return DrawSegm;
}
2007-08-03 18:59:14 +00:00
item = Locate_Cotation( m_Pcb, LayerSearch, typeloc );
if( item != NULL )
return item;
2007-08-03 18:59:14 +00:00
item = Locate_MirePcb( m_Pcb->m_Drawings, LayerSearch, typeloc );
if( item != NULL )
return item;
/* Search for tracks and vias, with via priority */
2007-08-03 18:59:14 +00:00
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 */
2007-08-03 18:59:14 +00:00
while( ( TrackLocate = Locate_Pistes( TrackLocate,
masque_layer, typeloc ) ) != NULL )
{
Track = TrackLocate;
2007-08-03 18:59:14 +00:00
if( TrackLocate->m_StructType == TYPEVIA )
break;
TrackLocate = (TRACK*) TrackLocate->Pnext;
}
2007-08-03 18:59:14 +00:00
Affiche_Infos_Piste( this, Track );
return Track;
}
/* Search for Pads */
2007-08-03 18:59:14 +00:00
if( ( pt_pad = Locate_Any_Pad( m_Pcb, typeloc ) ) != NULL )
{
2007-08-03 18:59:14 +00:00
pt_pad->Display_Infos( this ); return pt_pad;
}
/* Search for a footprint text */
2007-08-03 18:59:14 +00:00
// 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 )
{
2007-08-03 18:59:14 +00:00
for( module = m_Pcb->m_Modules; module != NULL; module = (MODULE*) module->Pnext )
{
2007-08-03 18:59:14 +00:00
TEXTE_MODULE* pt_texte;
if( module->m_Layer != LayerSearch )
continue;
2007-08-03 18:59:14 +00:00
pt_texte = LocateTexteModule( m_Pcb, &module, typeloc | VISIBLE_ONLY );
if( pt_texte != NULL )
{
2007-08-03 18:59:14 +00:00
Affiche_Infos_E_Texte( this, module, pt_texte );
return pt_texte;
}
}
}
// Now Search footprint texts on all layers
module = NULL;
{
2007-08-03 18:59:14 +00:00
TEXTE_MODULE* pt_texte;
pt_texte = LocateTexteModule( m_Pcb, &module, typeloc | VISIBLE_ONLY );
if( pt_texte != NULL )
{
2007-08-03 18:59:14 +00:00
Affiche_Infos_E_Texte( this, module, pt_texte );
return pt_texte;
}
}
/* Search for a footprint */
module = Locate_Prefered_Module( m_Pcb, typeloc | VISIBLE_ONLY );
if( module != NULL )
{
2007-08-03 18:59:14 +00:00
module->Display_Infos( this );
return module;
}
/* Search for zones */
2007-08-03 18:59:14 +00:00
if( ( TrackLocate = Locate_Zone( (TRACK*) m_Pcb->m_Zone,
GetScreen()->m_Active_Layer, typeloc ) ) != NULL )
{
2007-08-03 18:59:14 +00:00
Affiche_Infos_Piste( this, TrackLocate );
return TrackLocate;
}
MsgPanel->EraseMsgBox();
return NULL;
}
/*******************************************************************/
2007-08-03 18:59:14 +00:00
TRACK* Locate_Via( BOARD* Pcb, const wxPoint& pos, int layer )
/*******************************************************************/
/* Localise une via au point pX,pY
2007-08-03 18:59:14 +00:00
* 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
*/
{
2007-08-03 18:59:14 +00:00
TRACK* Track;
2007-08-03 18:59:14 +00:00
for( Track = Pcb->m_Track; Track != NULL; Track = Track->Next() )
{
2007-08-03 18:59:14 +00:00
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;
}
2007-08-03 18:59:14 +00:00
return NULL;
}
/********************************************************************/
2007-08-03 18:59:14 +00:00
D_PAD* Locate_Pad_Connecte( BOARD* Pcb, TRACK* ptr_piste, int extr )
/********************************************************************/
2007-08-03 18:59:14 +00:00
/* localisation de la pastille connectee au point de piste a tester
2007-08-03 18:59:14 +00:00
* 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
*/
{
2007-08-03 18:59:14 +00:00
D_PAD* ptr_pad = NULL;
int masque_layer;
MODULE* module;
wxPoint ref_pos;
masque_layer = g_TabOneLayerMask[ptr_piste->m_Layer];
2007-08-03 18:59:14 +00:00
if( extr == START )
{
ref_pos = ptr_piste->m_Start;
2007-08-03 18:59:14 +00:00
}
else
2007-08-03 18:59:14 +00:00
{
ref_pos = ptr_piste->m_End;
2007-08-03 18:59:14 +00:00
}
module = Pcb->m_Modules;
2007-08-03 18:59:14 +00:00
for( ; module != NULL; module = (MODULE*) module->Pnext )
{
ptr_pad = Locate_Pads( module, ref_pos, masque_layer );
if( ptr_pad != NULL )
break;
}
2007-08-03 18:59:14 +00:00
return ptr_pad;
}
/****************************************************************/
2007-08-03 18:59:14 +00:00
EDGE_MODULE* Locate_Edge_Module( MODULE* module, int typeloc )
/****************************************************************/
2007-08-03 18:59:14 +00:00
/* Localisation de segments de contour du type edge MODULE
2007-08-03 18:59:14 +00:00
* 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
*/
{
2007-08-03 18:59:14 +00:00
if( !module )
return NULL;
2007-08-08 20:51:08 +00:00
/* coord du point de localisation */
wxPoint ref_pos = RefPos( typeloc );
2007-08-08 20:51:08 +00:00
EDA_BaseStruct* PtStruct = module->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
2007-08-03 18:59:14 +00:00
{
if( PtStruct->m_StructType != TYPEEDGEMODULE )
continue;
2007-08-08 03:50:44 +00:00
2007-08-08 20:51:08 +00:00
// calls virtual EDGE_MODULE::HitTest()
if( PtStruct->HitTest( ref_pos ) )
return (EDGE_MODULE*) PtStruct;
2007-08-03 18:59:14 +00:00
}
return NULL;
}
/*************************************************************************/
2007-08-03 18:59:14 +00:00
EDA_BaseStruct* Locate_Cotation( BOARD* Pcb, int LayerSearch, int typeloc )
/*************************************************************************/
2007-08-03 18:59:14 +00:00
/* Serach for a cotation item , on LayerSearch,
2007-08-03 18:59:14 +00:00
* (if LayerSearch == -1 , no yaere restriction )
* return a pointer to the located item, or NULL
*/
{
2007-08-08 20:51:08 +00:00
wxPoint ref_pos = RefPos( typeloc );
2007-08-08 20:51:08 +00:00
EDA_BaseStruct* PtStruct = Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
2007-08-03 18:59:14 +00:00
if( PtStruct->m_StructType != TYPECOTATION )
continue;
2007-08-08 20:51:08 +00:00
// calls virtual COTATION::HitTest()
if( PtStruct->HitTest( ref_pos ) )
return (COTATION*) PtStruct;
}
2007-08-03 18:59:14 +00:00
return NULL;
}
2007-08-03 18:59:14 +00:00
/*************************************************************************/
2007-08-03 18:59:14 +00:00
DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc )
/*************************************************************************/
2007-08-03 18:59:14 +00:00
/* Localisation de segments de contour du type drawing
2007-08-03 18:59:14 +00:00
* Retourne:
* Pointeur sur DEBUT du segment localise
* NULL si rien trouve
* Le segment sur la couche active est d<EFBFBD>tect<EFBFBD> en priorite
*/
{
2007-08-03 18:59:14 +00:00
2007-08-08 20:51:08 +00:00
DRAWSEGMENT* locate_segm = NULL;
PCB_SCREEN* screen = (PCB_SCREEN*) ActiveScreen;
wxPoint ref_pos = RefPos( typeloc );
2007-08-08 20:51:08 +00:00
EDA_BaseStruct* PtStruct = Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
2007-08-03 18:59:14 +00:00
if( PtStruct->m_StructType != TYPEDRAWSEGMENT )
continue;
2007-08-08 20:51:08 +00:00
DRAWSEGMENT* pts = (DRAWSEGMENT*) PtStruct;
2007-08-08 20:51:08 +00:00
if( (pts->m_Layer != LayerSearch) && (LayerSearch != -1) )
continue;
2007-08-08 20:51:08 +00:00
if( pts->HitTest( ref_pos ) )
{
2007-08-08 20:51:08 +00:00
// return this hit if layer matches, else remember in
// case no layer match is found.
if( pts->m_Layer == screen->m_Active_Layer )
return pts;
2007-08-08 20:51:08 +00:00
else if( !locate_segm )
locate_segm = pts;
}
}
2007-08-03 18:59:14 +00:00
return locate_segm;
}
2007-08-03 18:59:14 +00:00
/*************************************************/
/* D_PAD * Locate_Any_Pad(int typeloc, bool OnlyCurrentLayer) */
/* D_PAD* Locate_Any_Pad(int ref_pos, bool OnlyCurrentLayer) */
/*************************************************/
/*
2007-08-03 18:59:14 +00:00
* 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<EFBFBD> est donn<EFBFBD>e a la couche active
*/
D_PAD* Locate_Any_Pad( BOARD* Pcb, int typeloc, bool OnlyCurrentLayer )
{
wxPoint ref_pos = RefPos( typeloc );
2007-08-03 18:59:14 +00:00
return Locate_Any_Pad( Pcb, ref_pos, OnlyCurrentLayer );
}
2007-08-03 18:59:14 +00:00
D_PAD* Locate_Any_Pad( BOARD* Pcb, const wxPoint& ref_pos, bool OnlyCurrentLayer )
{
2007-08-03 18:59:14 +00:00
D_PAD* pt_pad;
MODULE* module;
int layer_mask = g_TabOneLayerMask[ ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer];
module = Pcb->m_Modules;
2007-08-03 18:59:14 +00:00
for( ; module != NULL; module = (MODULE*) module->Pnext )
{
/* First: Search a pad on the active layer: */
2007-08-03 18:59:14 +00:00
if( ( pt_pad = Locate_Pads( module, ref_pos, layer_mask ) ) != NULL )
return pt_pad;
2007-08-03 18:59:14 +00:00
/* If not found, search on other layers: */
if( !OnlyCurrentLayer )
{
2007-08-03 18:59:14 +00:00
if( ( pt_pad = Locate_Pads( module, ref_pos, ALL_LAYERS ) ) != NULL )
return pt_pad;
}
}
2007-08-03 18:59:14 +00:00
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
2007-08-03 18:59:14 +00:00
* 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 = RefPos( typeloc );
2007-08-03 18:59:14 +00:00
return Locate_Pads( module, ref_pos, masque_layer );
}
2007-08-03 18:59:14 +00:00
D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer )
{
2007-08-08 03:50:44 +00:00
D_PAD* pt_pad = module->m_Pads;
2007-08-03 18:59:14 +00:00
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext )
{
/* ... et sur la bonne couche */
2007-08-03 18:59:14 +00:00
if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
continue;
2007-08-08 03:50:44 +00:00
if( pt_pad->HitTest( ref_pos ) )
return pt_pad;
}
2007-08-03 18:59:14 +00:00
return NULL;
}
/********************************************************/
2007-08-03 18:59:14 +00:00
MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
/********************************************************/
2007-08-03 18:59:14 +00:00
/*
2007-08-03 18:59:14 +00:00
* localisation d'une empreinte par son rectangle d'encadrement
* Si plusieurs empreintes sont possibles, la priorite est:
* - sur la couche active
* - la plus petite
*/
{
2007-08-03 18:59:14 +00:00
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 */
ref_pos = RefPos( typeloc );
pt_module = Pcb->m_Modules;
for( ; pt_module; pt_module = (MODULE*) pt_module->Pnext )
{
2007-08-08 03:50:44 +00:00
// is the ref point within the module's bounds?
if( !pt_module->HitTest( ref_pos ) )
continue;
// if caller wants to ignore locked modules, and this one is locked, skip it.
if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() )
continue;
2007-08-03 18:59:14 +00:00
/* calcul de priorite: la priorite est donnee a la couche
2007-08-03 18:59:14 +00:00
* 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;
2007-08-08 03:50:44 +00:00
2007-08-08 20:51:08 +00:00
/* Localisation: test des dimensions minimales, choix du meilleur candidat */
2007-08-08 03:50:44 +00:00
/* calcul des dimensions du cadre :*/
lx = pt_module->m_BoundaryBox.GetWidth();
ly = pt_module->m_BoundaryBox.GetHeight();
2007-08-03 18:59:14 +00:00
if( ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer == layer )
{
2007-08-03 18:59:14 +00:00
if( min( lx, ly ) <= min_dim )
{
/* meilleure empreinte localisee sur couche active */
2007-08-08 03:50:44 +00:00
module = pt_module;
min_dim = min( lx, ly );
}
}
2007-08-03 18:59:14 +00:00
else if( !(typeloc & MATCH_LAYER)
&& ( !(typeloc & VISIBLE_ONLY) || IsModuleLayerVisible( layer ) ) )
{
2007-08-03 18:59:14 +00:00
if( min( lx, ly ) <= alt_min_dim )
{
/* meilleure empreinte localisee sur autres couches */
2007-08-03 18:59:14 +00:00
Altmodule = pt_module;
alt_min_dim = min( lx, ly );
}
}
}
if( module )
{
return module;
}
if( Altmodule )
{
return Altmodule;
}
return NULL;
}
/*****************************************************************************/
2007-08-03 18:59:14 +00:00
TEXTE_MODULE* LocateTexteModule( BOARD* Pcb, MODULE** PtModule, int typeloc )
/*****************************************************************************/
2007-08-03 18:59:14 +00:00
/* 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 has the flag VISIBLE_ONLY set, only footprints which are
* "visible" are considered
2007-08-03 18:59:14 +00:00
*/
{
2007-08-03 18:59:14 +00:00
EDA_BaseStruct* PtStruct;
TEXTE_MODULE* pt_txt_mod;
MODULE* module;
wxPoint ref_pos;
ref_pos = RefPos( typeloc );
2007-08-03 18:59:14 +00:00
module = *PtModule;
if( module == NULL )
{
module = Pcb->m_Modules;
}
2007-08-03 18:59:14 +00:00
for( ; module != NULL; module = (MODULE*) module->Pnext )
{
int layer = module->m_Layer;
2007-08-03 18:59:14 +00:00
if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU )
layer = CUIVRE_N;
2007-08-03 18:59:14 +00:00
else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
layer = CMP_N;
if( typeloc & VISIBLE_ONLY )
2007-08-03 18:59:14 +00:00
{
if( !IsModuleLayerVisible( layer ) )
continue;
2007-08-03 18:59:14 +00:00
}
if( typeloc & MATCH_LAYER )
{
2007-08-03 18:59:14 +00:00
if( ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer != layer )
continue;
}
2007-08-03 18:59:14 +00:00
// hit-test the reference text
pt_txt_mod = module->m_Reference;
if( pt_txt_mod->HitTest( ref_pos ) )
{
2007-08-03 18:59:14 +00:00
if( PtModule )
*PtModule = module;
return pt_txt_mod;
}
2007-08-03 18:59:14 +00:00
// hit-test the value text
pt_txt_mod = module->m_Value;
if( pt_txt_mod->HitTest( ref_pos ) )
{
2007-08-03 18:59:14 +00:00
if( PtModule )
*PtModule = module;
return pt_txt_mod;
}
// hit-test any other texts
PtStruct = module->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
2007-08-03 18:59:14 +00:00
if( PtStruct->m_StructType != TYPETEXTEMODULE )
continue;
pt_txt_mod = (TEXTE_MODULE*) PtStruct;
if( pt_txt_mod->HitTest( ref_pos ) )
{
2007-08-03 18:59:14 +00:00
if( PtModule )
*PtModule = module;
return pt_txt_mod;
}
}
2007-08-03 18:59:14 +00:00
if( *PtModule != NULL )
break; /* Recherche limitee a 1 seul module */
}
2007-08-03 18:59:14 +00:00
return NULL;
}
/**************************************************************/
2007-08-03 18:59:14 +00:00
TRACK* Locate_Piste_Connectee( TRACK* PtRefSegm, TRACK* pt_base,
TRACK* pt_lim, int extr )
/**************************************************************/
2007-08-03 18:59:14 +00:00
/* recherche le segment connecte au segment pointe par
2007-08-03 18:59:14 +00:00
* 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
*/
{
2007-08-03 18:59:14 +00:00
TRACK* PtSegmB, * PtSegmN;
int Reflayer;
wxPoint pos_ref;
int ii;
2007-08-03 18:59:14 +00:00
if( extr == START )
pos_ref = PtRefSegm->m_Start;
else
pos_ref = PtRefSegm->m_End;
Reflayer = PtRefSegm->ReturnMaskLayer();
/* 1ere passe */
PtSegmB = PtSegmN = PtRefSegm;
2007-08-03 18:59:14 +00:00
for( ii = 0; ii < 50; ii++ )
{
if( (PtSegmN == NULL) && (PtSegmB == NULL) )
break;
if( PtSegmN )
2007-08-03 18:59:14 +00:00
{
if( PtSegmN->GetState( BUSY | DELETED ) )
goto suite;
if( PtSegmN == PtRefSegm )
goto suite;
if( pos_ref == PtSegmN->m_Start )
2007-08-03 18:59:14 +00:00
{ /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN;
}
if( pos_ref == PtSegmN->m_End )
2007-08-03 18:59:14 +00:00
{ /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN;
}
2007-08-03 18:59:14 +00:00
suite:
if( PtSegmN == pt_lim )
PtSegmN = NULL;
else
PtSegmN = (TRACK*) PtSegmN->Pnext;
}
if( PtSegmB )
2007-08-03 18:59:14 +00:00
{
if( PtSegmB->GetState( BUSY | DELETED ) )
goto suite1;
if( PtSegmB == PtRefSegm )
goto suite1;
if( pos_ref == PtSegmB->m_Start )
2007-08-03 18:59:14 +00:00
{ /* Test des couches */
if( Reflayer & PtSegmB->ReturnMaskLayer() )
return PtSegmB;
}
if( pos_ref == PtSegmB->m_End )
2007-08-03 18:59:14 +00:00
{ /* Test des couches */
if( Reflayer & PtSegmB->ReturnMaskLayer() )
return PtSegmB;
}
2007-08-03 18:59:14 +00:00
suite1:
if( PtSegmB == pt_base )
PtSegmB = NULL;
else if( PtSegmB->m_StructType != TYPEPCB )
PtSegmB = (TRACK*) PtSegmB->Pback;
else
PtSegmB = NULL;
}
2007-08-03 18:59:14 +00:00
}
/* Recherche generale */
2007-08-03 18:59:14 +00:00
for( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = (TRACK*) PtSegmN->Pnext )
{
if( PtSegmN->GetState( DELETED | BUSY ) )
{
2007-08-03 18:59:14 +00:00
if( PtSegmN == pt_lim )
break;
continue;
2007-08-03 18:59:14 +00:00
}
if( PtSegmN == PtRefSegm )
{
if( PtSegmN == pt_lim )
break;
continue;
2007-08-03 18:59:14 +00:00
}
if( pos_ref == PtSegmN->m_Start )
2007-08-03 18:59:14 +00:00
{ /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN;
}
if( pos_ref == PtSegmN->m_End )
2007-08-03 18:59:14 +00:00
{ /* Test des couches */
if( Reflayer & PtSegmN->ReturnMaskLayer() )
return PtSegmN;
}
2007-08-03 18:59:14 +00:00
if( PtSegmN == pt_lim )
break;
}
return NULL;
}
2007-08-03 18:59:14 +00:00
/****************************************************************************/
/* 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) */
/****************************************************************************/
/*
2007-08-03 18:59:14 +00:00
* 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
*/
2007-08-03 18:59:14 +00:00
TRACK* Locate_Pistes( TRACK* start_adresse, int MasqueLayer, int typeloc )
{
wxPoint ref_pos = RefPos( typeloc );
2007-08-03 18:59:14 +00:00
return Locate_Pistes( start_adresse, ref_pos, MasqueLayer );
}
2007-08-03 18:59:14 +00:00
TRACK* Locate_Pistes( TRACK* start_adresse, const wxPoint& ref_pos, int MasqueLayer )
{
2007-08-08 20:51:08 +00:00
for( TRACK* Track = start_adresse; Track; Track = (TRACK*) Track->Pnext )
{
2007-08-03 18:59:14 +00:00
if( Track->GetState( BUSY | DELETED ) )
continue;
2007-08-08 20:51:08 +00:00
2007-08-03 18:59:14 +00:00
if( (g_DesignSettings.m_LayerColor[Track->m_Layer] & ITEM_NOT_SHOW) )
continue;
2007-08-03 18:59:14 +00:00
if( Track->m_StructType == TYPEVIA ) /* VIA rencontree */
{
2007-08-08 20:51:08 +00:00
if( Track->HitTest( ref_pos ) )
return Track;
}
else
{
if( MasqueLayer != -1 )
if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0 )
continue; /* Segments sur couches differentes */
if( Track->HitTest( ref_pos ) )
2007-08-03 18:59:14 +00:00
return Track;
}
}
2007-08-08 20:51:08 +00:00
2007-08-03 18:59:14 +00:00
return NULL;
}
2007-08-03 18:59:14 +00:00
/****************************************************************/
/* TRACK * Locate_Zone(TRACK * start_adresse, int layer, */
/* int typeloc) */
/* TRACK * Locate_Zone(TRACK * start_adresse, */
/* const wxPoint & ref_pos, */
/* int layer) */
/****************************************************************/
2007-08-03 18:59:14 +00:00
/*
* 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 = RefPos( typeloc );
2007-08-03 18:59:14 +00:00
return Locate_Zone( start_adresse, ref_pos, layer );
}
2007-08-03 18:59:14 +00:00
TRACK* Locate_Zone( TRACK* start_adresse, const wxPoint& ref_pos, int layer )
{
2007-08-08 20:51:08 +00:00
for( TRACK* Zone = start_adresse; Zone; Zone = (TRACK*) Zone->Pnext )
2007-08-03 18:59:14 +00:00
{
if( (layer != -1) && (Zone->m_Layer != layer) )
continue;
2007-08-08 20:51:08 +00:00
if( Zone->HitTest( ref_pos ) )
2007-08-03 18:59:14 +00:00
return Zone;
}
2007-08-03 18:59:14 +00:00
return NULL;
}
/************************************************************************************/
2007-08-03 18:59:14 +00:00
TEXTE_PCB* Locate_Texte_Pcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc )
/************************************************************************************/
2007-08-03 18:59:14 +00:00
/* localisation des inscriptions sur le Pcb:
2007-08-03 18:59:14 +00:00
* entree : EDA_BaseStruct pointeur sur le debut de la zone de recherche
* retour : pointeur sur la description du texte localise
*/
{
wxPoint ref = RefPos( typeloc );
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
2007-08-03 18:59:14 +00:00
if( PtStruct->m_StructType != TYPETEXTE )
continue;
2007-08-08 03:50:44 +00:00
2007-08-03 18:59:14 +00:00
TEXTE_PCB* pt_txt_pcb = (TEXTE_PCB*) PtStruct;
2007-08-08 03:50:44 +00:00
if( pt_txt_pcb->m_Layer == LayerSearch )
{
2007-08-08 03:50:44 +00:00
// because HitTest() is present in both base classes of TEXTE_PCB
// use a dis-ambiguating cast to tell compiler which HitTest()
// to call.
if( static_cast<EDA_TextStruct*>(pt_txt_pcb)->HitTest( ref ) )
{
return pt_txt_pcb;
2007-08-08 03:50:44 +00:00
}
}
}
2007-08-03 18:59:14 +00:00
return NULL;
}
2007-08-03 18:59:14 +00:00
/*******************************************************************************/
2007-08-03 18:59:14 +00:00
D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int masque_layer )
/*******************************************************************************/
2007-08-03 18:59:14 +00:00
/* Routine cherchant le pad de centre px,py,
2007-08-03 18:59:14 +00:00
* 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).
*/
{
2007-08-03 18:59:14 +00:00
D_PAD* pad;
LISTE_PAD* ptr_pad, * lim;
2007-08-03 18:59:14 +00:00
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 */
2007-08-03 18:59:14 +00:00
if( pad->m_Masque_Layer & masque_layer )
return pad;
}
2007-08-03 18:59:14 +00:00
return NULL;
}
/***********************************************************************************/
2007-08-03 18:59:14 +00:00
TRACK* Fast_Locate_Piste( TRACK* start_adr, TRACK* end_adr,
const wxPoint& ref_pos, int MaskLayer )
/***********************************************************************************/
2007-08-03 18:59:14 +00:00
/* Localiste le segment dont une extremite coincide avec le point x,y
2007-08-03 18:59:14 +00:00
* 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
*/
{
2007-08-03 18:59:14 +00:00
TRACK* PtSegm;
2007-08-03 18:59:14 +00:00
if( start_adr == NULL )
return NULL;
2007-08-03 18:59:14 +00:00
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 */
2007-08-03 18:59:14 +00:00
if( MaskLayer & PtSegm->ReturnMaskLayer() )
return PtSegm;
}
if( ref_pos == PtSegm->m_End )
{
/* Test des couches */
2007-08-03 18:59:14 +00:00
if( MaskLayer & PtSegm->ReturnMaskLayer() )
return PtSegm;
}
}
2007-08-03 18:59:14 +00:00
if( PtSegm == end_adr )
break;
}
return NULL;
}
2007-08-03 18:59:14 +00:00
/*******************************************************************/
2007-08-03 18:59:14 +00:00
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
2007-08-03 18:59:14 +00:00
* 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
*/
{
2007-08-03 18:59:14 +00:00
TRACK* PtSegm;
2007-08-03 18:59:14 +00:00
for( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
{
if( PtSegm->m_StructType == TYPEVIA )
{
if( pos == PtSegm->m_Start )
2007-08-03 18:59:14 +00:00
{
if( PtSegm->GetState( BUSY | DELETED ) == 0 )
{
/* Test des couches */
2007-08-03 18:59:14 +00:00
if( MaskLayer & PtSegm->ReturnMaskLayer() )
return PtSegm;
}
}
}
2007-08-03 18:59:14 +00:00
if( PtSegm == end_adr )
break;
}
return NULL;
}
/***********************************************************************/
2007-08-03 18:59:14 +00:00
EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch,
int typeloc )
/***********************************************************************/
2007-08-03 18:59:14 +00:00
2007-08-08 20:51:08 +00:00
/* Search for a photo target
2007-08-03 18:59:14 +00:00
*/
{
2007-08-03 18:59:14 +00:00
wxPoint ref_pos;/* coord du point de localisation */
2007-08-03 18:59:14 +00:00
if( PtStruct == NULL )
return NULL;
ref_pos = RefPos( typeloc );
2007-08-03 18:59:14 +00:00
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{
MIREPCB* item;
2007-08-03 18:59:14 +00:00
if( PtStruct->m_StructType != TYPEMIRE )
continue;
item = (MIREPCB*) PtStruct;
2007-08-03 18:59:14 +00:00
if( LayerSearch != -1 && item->m_Layer != LayerSearch )
continue;
2007-08-08 20:51:08 +00:00
if( item->HitTest( ref_pos ) )
break;
}
2007-08-03 18:59:14 +00:00
return PtStruct;
}
2007-08-08 20:51:08 +00:00