Commit f601dff4 authored by dickelbeck's avatar dickelbeck

Hot key operations for a single module such as Move 'M', Rotate 'R', Swap...

Hot key operations for a single module such as Move 'M', Rotate 'R', Swap Layer 'S', now operate only on unlocked modules 
and only on modules in the current layer.

parent ad61cdaa
/*******************************************************/ /*******************************************************/
/* class_module.h : module description (excepted pads) */ /* class_module.h : module description (excepted pads) */
/*******************************************************/ /*******************************************************/
class Pcb3D_GLCanvas; class Pcb3D_GLCanvas;
class Struct3D_Master; class Struct3D_Master;
/************************************/ /************************************/
/* Modules (footprints) description */ /* Modules (footprints) description */
/* pad are in class_pad.xx */ /* pad are in class_pad.xx */
/************************************/ /************************************/
/* Format des modules: /* Format des modules:
Description generale Description generale
Description segments contour Description segments contour
Description textes Description textes
Description pastilles Description pastilles
*/ */
/* Flags :*/ /* Flags :*/
enum Mod_Attribut /* Attributs d'un module */ enum Mod_Attribut /* Attributs d'un module */
{ {
MOD_DEFAULT = 0, /* Type default */ MOD_DEFAULT = 0, /* Type default */
MOD_CMS = 1, /* Pour module apparaissant dans les MOD_CMS = 1, /* Pour module apparaissant dans les
fichiers de placement automatique (principalement modules CMS */ fichiers de placement automatique (principalement modules CMS */
MOD_VIRTUAL = 2 /* Module virtuel constitue par un dessin sur circuit MOD_VIRTUAL = 2 /* Module virtuel constitue par un dessin sur circuit
(connecteur, trou de percage..) */ (connecteur, trou de percage..) */
}; };
/* flags for autoplace and autoroute (.m_ModuleStatus member) */ /* flags for autoplace and autoroute (.m_ModuleStatus member) */
#define MODULE_is_LOCKED 0x01 /* module LOCKED: no autoplace allowed */ #define MODULE_is_LOCKED 0x01 /* module LOCKED: no autoplace allowed */
#define MODULE_is_PLACED 0x02 /* In autoplace: module automatically placed */ #define MODULE_is_PLACED 0x02 /* In autoplace: module automatically placed */
#define MODULE_to_PLACE 0x04 /* In autoplace: module waiting for autoplace */ #define MODULE_to_PLACE 0x04 /* In autoplace: module waiting for autoplace */
class MODULE: public EDA_BaseStruct class MODULE: public EDA_BaseStruct
{ {
public: public:
int m_Layer; // layer number int m_Layer; // layer number
wxPoint m_Pos; // Real coord on board wxPoint m_Pos; // Real coord on board
D_PAD * m_Pads; /* Pad list (linked list) */ D_PAD * m_Pads; /* Pad list (linked list) */
EDA_BaseStruct * m_Drawings; /* Graphic items list (linked list) */ EDA_BaseStruct * m_Drawings; /* Graphic items list (linked list) */
Struct3D_Master * m_3D_Drawings; /* Pointeur sur la liste des elements de trace 3D*/ Struct3D_Master * m_3D_Drawings; /* Pointeur sur la liste des elements de trace 3D*/
TEXTE_MODULE * m_Reference; // texte reference du composant (U34, R18..) TEXTE_MODULE * m_Reference; // texte reference du composant (U34, R18..)
TEXTE_MODULE * m_Value; // texte valeur du composant (74LS00, 22K..) TEXTE_MODULE * m_Value; // texte valeur du composant (74LS00, 22K..)
wxString m_LibRef; /* nom du module en librairie */ wxString m_LibRef; /* nom du module en librairie */
int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */ int m_Attributs; /* Flags bits a bit ( voir enum Mod_Attribut ) */
int m_Orient ; /* orientation en 1/10 degres */ int m_Orient ; /* orientation en 1/10 degres */
int flag ; /* flag utilise en trace rastnest et routage auto */ int flag ; /* flag utilise en trace rastnest et routage auto */
int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */ int m_ModuleStatus; /* For autoplace: flags (LOCKED, AUTOPLACED) */
EDA_Rect m_BoundaryBox ; /* position/taille du cadre de reperage (coord locales)*/ EDA_Rect m_BoundaryBox; /* position/taille du cadre de reperage (coord locales)*/
EDA_Rect m_RealBoundaryBox ; /* position/taille du module (coord relles) */ EDA_Rect m_RealBoundaryBox ; /* position/taille du module (coord relles) */
int m_PadNum; // Nombre total de pads int m_PadNum; // Nombre total de pads
int m_AltPadNum; // en placement auto Nombre de pads actifs pour int m_AltPadNum; // en placement auto Nombre de pads actifs pour
// les calculs // les calculs
int m_CntRot90; // Placement auto: cout ( 0..10 ) de la rotation 90 degre int m_CntRot90; // Placement auto: cout ( 0..10 ) de la rotation 90 degre
int m_CntRot180; // Placement auto: cout ( 0..10 ) de la rotation 180 degre int m_CntRot180; // Placement auto: cout ( 0..10 ) de la rotation 180 degre
wxSize m_Ext; // marges de "garde": utilise en placement auto. wxSize m_Ext; // marges de "garde": utilise en placement auto.
float m_Surface; // surface du rectangle d'encadrement float m_Surface; // surface du rectangle d'encadrement
long m_Link; // variable temporaire ( pour editions, ...) long m_Link; // variable temporaire ( pour editions, ...)
long m_LastEdit_Time; // Date de la derniere modification du module (gestion de librairies) long m_LastEdit_Time; // Date de la derniere modification du module (gestion de librairies)
wxString m_Doc; // Texte de description du module wxString m_Doc; // Texte de description du module
wxString m_KeyWord; // Liste des mots cles relatifs au module wxString m_KeyWord; // Liste des mots cles relatifs au module
public: public:
MODULE(BOARD * parent); MODULE(BOARD * parent);
MODULE(MODULE * module); MODULE(MODULE * module);
~MODULE(void); ~MODULE(void);
void Copy(MODULE * Module); // Copy structure void Copy(MODULE * Module); // Copy structure
MODULE * Next(void) { return (MODULE *) Pnext; } MODULE * Next(void) { return (MODULE *) Pnext; }
void Set_Rectangle_Encadrement(void); /* mise a jour du rect d'encadrement void Set_Rectangle_Encadrement(void); /* mise a jour du rect d'encadrement
en coord locales (orient 0 et origine = pos module) */ en coord locales (orient 0 et origine = pos module) */
void SetRectangleExinscrit(void); /* mise a jour du rect d'encadrement
et de la surface en coord reelles */ void SetRectangleExinscrit(void); /* mise a jour du rect d'encadrement
et de la surface en coord reelles */
// deplacements
void SetPosition(const wxPoint & newpos); // deplacements
void SetOrientation(int newangle); void SetPosition(const wxPoint & newpos);
void SetOrientation(int newangle);
/* supprime du chainage la structure Struct */
void UnLink( void ); /* supprime du chainage la structure Struct */
void UnLink( void );
/* Readind and writing data on files */
int WriteDescr( FILE * File );
int Write_3D_Descr( FILE * File ); /**
int ReadDescr( FILE * File, int * LineNum = NULL); * Function IsLocked
int Read_3D_Descr( FILE * File, int * LineNum = NULL); * @returns bool - true if the MODULE is locked, else false
*/
/* drawing functions */ bool IsLocked()
void Draw(WinEDA_DrawPanel * panel, wxDC * DC, {
const wxPoint & offset, int draw_mode); return (m_ModuleStatus & MODULE_is_LOCKED) != 0;
void Draw3D(Pcb3D_GLCanvas * glcanvas); }
void DrawEdgesOnly(WinEDA_DrawPanel * panel, wxDC * DC,
const wxPoint & offset,int draw_mode);
void DrawAncre(WinEDA_DrawPanel * panel, wxDC * DC, /**
const wxPoint & offset, int dim_ancre, int draw_mode); * Function SetLocked
* sets the MODULE_is_LOCKED bit in the m_ModuleStatus
/* miscellaneous */ * @param setLocked When true means turn on locked status, else unlock
void Display_Infos(WinEDA_BasePcbFrame * frame); */
void SetLocked( bool setLocked )
{
if( setLocked )
m_ModuleStatus |= MODULE_is_LOCKED;
else
m_ModuleStatus &= ~MODULE_is_LOCKED;
}
/* Readind and writing data on files */
int WriteDescr( FILE * File );
int Write_3D_Descr( FILE * File );
int ReadDescr( FILE * File, int * LineNum = NULL);
int Read_3D_Descr( FILE * File, int * LineNum = NULL);
/* drawing functions */
void Draw(WinEDA_DrawPanel * panel, wxDC * DC,
const wxPoint & offset, int draw_mode);
void Draw3D(Pcb3D_GLCanvas * glcanvas);
void DrawEdgesOnly(WinEDA_DrawPanel * panel, wxDC * DC,
const wxPoint & offset,int draw_mode);
void DrawAncre(WinEDA_DrawPanel * panel, wxDC * DC,
const wxPoint & offset, int dim_ancre, int draw_mode);
/* miscellaneous */
void Display_Infos(WinEDA_BasePcbFrame * frame);
}; };
/***************/ /***************/
/* hotkeys.cpp */ /* hotkeys.cpp */
/***************/ /***************/
#include "fctsys.h" #include "fctsys.h"
...@@ -18,129 +18,161 @@ ...@@ -18,129 +18,161 @@
/***********************************************************/ /***********************************************************/
void WinEDA_PcbFrame::OnHotKey(wxDC * DC, int hotkey, void WinEDA_PcbFrame::OnHotKey(wxDC * DC, int hotkey,
EDA_BaseStruct * DrawStruct) EDA_BaseStruct * DrawStruct)
/***********************************************************/ /***********************************************************/
/* Gestion des commandes rapides (Raccourcis claviers) concernant l'element /* Gestion des commandes rapides (Raccourcis claviers) concernant l'element
sous le courseur souris sous le courseur souris
Les majuscules/minuscules sont indifferenciees Les majuscules/minuscules sont indifferenciees
touche DELETE: Effacement (Module ou piste selon commande en cours) touche DELETE: Effacement (Module ou piste selon commande en cours)
touche V: Place via en cours de trace de piste touche V: Place via en cours de trace de piste
touche R: Rotation module touche R: Rotation module
touche S: Change couche module (Composant <-> Cuivre) touche S: Change couche module (Composant <-> Cuivre)
touche M: Start Move module touche M: Start Move module
touche G: Start Drag module touche G: Start Drag module
*/ */
{ {
bool PopupOn = GetScreen()->m_CurrentItem && bool PopupOn = GetScreen()->m_CurrentItem &&
GetScreen()->m_CurrentItem->m_Flags; GetScreen()->m_CurrentItem->m_Flags;
bool ItemFree = (GetScreen()->m_CurrentItem == 0 ) || bool ItemFree = (GetScreen()->m_CurrentItem == 0 ) ||
(GetScreen()->m_CurrentItem->m_Flags == 0); (GetScreen()->m_CurrentItem->m_Flags == 0);
if ( hotkey == 0 ) return; if ( hotkey == 0 ) return;
MODULE* module = NULL; MODULE* module = NULL;
switch (hotkey) switch (hotkey)
{ {
case WXK_DELETE: case WXK_DELETE:
case WXK_NUMPAD_DELETE: case WXK_NUMPAD_DELETE:
OnHotkeyDeleteItem(DC, DrawStruct); OnHotkeyDeleteItem(DC, DrawStruct);
break; break;
case WXK_BACK:{
if( m_ID_current_state == ID_TRACK_BUTT &&
GetScreen()->m_Active_Layer <= CMP_N ){
bool ItemFree = (GetScreen()->m_CurrentItem == NULL ) ||
(GetScreen()->m_CurrentItem->m_Flags == 0);
if ( ItemFree ){
//no track is currently being edited - select a segment and remove it.
DrawStruct = PcbGeneralLocateAndDisplay();
//don't let backspace delete modules!!
if ( DrawStruct && (DrawStruct->m_StructType == TYPETRACK
|| DrawStruct->m_StructType == TYPEVIA))
Delete_Segment(DC, (TRACK*)DrawStruct);
GetScreen()->SetModify();
}
else if ( GetScreen()->m_CurrentItem->m_StructType == TYPETRACK )
{
//then an element is being edited - remove the last segment.
GetScreen()->m_CurrentItem =
Delete_Segment(DC, (TRACK*)GetScreen()->m_CurrentItem);
GetScreen()->SetModify();
}
}
break;
}
case WXK_END:
DrawPanel->MouseToCursorSchema();
End_Route( (TRACK *) (GetScreen()->m_CurrentItem), DC);
break;
case 'v': // Switch to alternate layer and Place a via if a track is in progress
case 'V':
if ( m_ID_current_state != ID_TRACK_BUTT ) return;
if ( ItemFree )
{
Other_Layer_Route( NULL, DC);
break;
}
if ( GetScreen()->m_CurrentItem->m_StructType != TYPETRACK )
return;
if ( (GetScreen()->m_CurrentItem->m_Flags & IS_NEW) == 0 )
return;
Other_Layer_Route( (TRACK *) GetScreen()->m_CurrentItem, DC);
if ( DisplayOpt.ContrastModeDisplay )
GetScreen()->SetRefreshReq();
break;
case 'r': // Rotation
case 'R':
if ( ItemFree )
module = Locate_Prefered_Module(m_Pcb, CURSEUR_ON_GRILLE);
else if (GetScreen()->m_CurrentItem->m_StructType == TYPEMODULE)
module = (MODULE*)GetScreen()->m_CurrentItem;
if ( module )
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
Rotate_Module(DC, module, 900, TRUE);
}
break;
case 's': // move to other side
case 'S':
if ( ItemFree )
module = Locate_Prefered_Module(m_Pcb, CURSEUR_ON_GRILLE);
else if (GetScreen()->m_CurrentItem->m_StructType == TYPEMODULE)
module = (MODULE*)GetScreen()->m_CurrentItem;
if ( module )
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
Change_Side_Module(module, DC);
}
break;
case 'g':
case 'G': // Start move (and drag) module
g_Drag_Pistes_On = TRUE;
case 'm':
case 'M': // Start move module
if ( PopupOn ) break;
if ( (module = Locate_Prefered_Module(m_Pcb, CURSEUR_ON_GRILLE)) != NULL)
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
StartMove_Module( module, DC);
}
break;
}
}
case WXK_BACK:
{
if( m_ID_current_state == ID_TRACK_BUTT &&
GetScreen()->m_Active_Layer <= CMP_N )
{
bool ItemFree = (GetScreen()->m_CurrentItem == NULL ) ||
(GetScreen()->m_CurrentItem->m_Flags == 0);
if ( ItemFree )
{
//no track is currently being edited - select a segment and remove it.
DrawStruct = PcbGeneralLocateAndDisplay();
//don't let backspace delete modules!!
if ( DrawStruct && (DrawStruct->m_StructType == TYPETRACK
|| DrawStruct->m_StructType == TYPEVIA))
Delete_Segment(DC, (TRACK*)DrawStruct);
GetScreen()->SetModify();
}
else if ( GetScreen()->m_CurrentItem->m_StructType == TYPETRACK )
{
//then an element is being edited - remove the last segment.
GetScreen()->m_CurrentItem =
Delete_Segment(DC, (TRACK*)GetScreen()->m_CurrentItem);
GetScreen()->SetModify();
}
}
break;
}
case WXK_END:
DrawPanel->MouseToCursorSchema();
End_Route( (TRACK *) (GetScreen()->m_CurrentItem), DC);
break;
case 'v': // Switch to alternate layer and Place a via if a track is in progress
case 'V':
if ( m_ID_current_state != ID_TRACK_BUTT ) return;
if ( ItemFree )
{
Other_Layer_Route( NULL, DC);
break;
}
if ( GetScreen()->m_CurrentItem->m_StructType != TYPETRACK )
return;
if ( (GetScreen()->m_CurrentItem->m_Flags & IS_NEW) == 0 )
return;
Other_Layer_Route( (TRACK *) GetScreen()->m_CurrentItem, DC);
if ( DisplayOpt.ContrastModeDisplay )
GetScreen()->SetRefreshReq();
break;
case 'r': // Rotation
case 'R':
if ( ItemFree )
module = Locate_Prefered_Module(m_Pcb,
CURSEUR_ON_GRILLE | IGNORE_LOCKED | MATCH_LAYER );
else if (GetScreen()->m_CurrentItem->m_StructType == TYPEMODULE)
{
module = (MODULE*)GetScreen()->m_CurrentItem;
// @todo: might need to add a layer check in if() below
if( module->IsLocked() )
module = 0; // do not move it.
}
if ( module )
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
Rotate_Module(DC, module, 900, TRUE);
}
break;
case 's': // move to other side
case 'S':
if ( ItemFree )
module = Locate_Prefered_Module(m_Pcb,
CURSEUR_ON_GRILLE | IGNORE_LOCKED | MATCH_LAYER );
else if (GetScreen()->m_CurrentItem->m_StructType == TYPEMODULE)
{
module = (MODULE*)GetScreen()->m_CurrentItem;
// @todo: might need to add a layer check in if() below
if( module->IsLocked() )
module = 0; // do not move it.
}
if ( module )
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
Change_Side_Module(module, DC);
}
break;
case 'L': // toggle module "MODULE_is_LOCKED" status:
case 'l':
// get any module, locked or not locked and toggle its locked status
module = Locate_Prefered_Module( m_Pcb, CURSEUR_ON_GRILLE | MATCH_LAYER );
if( module )
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
module->SetLocked( !module->IsLocked() );
}
break;
case 'g':
case 'G': // Start move (and drag) module
g_Drag_Pistes_On = TRUE;
// fall through
case 'm':
case 'M': // Start move module
if ( PopupOn ) break;
module = Locate_Prefered_Module( m_Pcb,
CURSEUR_ON_GRILLE | IGNORE_LOCKED | MATCH_LAYER );
if( module )
{
GetScreen()->m_CurrentItem = module;
module->Display_Infos(this);
StartMove_Module( module, DC);
}
break;
}
}
/***********************************************************/ /***********************************************************/
void WinEDA_ModuleEditFrame::OnHotKey(wxDC * DC, int hotkey, void WinEDA_ModuleEditFrame::OnHotKey(wxDC * DC, int hotkey,
EDA_BaseStruct * DrawStruct) EDA_BaseStruct * DrawStruct)
/***********************************************************/ /***********************************************************/
/* Gestion des commandes rapides (Raccourcis claviers) concernant l'element /* Gestion des commandes rapides (Raccourcis claviers) concernant l'element
sous le courseur souris sous le courseur souris
...@@ -148,88 +180,88 @@ sous le courseur souris ...@@ -148,88 +180,88 @@ sous le courseur souris
*/ */
{ {
bool PopupOn = GetScreen()->m_CurrentItem && bool PopupOn = GetScreen()->m_CurrentItem &&
GetScreen()->m_CurrentItem->m_Flags; GetScreen()->m_CurrentItem->m_Flags;
if ( hotkey == 0 ) return; if ( hotkey == 0 ) return;
switch (hotkey) switch (hotkey)
{ {
case WXK_DELETE: case WXK_DELETE:
case WXK_NUMPAD_DELETE: case WXK_NUMPAD_DELETE:
if ( PopupOn ) break; if ( PopupOn ) break;
break; break;
case 'r': // Rotation case 'r': // Rotation
case 'R': case 'R':
break; break;
case 'y': // Mirror Y (drawlibpart) case 'y': // Mirror Y (drawlibpart)
case 'Y': case 'Y':
break; break;
case 'x': // Mirror X (drawlibpart) case 'x': // Mirror X (drawlibpart)
case 'X': case 'X':
break; break;
case 'n': case 'n':
case 'N': // Orient 0, no mirror (drawlibpart) case 'N': // Orient 0, no mirror (drawlibpart)
break; break;
case 'm': case 'm':
case 'M': // Start move drawlibpart case 'M': // Start move drawlibpart
if ( PopupOn ) break; if ( PopupOn ) break;
break; break;
} }
} }
/******************************************************************************/ /******************************************************************************/
bool WinEDA_PcbFrame::OnHotkeyDeleteItem(wxDC * DC, EDA_BaseStruct * DrawStruct) bool WinEDA_PcbFrame::OnHotkeyDeleteItem(wxDC * DC, EDA_BaseStruct * DrawStruct)
/******************************************************************************/ /******************************************************************************/
/* Efface l'item pointe par la souris, en reponse a la touche "Del" /* Efface l'item pointe par la souris, en reponse a la touche "Del"
Effet dependant de l'outil selectionne: Effet dependant de l'outil selectionne:
Outil trace de pistes Outil trace de pistes
Efface le segment en cours ou la piste si pas d'element Efface le segment en cours ou la piste si pas d'element
Outil module: Outil module:
Efface le module. Efface le module.
*/ */
{ {
bool ItemFree = (GetScreen()->m_CurrentItem == NULL ) || bool ItemFree = (GetScreen()->m_CurrentItem == NULL ) ||
(GetScreen()->m_CurrentItem->m_Flags == 0); (GetScreen()->m_CurrentItem->m_Flags == 0);
switch ( m_ID_current_state ) switch ( m_ID_current_state )
{ {
case ID_TRACK_BUTT: case ID_TRACK_BUTT:
if ( GetScreen()->m_Active_Layer > CMP_N ) return FALSE; if ( GetScreen()->m_Active_Layer > CMP_N ) return FALSE;
if ( ItemFree ) if ( ItemFree )
{ {
DrawStruct = PcbGeneralLocateAndDisplay(); DrawStruct = PcbGeneralLocateAndDisplay();
if ( DrawStruct && DrawStruct->m_StructType != TYPETRACK ) return FALSE; if ( DrawStruct && DrawStruct->m_StructType != TYPETRACK ) return FALSE;
Delete_Track(DC, (TRACK*)DrawStruct); Delete_Track(DC, (TRACK*)DrawStruct);
} }
else if ( GetScreen()->m_CurrentItem->m_StructType == TYPETRACK ) else if ( GetScreen()->m_CurrentItem->m_StructType == TYPETRACK )
{ {
GetScreen()->m_CurrentItem = GetScreen()->m_CurrentItem =
Delete_Segment(DC, (TRACK*)GetScreen()->m_CurrentItem); Delete_Segment(DC, (TRACK*)GetScreen()->m_CurrentItem);
GetScreen()->SetModify(); GetScreen()->SetModify();
return TRUE; return TRUE;
} }
break; break;
case ID_COMPONENT_BUTT: case ID_COMPONENT_BUTT:
if ( ItemFree ) if ( ItemFree )
{ {
MODULE * module = Locate_Prefered_Module(m_Pcb, CURSEUR_ON_GRILLE); MODULE * module = Locate_Prefered_Module(m_Pcb, CURSEUR_ON_GRILLE);
if ( module == NULL ) return FALSE; if ( module == NULL ) return FALSE;
if( ! IsOK(this, _("Delete module?")) ) return FALSE; if( ! IsOK(this, _("Delete module?")) ) return FALSE;
RemoveStruct(module, DC); RemoveStruct(module, DC);
} }
else return FALSE; else return FALSE;
break; break;
default: default:
return FALSE; return FALSE;
} }
GetScreen()->SetModify(); GetScreen()->SetModify();
GetScreen()->m_CurrentItem = NULL; GetScreen()->m_CurrentItem = NULL;
return TRUE; return TRUE;
} }
/*****************************/ /*****************************/
/* Localisation des elements */ /* Localisation des elements */
/*****************************/ /*****************************/
#include "fctsys.h" #include "fctsys.h"
#include "gr_basic.h" #include "gr_basic.h"
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
/* variables locales */ /* variables locales */
int ux0 , uy0 ,dx, dy, spot_cX, spot_cY; /* Variables utilisees pour int ux0 , uy0 ,dx, dy, spot_cX, spot_cY; /* Variables utilisees pour
la localisation des segments */ la localisation des segments */
/* fonctions locales */ /* fonctions locales */
EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch, int typeloc); EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch, int typeloc);
/**/ /**/
...@@ -24,29 +24,48 @@ EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch, int ...@@ -24,29 +24,48 @@ EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch, int
(ON/OFF grille) choisi (ON/OFF grille) choisi
*/ */
#define SET_REF_POS(ref_pos) if(typeloc == CURSEUR_ON_GRILLE) \ #define SET_REF_POS(ref_pos) if(typeloc == CURSEUR_ON_GRILLE) \
{ ref_pos = ActiveScreen->m_Curseur;} \ { ref_pos = ActiveScreen->m_Curseur;} \
else { ref_pos = ActiveScreen->m_MousePosition; } 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) MODULE * ReturnModule(BOARD * pcb, const wxString & reference)
/*************************************************************/ /*************************************************************/
/* /*
Recherche d'un module par sa reference Recherche d'un module par sa reference
Retourne: Retourne:
un pointeur sur le module un pointeur sur le module
Null si pas localis Null si pas localis
*/ */
{ {
MODULE * Module = pcb->m_Modules; MODULE * Module = pcb->m_Modules;
for( ; Module != NULL ; Module = (MODULE *) Module->Pnext ) for( ; Module != NULL ; Module = (MODULE *) Module->Pnext )
{ {
if( reference.CmpNoCase(Module->m_Reference->m_Text) == 0 ) if( reference.CmpNoCase(Module->m_Reference->m_Text) == 0 )
return Module; return Module;
} }
return NULL; return NULL;
} }
...@@ -59,17 +78,17 @@ D_PAD * ReturnPad(MODULE * module, const wxString & name) ...@@ -59,17 +78,17 @@ D_PAD * ReturnPad(MODULE * module, const wxString & name)
D_PAD * pt_pad ; D_PAD * pt_pad ;
wxString buf; wxString buf;
if( module == NULL ) return NULL; if( module == NULL ) return NULL;
pt_pad = module->m_Pads; pt_pad = module->m_Pads;
for ( ; pt_pad != NULL; pt_pad = (D_PAD*)pt_pad->Pnext ) for ( ; pt_pad != NULL; pt_pad = (D_PAD*)pt_pad->Pnext )
{ {
pt_pad->ReturnStringPadName(buf); pt_pad->ReturnStringPadName(buf);
if( buf.CmpNoCase(name) == 0 ) if( buf.CmpNoCase(name) == 0 )
return pt_pad; return pt_pad;
} }
return(NULL); return(NULL);
} }
...@@ -79,8 +98,8 @@ wxString buf; ...@@ -79,8 +98,8 @@ wxString buf;
EDA_BaseStruct * WinEDA_BasePcbFrame::Locate( int typeloc, int LayerSearch ) EDA_BaseStruct * WinEDA_BasePcbFrame::Locate( int typeloc, int LayerSearch )
/*******************************************************************************/ /*******************************************************************************/
/* General locate function /* General locate function
Display infos relatives to the item found Display infos relatives to the item found
return a pointer to this item ( or NULL ) return a pointer to this item ( or NULL )
*/ */
{ {
TEXTE_PCB * pt_texte_pcb; TEXTE_PCB * pt_texte_pcb;
...@@ -91,96 +110,96 @@ D_PAD* pt_pad; ...@@ -91,96 +110,96 @@ D_PAD* pt_pad;
int masque_layer; int masque_layer;
EDA_BaseStruct * item; EDA_BaseStruct * item;
pt_texte_pcb = Locate_Texte_Pcb(m_Pcb->m_Drawings, LayerSearch, typeloc); pt_texte_pcb = Locate_Texte_Pcb(m_Pcb->m_Drawings, LayerSearch, typeloc);
if(pt_texte_pcb ) // a PCB text is found if(pt_texte_pcb ) // a PCB text is found
{ {
Affiche_Infos_PCB_Texte(this, pt_texte_pcb); Affiche_Infos_PCB_Texte(this, pt_texte_pcb);
return pt_texte_pcb; return pt_texte_pcb;
} }
if ( (DrawSegm = Locate_Segment_Pcb(m_Pcb, LayerSearch, typeloc)) != NULL) if ( (DrawSegm = Locate_Segment_Pcb(m_Pcb, LayerSearch, typeloc)) != NULL)
{ {
Affiche_Infos_DrawSegment(this, DrawSegm); Affiche_Infos_DrawSegment(this, DrawSegm);
return DrawSegm; return DrawSegm;
} }
if ( (item = Locate_Cotation(m_Pcb, LayerSearch, typeloc)) != NULL) return item; if ( (item = Locate_Cotation(m_Pcb, LayerSearch, typeloc)) != NULL) return item;
if ( (item = Locate_MirePcb(m_Pcb->m_Drawings, 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 */ /* Search for tracks and vias, with via priority */
if ( LayerSearch == -1 ) masque_layer = ALL_LAYERS; if ( LayerSearch == -1 ) masque_layer = ALL_LAYERS;
else masque_layer = g_TabOneLayerMask[LayerSearch]; else masque_layer = g_TabOneLayerMask[LayerSearch];
Track = Locate_Pistes( m_Pcb->m_Track, masque_layer,typeloc ); Track = Locate_Pistes( m_Pcb->m_Track, masque_layer,typeloc );
if ( Track != NULL ) if ( Track != NULL )
{ {
TrackLocate = Track ; /* a track or a via is found*/ TrackLocate = Track ; /* a track or a via is found*/
/* Search for a via */ /* Search for a via */
while((TrackLocate = Locate_Pistes(TrackLocate, while((TrackLocate = Locate_Pistes(TrackLocate,
masque_layer,typeloc)) != NULL ) masque_layer,typeloc)) != NULL )
{ {
Track = TrackLocate; Track = TrackLocate;
if(TrackLocate->m_StructType == TYPEVIA) break ; if(TrackLocate->m_StructType == TYPEVIA) break ;
TrackLocate = (TRACK*) TrackLocate->Pnext; TrackLocate = (TRACK*) TrackLocate->Pnext;
} }
Affiche_Infos_Piste(this, Track) ; Affiche_Infos_Piste(this, Track) ;
return Track; return Track;
} }
/* Search for Pads */ /* Search for Pads */
if( (pt_pad = Locate_Any_Pad(m_Pcb, typeloc)) != NULL ) if( (pt_pad = Locate_Any_Pad(m_Pcb, typeloc)) != NULL )
{ {
pt_pad->Display_Infos(this); return pt_pad; pt_pad->Display_Infos(this); return pt_pad;
} }
/* Search for a footprint text */ /* Search for a footprint text */
// First search: locate texts for footprints on copper or component layer // First search: locate texts for footprints on copper or component layer
// Priority to the active layer (component or copper. // 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 // 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 )) if ( (LayerSearch == LAYER_CUIVRE_N) || (LayerSearch == CMP_N ))
{ {
for (module = m_Pcb->m_Modules; module != NULL; module = (MODULE*)module->Pnext) for (module = m_Pcb->m_Modules; module != NULL; module = (MODULE*)module->Pnext)
{ {
TEXTE_MODULE * pt_texte; TEXTE_MODULE * pt_texte;
if ( module->m_Layer != LayerSearch) continue; if ( module->m_Layer != LayerSearch) continue;
pt_texte = LocateTexteModule(m_Pcb, &module, typeloc); pt_texte = LocateTexteModule(m_Pcb, &module, typeloc);
if( pt_texte != NULL ) if( pt_texte != NULL )
{ {
Affiche_Infos_E_Texte(this, module, pt_texte); Affiche_Infos_E_Texte(this, module, pt_texte);
return pt_texte; return pt_texte;
} }
} }
} }
// Now Search footprint texts on all layers // Now Search footprint texts on all layers
module = NULL; module = NULL;
{ {
TEXTE_MODULE * pt_texte; TEXTE_MODULE * pt_texte;
pt_texte = LocateTexteModule(m_Pcb, &module, typeloc); pt_texte = LocateTexteModule(m_Pcb, &module, typeloc);
if( pt_texte != NULL ) if( pt_texte != NULL )
{ {
Affiche_Infos_E_Texte(this, module, pt_texte); Affiche_Infos_E_Texte(this, module, pt_texte);
return pt_texte; return pt_texte;
} }
} }
/* Search for a footprint */ /* Search for a footprint */
if ( (module = Locate_Prefered_Module(m_Pcb, typeloc)) != NULL) if ( (module = Locate_Prefered_Module(m_Pcb, typeloc)) != NULL)
{ {
module->Display_Infos(this); module->Display_Infos(this);
return module; return module;
} }
/* Search for zones */ /* Search for zones */
if( (TrackLocate = Locate_Zone((TRACK*)m_Pcb->m_Zone, if( (TrackLocate = Locate_Zone((TRACK*)m_Pcb->m_Zone,
GetScreen()->m_Active_Layer,typeloc)) != NULL ) GetScreen()->m_Active_Layer,typeloc)) != NULL )
{ {
Affiche_Infos_Piste(this, TrackLocate) ; return TrackLocate; Affiche_Infos_Piste(this, TrackLocate) ; return TrackLocate;
} }
MsgPanel->EraseMsgBox(); MsgPanel->EraseMsgBox();
return NULL; return NULL;
} }
...@@ -189,28 +208,28 @@ TRACK * Locate_Via(BOARD * Pcb, const wxPoint & pos, int layer) ...@@ -189,28 +208,28 @@ TRACK * Locate_Via(BOARD * Pcb, const wxPoint & pos, int layer)
/*******************************************************************/ /*******************************************************************/
/* Localise une via au point pX,pY /* Localise une via au point pX,pY
Si layer < 0 la via sera localisee quelle que soit la couche Si layer < 0 la via sera localisee quelle que soit la couche
Si layer = 0 .. 15 la via sera localisee selon son type: Si layer = 0 .. 15 la via sera localisee selon son type:
- traversante : toutes couches - traversante : toutes couches
- aveugle = entre couches utiles - aveugle = entre couches utiles
- borgnes idem - borgnes idem
Entree : coord du point de reference, couche Entree : coord du point de reference, couche
Sortie: NULL si pas de via Sortie: NULL si pas de via
(TRACK*) adresse de la via (TRACK*) adresse de la via
*/ */
{ {
TRACK * Track; TRACK * Track;
for(Track = Pcb->m_Track; Track != NULL; Track = Track->Next()) for(Track = Pcb->m_Track; Track != NULL; Track = Track->Next())
{ {
if( Track->m_StructType != TYPEVIA) continue; if( Track->m_StructType != TYPEVIA) continue;
if( Track->m_Start != pos) continue; if( Track->m_Start != pos) continue;
if( Track->GetState(BUSY|DELETED) ) continue; if( Track->GetState(BUSY|DELETED) ) continue;
if(layer < 0 ) return(Track); if(layer < 0 ) return(Track);
if ( ((SEGVIA *)Track)->IsViaOnLayer(layer) ) if ( ((SEGVIA *)Track)->IsViaOnLayer(layer) )
return(Track); return(Track);
} }
return(NULL); return(NULL);
} }
...@@ -218,12 +237,12 @@ TRACK * Track; ...@@ -218,12 +237,12 @@ TRACK * Track;
D_PAD * Locate_Pad_Connecte(BOARD * Pcb, TRACK * ptr_piste, int extr) D_PAD * Locate_Pad_Connecte(BOARD * Pcb, TRACK * ptr_piste, int extr)
/********************************************************************/ /********************************************************************/
/* localisation de la pastille connectee au point de piste a tester /* localisation de la pastille connectee au point de piste a tester
entree : ptr_piste: pointeur sur le segment de piste entree : ptr_piste: pointeur sur le segment de piste
extr = flag = START -> debut du segment a tester extr = flag = START -> debut du segment a tester
= END -> fin du segment a tester = END -> fin du segment a tester
retourne: retourne:
un pointeur sur la description de la pastille si localisation un pointeur sur la description de la pastille si localisation
pointeur NULL si pastille non trouvee pointeur NULL si pastille non trouvee
*/ */
{ {
D_PAD * ptr_pad = NULL; D_PAD * ptr_pad = NULL;
...@@ -231,22 +250,22 @@ int masque_layer; ...@@ -231,22 +250,22 @@ int masque_layer;
MODULE * module; MODULE * module;
wxPoint ref_pos; wxPoint ref_pos;
masque_layer = g_TabOneLayerMask[ptr_piste->m_Layer]; masque_layer = g_TabOneLayerMask[ptr_piste->m_Layer];
if( extr == START) if( extr == START)
{ {
ref_pos = ptr_piste->m_Start; ref_pos = ptr_piste->m_Start;
} }
else else
{ {
ref_pos = ptr_piste->m_End; ref_pos = ptr_piste->m_End;
} }
module = Pcb->m_Modules; module = Pcb->m_Modules;
for(; module != NULL; module = (MODULE*) module->Pnext) for(; module != NULL; module = (MODULE*) module->Pnext)
{ {
ptr_pad = Locate_Pads(module, ref_pos, masque_layer) ; ptr_pad = Locate_Pads(module, ref_pos, masque_layer) ;
if ( ptr_pad != NULL ) break ; if ( ptr_pad != NULL ) break ;
} }
return(ptr_pad); return(ptr_pad);
} }
...@@ -255,78 +274,78 @@ wxPoint ref_pos; ...@@ -255,78 +274,78 @@ wxPoint ref_pos;
EDGE_MODULE * Locate_Edge_Module(MODULE * module, int typeloc) EDGE_MODULE * Locate_Edge_Module(MODULE * module, int typeloc)
/****************************************************************/ /****************************************************************/
/* Localisation de segments de contour du type edge MODULE /* Localisation de segments de contour du type edge MODULE
Les contours sont de differents type: Les contours sont de differents type:
simple : succession de droites simple : succession de droites
Arcs de cercles : on a alors debut arc, fin arc , centre Arcs de cercles : on a alors debut arc, fin arc , centre
si debut arc = fin arc : cercle complet si debut arc = fin arc : cercle complet
Retourne: Retourne:
Pointeur sur le segment localise Pointeur sur le segment localise
NULL si rien trouve NULL si rien trouve
*/ */
{ {
EDGE_MODULE * edge_mod; EDGE_MODULE * edge_mod;
EDA_BaseStruct * PtStruct; EDA_BaseStruct * PtStruct;
int uxf, uyf, type_trace; int uxf, uyf, type_trace;
int rayon, dist; int rayon, dist;
wxPoint ref_pos; /* coord du point de localisation */ wxPoint ref_pos; /* coord du point de localisation */
int StAngle, EndAngle, MouseAngle; /* pour localisation d'arcs, int StAngle, EndAngle, MouseAngle; /* pour localisation d'arcs,
angle du point de debut, de fin et du point angle du point de debut, de fin et du point
de reference */ de reference */
if ( ! module ) return NULL; if ( ! module ) return NULL;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
PtStruct = module->m_Drawings; PtStruct = module->m_Drawings;
for ( ;PtStruct != NULL; PtStruct = PtStruct->Pnext ) for ( ;PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPEEDGEMODULE ) continue; if( PtStruct->m_StructType != TYPEEDGEMODULE ) continue;
edge_mod = (EDGE_MODULE *) PtStruct; edge_mod = (EDGE_MODULE *) PtStruct;
type_trace = edge_mod->m_Shape ; type_trace = edge_mod->m_Shape ;
ux0 = edge_mod->m_Start.x; uy0 = edge_mod->m_Start.y; ux0 = edge_mod->m_Start.x; uy0 = edge_mod->m_Start.y;
uxf = edge_mod->m_End.x; uyf = edge_mod->m_End.y; uxf = edge_mod->m_End.x; uyf = edge_mod->m_End.y;
switch(type_trace) switch(type_trace)
{ {
case S_SEGMENT : case S_SEGMENT :
/* recalcul des coordonnees avec ux0,uy0 = origine des coord. */ /* recalcul des coordonnees avec ux0,uy0 = origine des coord. */
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0; spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
dx = uxf - ux0 ; dy = uyf - uy0 ; dx = uxf - ux0 ; dy = uyf - uy0 ;
/* detection : */ /* detection : */
if( distance(edge_mod->m_Width/2) ) return( edge_mod) ; if( distance(edge_mod->m_Width/2) ) return( edge_mod) ;
break; break;
case S_CIRCLE: case S_CIRCLE:
rayon = (int)hypot((double)(uxf-ux0),(double)(uyf-uy0) ); rayon = (int)hypot((double)(uxf-ux0),(double)(uyf-uy0) );
dist = (int)hypot((double)(ref_pos.x - ux0),(double)(ref_pos.y - 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); if(abs(rayon-dist) <= edge_mod->m_Width) return(edge_mod);
break; break;
case S_ARC: case S_ARC:
rayon = (int)hypot((double)(uxf-ux0),(double)(uyf-uy0) ); rayon = (int)hypot((double)(uxf-ux0),(double)(uyf-uy0) );
dist = (int)hypot((double)(ref_pos.x - ux0),(double)(ref_pos.y - uy0) ); dist = (int)hypot((double)(ref_pos.x - ux0),(double)(ref_pos.y - uy0) );
if(abs(rayon-dist) > edge_mod->m_Width) break; if(abs(rayon-dist) > edge_mod->m_Width) break;
/* pour un arc, controle complementaire */ /* pour un arc, controle complementaire */
MouseAngle = (int) ArcTangente(ref_pos.y - uy0, ref_pos.x - ux0); MouseAngle = (int) ArcTangente(ref_pos.y - uy0, ref_pos.x - ux0);
StAngle = (int) ArcTangente(uyf - uy0, uxf - ux0); StAngle = (int) ArcTangente(uyf - uy0, uxf - ux0);
EndAngle = StAngle + edge_mod->m_Angle; EndAngle = StAngle + edge_mod->m_Angle;
if( EndAngle > 3600 ) if( EndAngle > 3600 )
{ {
StAngle -= 3600; EndAngle -= 3600; StAngle -= 3600; EndAngle -= 3600;
} }
if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) ) if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) )
return(edge_mod); return(edge_mod);
break; break;
} }
} }
return(NULL) ; return(NULL) ;
} }
...@@ -334,8 +353,8 @@ int StAngle, EndAngle, MouseAngle; /* pour localisation d'arcs, ...@@ -334,8 +353,8 @@ int StAngle, EndAngle, MouseAngle; /* pour localisation d'arcs,
EDA_BaseStruct * Locate_Cotation(BOARD * Pcb, int LayerSearch, int typeloc) EDA_BaseStruct * Locate_Cotation(BOARD * Pcb, int LayerSearch, int typeloc)
/*************************************************************************/ /*************************************************************************/
/* Serach for a cotation item , on LayerSearch, /* Serach for a cotation item , on LayerSearch,
(if LayerSearch == -1 , no yaere restriction ) (if LayerSearch == -1 , no yaere restriction )
return a pointer to the located item, or NULL return a pointer to the located item, or NULL
*/ */
{ {
EDA_BaseStruct * PtStruct; EDA_BaseStruct * PtStruct;
...@@ -344,184 +363,184 @@ TEXTE_PCB* pt_txt; ...@@ -344,184 +363,184 @@ TEXTE_PCB* pt_txt;
wxPoint ref_pos; wxPoint ref_pos;
int ux0, uy0; int ux0, uy0;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
PtStruct = Pcb->m_Drawings; PtStruct = Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPECOTATION ) continue; if( PtStruct->m_StructType != TYPECOTATION ) continue;
Cotation = (COTATION*) PtStruct; Cotation = (COTATION*) PtStruct;
if( (Cotation->m_Layer != LayerSearch) && (LayerSearch != -1) ) if( (Cotation->m_Layer != LayerSearch) && (LayerSearch != -1) )
continue; continue;
/* Localisation du texte ? */ /* Localisation du texte ? */
pt_txt = Cotation->m_Text; pt_txt = Cotation->m_Text;
if( pt_txt ) if( pt_txt )
{ {
if( pt_txt->Locate(ref_pos) ) return(PtStruct); if( pt_txt->Locate(ref_pos) ) return(PtStruct);
} }
/* Localisation des SEGMENTS ?) */ /* Localisation des SEGMENTS ?) */
ux0 = Cotation->Barre_ox ; uy0 = Cotation->Barre_oy; ux0 = Cotation->Barre_ox ; uy0 = Cotation->Barre_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx =Cotation->Barre_fx - ux0 ; dy = Cotation->Barre_fy - uy0 ; dx =Cotation->Barre_fx - ux0 ; dy = Cotation->Barre_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
ux0 = Cotation->TraitG_ox ; uy0 = Cotation->TraitG_oy; ux0 = Cotation->TraitG_ox ; uy0 = Cotation->TraitG_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->TraitG_fx - ux0 ; dy = Cotation->TraitG_fy - uy0 ; dx = Cotation->TraitG_fx - ux0 ; dy = Cotation->TraitG_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
ux0 = Cotation->TraitD_ox ; uy0 = Cotation->TraitD_oy; ux0 = Cotation->TraitD_ox ; uy0 = Cotation->TraitD_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->TraitD_fx - ux0 ; dy = Cotation->TraitD_fy - uy0 ; dx = Cotation->TraitD_fx - ux0 ; dy = Cotation->TraitD_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
ux0 = Cotation->FlecheD1_ox ; uy0 = Cotation->FlecheD1_oy; ux0 = Cotation->FlecheD1_ox ; uy0 = Cotation->FlecheD1_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheD1_fx - ux0 ; dy = Cotation->FlecheD1_fy - uy0 ; dx = Cotation->FlecheD1_fx - ux0 ; dy = Cotation->FlecheD1_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
ux0 = Cotation->FlecheD2_ox ; uy0 = Cotation->FlecheD2_oy; ux0 = Cotation->FlecheD2_ox ; uy0 = Cotation->FlecheD2_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheD2_fx - ux0 ; dy = Cotation->FlecheD2_fy - uy0 ; dx = Cotation->FlecheD2_fx - ux0 ; dy = Cotation->FlecheD2_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
ux0 = Cotation->FlecheG1_ox ; uy0 = Cotation->FlecheG1_oy; ux0 = Cotation->FlecheG1_ox ; uy0 = Cotation->FlecheG1_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheG1_fx - ux0 ; dy = Cotation->FlecheG1_fy - uy0 ; dx = Cotation->FlecheG1_fx - ux0 ; dy = Cotation->FlecheG1_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
ux0 = Cotation->FlecheG2_ox ; uy0 = Cotation->FlecheG2_oy; ux0 = Cotation->FlecheG2_ox ; uy0 = Cotation->FlecheG2_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheG2_fx - ux0 ; dy = Cotation->FlecheG2_fy - uy0 ; dx = Cotation->FlecheG2_fx - ux0 ; dy = Cotation->FlecheG2_fy - uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( distance( Cotation->m_Width/2 )) return( PtStruct ); if( distance( Cotation->m_Width/2 )) return( PtStruct );
} }
return(NULL); return(NULL);
} }
/*************************************************************************/ /*************************************************************************/
DRAWSEGMENT * Locate_Segment_Pcb(BOARD * Pcb, int LayerSearch, int typeloc) DRAWSEGMENT * Locate_Segment_Pcb(BOARD * Pcb, int LayerSearch, int typeloc)
/*************************************************************************/ /*************************************************************************/
/* Localisation de segments de contour du type drawing /* Localisation de segments de contour du type drawing
Retourne: Retourne:
Pointeur sur DEBUT du segment localise Pointeur sur DEBUT du segment localise
NULL si rien trouve NULL si rien trouve
Le segment sur la couche active est dtect en priorite Le segment sur la couche active est dtect en priorite
*/ */
{ {
EDA_BaseStruct * PtStruct; EDA_BaseStruct * PtStruct;
DRAWSEGMENT * pts, *locate_segm = NULL; DRAWSEGMENT * pts, *locate_segm = NULL;
wxPoint ref_pos; wxPoint ref_pos;
PCB_SCREEN *screen = (PCB_SCREEN *)ActiveScreen; PCB_SCREEN *screen = (PCB_SCREEN *)ActiveScreen;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
PtStruct = Pcb->m_Drawings; PtStruct = Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue; if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue;
pts = ( DRAWSEGMENT * ) PtStruct; pts = ( DRAWSEGMENT * ) PtStruct;
if ( (pts->m_Layer != LayerSearch) && (LayerSearch != -1) ) if ( (pts->m_Layer != LayerSearch) && (LayerSearch != -1) )
continue; continue;
ux0 = pts->m_Start.x ; uy0 = pts->m_Start.y; ux0 = pts->m_Start.x ; uy0 = pts->m_Start.y;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = pts->m_End.x - ux0 ; dy = pts->m_End.y - uy0 ; dx = pts->m_End.x - ux0 ; dy = pts->m_End.y - uy0 ;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0 ;
/* detection : */ /* detection : */
if( (pts->m_Shape == S_CIRCLE) || (pts->m_Shape == S_ARC) ) if( (pts->m_Shape == S_CIRCLE) || (pts->m_Shape == S_ARC) )
{ {
int rayon, dist, StAngle, EndAngle, MouseAngle; int rayon, dist, StAngle, EndAngle, MouseAngle;
rayon = (int) hypot((double)(dx),(double)(dy) ); rayon = (int) hypot((double)(dx),(double)(dy) );
dist = (int) hypot((double)(spot_cX),(double)(spot_cY) ); dist = (int) hypot((double)(spot_cX),(double)(spot_cY) );
if( abs(rayon-dist) <= (pts->m_Width/2) ) if( abs(rayon-dist) <= (pts->m_Width/2) )
{ {
if(pts->m_Shape == S_CIRCLE) if(pts->m_Shape == S_CIRCLE)
{ {
if(pts->m_Layer == screen->m_Active_Layer) if(pts->m_Layer == screen->m_Active_Layer)
return( pts ) ; return( pts ) ;
else if ( ! locate_segm ) locate_segm = pts; else if ( ! locate_segm ) locate_segm = pts;
} }
/* pour un arc, controle complementaire */ /* pour un arc, controle complementaire */
MouseAngle = (int) ArcTangente(spot_cY, spot_cX); MouseAngle = (int) ArcTangente(spot_cY, spot_cX);
StAngle = (int) ArcTangente(dy, dx); StAngle = (int) ArcTangente(dy, dx);
EndAngle = StAngle + pts->m_Angle; EndAngle = StAngle + pts->m_Angle;
if( EndAngle > 3600 ) if( EndAngle > 3600 )
{ {
StAngle -= 3600; EndAngle -= 3600; StAngle -= 3600; EndAngle -= 3600;
} }
if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) ) if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) )
{ {
if(pts->m_Layer == screen->m_Active_Layer) if(pts->m_Layer == screen->m_Active_Layer)
return( pts ) ; return( pts ) ;
else if ( ! locate_segm ) locate_segm = pts; else if ( ! locate_segm ) locate_segm = pts;
} }
} }
} }
else else
{ {
if( distance( pts->m_Width /2 ) ) if( distance( pts->m_Width /2 ) )
{ {
if(pts->m_Layer == screen->m_Active_Layer) if(pts->m_Layer == screen->m_Active_Layer)
return( pts ) ; return( pts ) ;
else if ( ! locate_segm ) locate_segm = pts; else if ( ! locate_segm ) locate_segm = pts;
} }
} }
} }
return(locate_segm) ; return(locate_segm) ;
} }
/*************************************************/ /*************************************************/
/* D_PAD * Locate_Any_Pad(int typeloc, bool OnlyCurrentLayer) */ /* 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 ref_pos, bool OnlyCurrentLayer) */
/*************************************************/ /*************************************************/
/* /*
localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
par la souris, recherche faite sur toutes les empreintes. par la souris, recherche faite sur toutes les empreintes.
entree : entree :
- coord souris - coord souris
ou ref_pos ou ref_pos
retourne: retourne:
pointeur sur la description de la pastille si localisation pointeur sur la description de la pastille si localisation
pointeur NULL si pastille non trouvee pointeur NULL si pastille non trouvee
num_empr = numero d'empreinte du pad num_empr = numero d'empreinte du pad
la priorit est donne a la couche active la priorit est donne a la couche active
*/ */
D_PAD * Locate_Any_Pad(BOARD * Pcb, int typeloc, bool OnlyCurrentLayer) D_PAD * Locate_Any_Pad(BOARD * Pcb, int typeloc, bool OnlyCurrentLayer)
{ {
wxPoint ref_pos; wxPoint ref_pos;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
return(Locate_Any_Pad(Pcb, ref_pos, OnlyCurrentLayer)) ; return(Locate_Any_Pad(Pcb, ref_pos, OnlyCurrentLayer)) ;
} }
D_PAD * Locate_Any_Pad(BOARD * Pcb, const wxPoint & ref_pos, bool OnlyCurrentLayer) D_PAD * Locate_Any_Pad(BOARD * Pcb, const wxPoint & ref_pos, bool OnlyCurrentLayer)
...@@ -529,45 +548,45 @@ D_PAD * Locate_Any_Pad(BOARD * Pcb, const wxPoint & ref_pos, bool OnlyCurrentLay ...@@ -529,45 +548,45 @@ D_PAD * Locate_Any_Pad(BOARD * Pcb, const wxPoint & ref_pos, bool OnlyCurrentLay
D_PAD * pt_pad ; D_PAD * pt_pad ;
MODULE * module; MODULE * module;
int layer_mask = g_TabOneLayerMask[ ((PCB_SCREEN*)ActiveScreen)->m_Active_Layer]; int layer_mask = g_TabOneLayerMask[ ((PCB_SCREEN*)ActiveScreen)->m_Active_Layer];
module = Pcb->m_Modules; module = Pcb->m_Modules;
for( ; module != NULL ; module = (MODULE *) module->Pnext ) for( ; module != NULL ; module = (MODULE *) module->Pnext )
{ {
/* First: Search a pad on the active layer: */ /* First: Search a pad on the active layer: */
if ( (pt_pad = Locate_Pads(module, ref_pos,layer_mask) ) != NULL ) if ( (pt_pad = Locate_Pads(module, ref_pos,layer_mask) ) != NULL )
return(pt_pad) ; return(pt_pad) ;
/* If not found, search on other layers: */ /* If not found, search on other layers: */
if ( ! OnlyCurrentLayer ) if ( ! OnlyCurrentLayer )
{ {
if ( (pt_pad = Locate_Pads(module, ref_pos,ALL_LAYERS) ) != NULL ) if ( (pt_pad = Locate_Pads(module, ref_pos,ALL_LAYERS) ) != NULL )
return(pt_pad) ; return(pt_pad) ;
} }
} }
return(NULL) ; return(NULL) ;
} }
/******************************************************************************/ /******************************************************************************/
/* D_PAD* Locate_Pads(MODULE * module, int masque_layer,int typeloc) */ /* D_PAD* Locate_Pads(MODULE * module, int masque_layer,int typeloc) */
/* D_PAD* Locate_Pads(MODULE * module, const wxPoint & ref_pos,int masque_layer) */ /* 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 /* localisation de la pastille pointee par la coordonnee ref_pos.x,,ref_pos.y, ou
par la souris, concernant l'empreinte en cours. par la souris, concernant l'empreinte en cours.
entree : entree :
- parametres generaux de l'empreinte mise a jour par caract() - parametres generaux de l'empreinte mise a jour par caract()
- masque_layer = couche(s) (bit_masque)sur laquelle doit etre la pastille - masque_layer = couche(s) (bit_masque)sur laquelle doit etre la pastille
retourne: retourne:
un pointeur sur la description de la pastille si localisation un pointeur sur la description de la pastille si localisation
pointeur NULL si pastille non trouvee pointeur NULL si pastille non trouvee
*/ */
D_PAD * Locate_Pads(MODULE * module, int masque_layer,int typeloc) D_PAD * Locate_Pads(MODULE * module, int masque_layer,int typeloc)
{ {
wxPoint ref_pos; wxPoint ref_pos;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
return(Locate_Pads(module, ref_pos, masque_layer) ); return(Locate_Pads(module, ref_pos, masque_layer) );
} }
...@@ -577,45 +596,45 @@ D_PAD * pt_pad ; ...@@ -577,45 +596,45 @@ D_PAD * pt_pad ;
int deltaX, deltaY; int deltaX, deltaY;
wxPoint shape_pos; wxPoint shape_pos;
double dist; double dist;
pt_pad = module->m_Pads; pt_pad = module->m_Pads;
for ( ; pt_pad != NULL; pt_pad = (D_PAD*)pt_pad->Pnext ) for ( ; pt_pad != NULL; pt_pad = (D_PAD*)pt_pad->Pnext )
{ {
shape_pos = pt_pad->ReturnShapePos(); shape_pos = pt_pad->ReturnShapePos();
ux0 = shape_pos.x; uy0 = shape_pos.y; /* pos x,y du centre du pad */ 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; deltaX = ref_pos.x - ux0; deltaY = ref_pos.y - uy0;
/* Test rapide: le point a tester doit etre a l'interieur du cercle /* Test rapide: le point a tester doit etre a l'interieur du cercle
exinscrit ... */ exinscrit ... */
if ( (abs(deltaX) > pt_pad->m_Rayon ) || if ( (abs(deltaX) > pt_pad->m_Rayon ) ||
(abs(deltaY) > pt_pad->m_Rayon) ) (abs(deltaY) > pt_pad->m_Rayon) )
continue; continue;
/* ... et sur la bonne couche */ /* ... et sur la bonne couche */
if( (pt_pad->m_Masque_Layer & masque_layer) == 0) continue ; if( (pt_pad->m_Masque_Layer & masque_layer) == 0) continue ;
/* calcul des demi dim dx et dy */ /* calcul des demi dim dx et dy */
dx = pt_pad->m_Size.x >> 1; // dx also is the radius for rounded pads dx = pt_pad->m_Size.x >> 1; // dx also is the radius for rounded pads
dy = pt_pad->m_Size.y >> 1; dy = pt_pad->m_Size.y >> 1;
/* localisation ? */ /* localisation ? */
switch (pt_pad->m_PadShape & 0x7F) switch (pt_pad->m_PadShape & 0x7F)
{ {
case CIRCLE : case CIRCLE :
dist = hypot(deltaX, deltaY); dist = hypot(deltaX, deltaY);
if ( (int)(round(dist)) <= dx ) return(pt_pad) ; if ( (int)(round(dist)) <= dx ) return(pt_pad) ;
break; break;
default: default:
/* calcul des coord du point test dans le repere du Pad */ /* calcul des coord du point test dans le repere du Pad */
RotatePoint(&deltaX, &deltaY, - pt_pad->m_Orient); RotatePoint(&deltaX, &deltaY, - pt_pad->m_Orient);
if ( (abs(deltaX) <= dx ) && (abs(deltaY) <= dy) ) if ( (abs(deltaX) <= dx ) && (abs(deltaY) <= dy) )
return(pt_pad) ; return(pt_pad) ;
break; break;
} }
} }
return(NULL); return(NULL);
} }
...@@ -624,88 +643,101 @@ MODULE * Locate_Prefered_Module(BOARD * Pcb, int typeloc) ...@@ -624,88 +643,101 @@ MODULE * Locate_Prefered_Module(BOARD * Pcb, int typeloc)
/********************************************************/ /********************************************************/
/* /*
localisation d'une empreinte par son rectangle d'encadrement localisation d'une empreinte par son rectangle d'encadrement
Si plusieurs empreintes sont possibles, la priorite est: Si plusieurs empreintes sont possibles, la priorite est:
- sur la couche active - sur la couche active
- la plus petite - la plus petite
*/ */
{ {
MODULE * pt_module; MODULE* pt_module;
int lx , ly; /* dimensions du rectangle d'encadrement du module */ int lx, ly; /* dimensions du rectangle d'encadrement du module */
MODULE * module = NULL, /* module localise sur la couche active */ MODULE* module = NULL; /* module localise sur la couche active */
* Altmodule = NULL; /* module localise sur les couches non actives */ MODULE* Altmodule = NULL; /* module localise sur les couches non actives */
int min_dim = 0x7FFFFFFF, /* dim mini du module localise sur la couche active */ int min_dim = 0x7FFFFFFF; /* dim mini du module localise sur la couche active */
alt_min_dim = 0x7FFFFFFF; /* dim mini du module localise sur les couches non actives */ int alt_min_dim = 0x7FFFFFFF; /* dim mini du module localise sur les couches non actives */
int layer; /* pour calcul de couches prioritaires */ int layer; /* pour calcul de couches prioritaires */
wxPoint ref_pos; /* coord du point de reference pour la localisation */ wxPoint ref_pos; /* coord du point de reference pour la localisation */
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
pt_module = Pcb->m_Modules; pt_module = Pcb->m_Modules;
for( ; pt_module != NULL ; pt_module = (MODULE *) pt_module->Pnext ) for( ; pt_module; pt_module = (MODULE*) pt_module->Pnext )
{ {
/* calcul des dimensions du cadre :*/ /* calcul des dimensions du cadre :*/
lx = pt_module->m_BoundaryBox.GetWidth(); lx = pt_module->m_BoundaryBox.GetWidth();
ly = pt_module->m_BoundaryBox.GetHeight(); ly = pt_module->m_BoundaryBox.GetHeight();
/* Calcul des coord souris dans le repere module */ /* Calcul des coord souris dans le repere module */
spot_cX = ref_pos.x - pt_module->m_Pos.x; spot_cX = ref_pos.x - pt_module->m_Pos.x;
spot_cY = ref_pos.y - pt_module->m_Pos.y; spot_cY = ref_pos.y - pt_module->m_Pos.y;
RotatePoint(&spot_cX, &spot_cY, - pt_module->m_Orient); RotatePoint(&spot_cX, &spot_cY, - pt_module->m_Orient);
/* la souris est-elle dans ce rectangle : */ /* la souris est-elle dans ce rectangle : */
if( ! pt_module->m_BoundaryBox.Inside(spot_cX, spot_cY) ) if( ! pt_module->m_BoundaryBox.Inside(spot_cX, spot_cY) )
continue; continue;
/* Localisation: test des dimensions minimales, choix du meilleur candidat */ // if caller wants to ignore locked modules, and this one is locked, skip it.
if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() )
/* calcul de priorite: la priorite est donnee a la couche continue;
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 /* Localisation: test des dimensions minimales, choix du meilleur candidat */
est sur couche serigr,adhesive composant */
layer = pt_module->m_Layer; /* calcul de priorite: la priorite est donnee a la couche
if( (layer == ADHESIVE_N_CU) || (layer == SILKSCREEN_N_CU) ) d'appartenance du module et a la couche cuivre si le module
layer = CUIVRE_N; est sur couche serigr,adhesive cuivre, a la couche cmp si le module
if( (layer == ADHESIVE_N_CMP) || (layer == SILKSCREEN_N_CMP) ) est sur couche serigr,adhesive composant */
layer = CMP_N; layer = pt_module->m_Layer;
if( ((PCB_SCREEN*)ActiveScreen)->m_Active_Layer == layer ) if( layer==ADHESIVE_N_CU || layer==SILKSCREEN_N_CU )
{ layer = CUIVRE_N;
if( min(lx,ly) <= min_dim )
{ /* meilleure empreinte localisee sur couche active */ else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
module = pt_module ; min_dim = min(lx,ly) ; layer = CMP_N;
}
} if( ((PCB_SCREEN*)ActiveScreen)->m_Active_Layer == layer )
{
else if( min(lx,ly) <= min_dim )
{ {
if( min(lx,ly) <= alt_min_dim ) /* meilleure empreinte localisee sur couche active */
{ /* meilleure empreinte localisee sur autres couches */ module = pt_module ; min_dim = min(lx,ly) ;
Altmodule = pt_module ; alt_min_dim = min(lx,ly) ; }
} }
}
} /* fin boucle d'examen des modules */ else if( !(typeloc & MATCH_LAYER)
&& ( !(typeloc & VISIBLE_ONLY) || IsModuleLayerVisible( layer )) )
if(module) {
{ if( min(lx,ly) <= alt_min_dim )
return(module); {
} /* meilleure empreinte localisee sur autres couches */
if(Altmodule) Altmodule = pt_module;
{ alt_min_dim = min(lx,ly);
return(Altmodule); }
} }
return(NULL); }
if( module )
{
return module;
}
if( Altmodule )
{
return Altmodule;
}
return NULL;
} }
/*****************************************************************************/ /*****************************************************************************/
TEXTE_MODULE * LocateTexteModule(BOARD * Pcb, MODULE ** PtModule, int typeloc) TEXTE_MODULE * LocateTexteModule(BOARD * Pcb, MODULE ** PtModule, int typeloc)
/*****************************************************************************/ /*****************************************************************************/
/* localisation du texte pointe par la souris (texte sur empreinte) /* localisation du texte pointe par la souris (texte sur empreinte)
si * PtModule == NULL; recherche sur tous les modules si * PtModule == NULL; recherche sur tous les modules
sinon sur le module pointe par module sinon sur le module pointe par module
retourne retourne
- pointeur sur le texte localise ( ou NULL ) - pointeur sur le texte localise ( ou NULL )
- si Ptmodule != NULL: pointeur sur module module ( non modifie sinon ) - si Ptmodule != NULL: pointeur sur module module ( non modifie sinon )
*/ */
{ {
EDA_BaseStruct * PtStruct; EDA_BaseStruct * PtStruct;
...@@ -713,65 +745,65 @@ TEXTE_MODULE * pt_txt_mod ; ...@@ -713,65 +745,65 @@ TEXTE_MODULE * pt_txt_mod ;
MODULE * module; MODULE * module;
wxPoint ref_pos; wxPoint ref_pos;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
module = * PtModule; module = * PtModule;
if( module == NULL ) if( module == NULL )
{ {
module = Pcb->m_Modules; module = Pcb->m_Modules;
} }
for( ; module != NULL; module = (MODULE*)module->Pnext ) for( ; module != NULL; module = (MODULE*)module->Pnext )
{ {
pt_txt_mod = module->m_Reference; pt_txt_mod = module->m_Reference;
/* la souris est-elle dans le rectangle autour du texte*/ /* la souris est-elle dans le rectangle autour du texte*/
if( pt_txt_mod->Locate(ref_pos) ) if( pt_txt_mod->Locate(ref_pos) )
{ {
if( PtModule) *PtModule = module; if( PtModule) *PtModule = module;
return(pt_txt_mod); return(pt_txt_mod);
} }
pt_txt_mod = module->m_Value; pt_txt_mod = module->m_Value;
/* la souris est-elle dans le rectangle autour du texte*/ /* la souris est-elle dans le rectangle autour du texte*/
if( pt_txt_mod->Locate(ref_pos) ) if( pt_txt_mod->Locate(ref_pos) )
{ {
if( PtModule) *PtModule = module; if( PtModule) *PtModule = module;
return(pt_txt_mod); return(pt_txt_mod);
} }
PtStruct = module->m_Drawings; PtStruct = module->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPETEXTEMODULE ) continue; if( PtStruct->m_StructType != TYPETEXTEMODULE ) continue;
pt_txt_mod = (TEXTE_MODULE*) PtStruct; pt_txt_mod = (TEXTE_MODULE*) PtStruct;
/* la souris est-elle dans le rectangle autour du texte*/ /* la souris est-elle dans le rectangle autour du texte*/
if( pt_txt_mod->Locate(ref_pos) ) if( pt_txt_mod->Locate(ref_pos) )
{ {
if( PtModule) *PtModule = module; if( PtModule) *PtModule = module;
return(pt_txt_mod); return(pt_txt_mod);
} }
} }
if( *PtModule != NULL ) break; /* Recherche limitee a 1 seul module */ if( *PtModule != NULL ) break; /* Recherche limitee a 1 seul module */
} }
return(NULL) ; return(NULL) ;
} }
/**************************************************************/ /**************************************************************/
TRACK * Locate_Piste_Connectee( TRACK * PtRefSegm, TRACK * pt_base, TRACK * Locate_Piste_Connectee( TRACK * PtRefSegm, TRACK * pt_base,
TRACK * pt_lim, int extr) TRACK * pt_lim, int extr)
/**************************************************************/ /**************************************************************/
/* recherche le segment connecte au segment pointe par /* recherche le segment connecte au segment pointe par
PtRefSegm: PtRefSegm:
si int extr = START, le point de debut du segment est utilise si int extr = START, le point de debut du segment est utilise
si int extr = END, le point de fin 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 ne se fait que sur les EXTREMITES des segments
La recherche se fait de l'adresse : La recherche se fait de l'adresse :
pt_base a pt_lim (borne finale comprise) pt_base a pt_lim (borne finale comprise)
si pt_lim = NULL, la recherche se fait jusqu'a la fin de la liste 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 Afin d'accelerer la recherche, une 1ere passe est faite, avec une recherche
realisee sur un ensemble de +/- 100 points autour du point courant. realisee sur un ensemble de +/- 100 points autour du point courant.
Si echec: recherche generale Si echec: recherche generale
*/ */
{ {
TRACK * PtSegmB, * PtSegmN; TRACK * PtSegmB, * PtSegmN;
...@@ -779,191 +811,191 @@ int Reflayer; ...@@ -779,191 +811,191 @@ int Reflayer;
wxPoint pos_ref; wxPoint pos_ref;
int ii; int ii;
if ( extr == START) pos_ref = PtRefSegm->m_Start; if ( extr == START) pos_ref = PtRefSegm->m_Start;
else pos_ref = PtRefSegm->m_End; else pos_ref = PtRefSegm->m_End;
Reflayer = PtRefSegm->ReturnMaskLayer(); Reflayer = PtRefSegm->ReturnMaskLayer();
/* 1ere passe */ /* 1ere passe */
PtSegmB = PtSegmN = PtRefSegm; PtSegmB = PtSegmN = PtRefSegm;
for ( ii = 0; ii < 50; ii++ ) for ( ii = 0; ii < 50; ii++ )
{ {
if( (PtSegmN == NULL) && (PtSegmB == NULL) ) break; if( (PtSegmN == NULL) && (PtSegmB == NULL) ) break;
if( PtSegmN ) if( PtSegmN )
{ {
if( PtSegmN->GetState(BUSY|DELETED) ) goto suite; if( PtSegmN->GetState(BUSY|DELETED) ) goto suite;
if (PtSegmN == PtRefSegm) goto suite; if (PtSegmN == PtRefSegm) goto suite;
if( pos_ref == PtSegmN->m_Start ) if( pos_ref == PtSegmN->m_Start )
{ /* Test des couches */ { /* Test des couches */
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN); if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
} }
if( pos_ref == PtSegmN->m_End ) if( pos_ref == PtSegmN->m_End )
{ /* Test des couches */ { /* Test des couches */
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN); if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
} }
suite: suite:
if( PtSegmN == pt_lim ) PtSegmN = NULL; if( PtSegmN == pt_lim ) PtSegmN = NULL;
else PtSegmN = (TRACK*)PtSegmN->Pnext; else PtSegmN = (TRACK*)PtSegmN->Pnext;
} }
if( PtSegmB ) if( PtSegmB )
{ {
if(PtSegmB->GetState(BUSY|DELETED) ) goto suite1; if(PtSegmB->GetState(BUSY|DELETED) ) goto suite1;
if (PtSegmB == PtRefSegm) goto suite1; if (PtSegmB == PtRefSegm) goto suite1;
if( pos_ref == PtSegmB->m_Start ) if( pos_ref == PtSegmB->m_Start )
{ /* Test des couches */ { /* Test des couches */
if(Reflayer & PtSegmB->ReturnMaskLayer() )return(PtSegmB); if(Reflayer & PtSegmB->ReturnMaskLayer() )return(PtSegmB);
} }
if( pos_ref == PtSegmB->m_End ) if( pos_ref == PtSegmB->m_End )
{ /* Test des couches */ { /* Test des couches */
if(Reflayer & PtSegmB->ReturnMaskLayer() )return(PtSegmB); if(Reflayer & PtSegmB->ReturnMaskLayer() )return(PtSegmB);
} }
suite1: suite1:
if( PtSegmB == pt_base ) PtSegmB = NULL; if( PtSegmB == pt_base ) PtSegmB = NULL;
else if( PtSegmB->m_StructType != TYPEPCB) PtSegmB = (TRACK*)PtSegmB->Pback; else if( PtSegmB->m_StructType != TYPEPCB) PtSegmB = (TRACK*)PtSegmB->Pback;
else PtSegmB = NULL; else PtSegmB = NULL;
} }
} }
/* Recherche generale */ /* Recherche generale */
for ( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = (TRACK*) PtSegmN->Pnext ) for ( PtSegmN = pt_base; PtSegmN != NULL; PtSegmN = (TRACK*) PtSegmN->Pnext )
{ {
if(PtSegmN->GetState(DELETED|BUSY)) if(PtSegmN->GetState(DELETED|BUSY))
{ {
if (PtSegmN == pt_lim ) break; if (PtSegmN == pt_lim ) break;
continue; continue;
} }
if (PtSegmN == PtRefSegm) if (PtSegmN == PtRefSegm)
{ {
if (PtSegmN == pt_lim ) break; if (PtSegmN == pt_lim ) break;
continue; continue;
} }
if( pos_ref == PtSegmN->m_Start ) if( pos_ref == PtSegmN->m_Start )
{ /* Test des couches */ { /* Test des couches */
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN); if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
} }
if( pos_ref == PtSegmN->m_End ) if( pos_ref == PtSegmN->m_End )
{ /* Test des couches */ { /* Test des couches */
if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN); if(Reflayer & PtSegmN->ReturnMaskLayer() )return(PtSegmN);
} }
if (PtSegmN == pt_lim ) break; if (PtSegmN == pt_lim ) break;
} }
return (NULL); return (NULL);
} }
/****************************************************************************/ /****************************************************************************/
/* TRACK *Locate_Pistes(TRACK * start_adresse, int MasqueLayer,int typeloc) */ /* TRACK *Locate_Pistes(TRACK * start_adresse, int MasqueLayer,int typeloc) */
/* TRACK *Locate_Pistes(TRACK * start_adresse, int ref_pos.x, int ref_pos.y,*/ /* TRACK *Locate_Pistes(TRACK * start_adresse, int ref_pos.x, int ref_pos.y,*/
/* int MasqueLayer) */ /* int MasqueLayer) */
/****************************************************************************/ /****************************************************************************/
/* /*
1 - routine de localisation du segment de piste pointe par la souris. 1 - routine de localisation du segment de piste pointe par la souris.
2 - routine de localisation du segment de piste pointe par le point 2 - routine de localisation du segment de piste pointe par le point
ref_pos.x , ref_pos.y.r ref_pos.x , ref_pos.y.r
La recherche commence a l'adresse start_adresse La recherche commence a l'adresse start_adresse
*/ */
TRACK * Locate_Pistes(TRACK * start_adresse,int MasqueLayer, int typeloc ) TRACK * Locate_Pistes(TRACK * start_adresse,int MasqueLayer, int typeloc )
{ {
wxPoint ref_pos; wxPoint ref_pos;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
return( Locate_Pistes(start_adresse, ref_pos,MasqueLayer) ); return( Locate_Pistes(start_adresse, ref_pos,MasqueLayer) );
} }
TRACK * Locate_Pistes(TRACK * start_adresse, const wxPoint & ref_pos,int MasqueLayer) TRACK * Locate_Pistes(TRACK * start_adresse, const wxPoint & ref_pos,int MasqueLayer)
{ {
TRACK * Track; /* pointeur sur les pistes */ TRACK * Track; /* pointeur sur les pistes */
int l_piste ; /* demi-largeur de la piste */ int l_piste ; /* demi-largeur de la piste */
for( Track = start_adresse; Track != NULL; Track = (TRACK*) Track->Pnext) for( Track = start_adresse; Track != NULL; Track = (TRACK*) Track->Pnext)
{ {
if( Track->GetState(BUSY|DELETED) ) continue; if( Track->GetState(BUSY|DELETED) ) continue;
if ( (g_DesignSettings.m_LayerColor[Track->m_Layer] & ITEM_NOT_SHOW) ) if ( (g_DesignSettings.m_LayerColor[Track->m_Layer] & ITEM_NOT_SHOW) )
continue; continue;
/* calcul des coordonnees du segment teste */ /* calcul des coordonnees du segment teste */
l_piste = Track->m_Width >> 1; /* l_piste = demi largeur piste */ l_piste = Track->m_Width >> 1; /* l_piste = demi largeur piste */
ux0 = Track->m_Start.x ; uy0 = Track->m_Start.y ; /* coord de depart */ 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 */ dx = Track->m_End.x ; dy = Track->m_End.y ; /* coord d'arrivee */
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx -= ux0 ; dy -= uy0 ; dx -= ux0 ; dy -= uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
if ( Track->m_StructType == TYPEVIA ) /* VIA rencontree */ if ( Track->m_StructType == TYPEVIA ) /* VIA rencontree */
{ {
if ((abs(spot_cX) <= l_piste ) && (abs(spot_cY) <=l_piste)) if ((abs(spot_cX) <= l_piste ) && (abs(spot_cY) <=l_piste))
{ {
return(Track) ; return(Track) ;
} }
continue ; continue ;
} }
if(MasqueLayer != -1) if(MasqueLayer != -1)
if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0) if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0)
continue; /* Segments sur couches differentes */ continue; /* Segments sur couches differentes */
if( distance(l_piste) ) return(Track) ; if( distance(l_piste) ) return(Track) ;
} }
return(NULL) ; return(NULL) ;
} }
/****************************************************************/ /****************************************************************/
/* TRACK * Locate_Zone(TRACK * start_adresse, int layer, */ /* TRACK * Locate_Zone(TRACK * start_adresse, int layer, */
/* int typeloc) */ /* int typeloc) */
/* TRACK * Locate_Zone(TRACK * start_adresse, */ /* TRACK * Locate_Zone(TRACK * start_adresse, */
/* const wxPoint & ref_pos, */ /* const wxPoint & ref_pos, */
/* int layer) */ /* int layer) */
/****************************************************************/ /****************************************************************/
/* /*
1 - routine de localisation du segment de zone pointe par la souris. 1 - routine de localisation du segment de zone pointe par la souris.
2 - routine de localisation du segment de zone pointe par le point 2 - routine de localisation du segment de zone pointe par le point
ref_pos.x , ref_pos.y.r ref_pos.x , ref_pos.y.r
Si layer == -1 , le tst de la couche n'est pas fait Si layer == -1 , le tst de la couche n'est pas fait
La recherche commence a l'adresse start_adresse La recherche commence a l'adresse start_adresse
*/ */
TRACK * Locate_Zone(TRACK * start_adresse,int layer, int typeloc ) TRACK * Locate_Zone(TRACK * start_adresse,int layer, int typeloc )
{ {
wxPoint ref_pos; wxPoint ref_pos;
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
return( Locate_Zone(start_adresse, ref_pos, layer) ); return( Locate_Zone(start_adresse, ref_pos, layer) );
} }
TRACK * Locate_Zone(TRACK * start_adresse, const wxPoint & ref_pos, int layer) TRACK * Locate_Zone(TRACK * start_adresse, const wxPoint & ref_pos, int layer)
{ {
TRACK * Zone; /* pointeur sur les pistes */ TRACK * Zone; /* pointeur sur les pistes */
int l_segm ; /* demi-largeur de la piste */ int l_segm ; /* demi-largeur de la piste */
for( Zone = start_adresse; Zone != NULL; Zone = (TRACK *) Zone->Pnext) for( Zone = start_adresse; Zone != NULL; Zone = (TRACK *) Zone->Pnext)
{ {
/* calcul des coordonnees du segment teste */ /* calcul des coordonnees du segment teste */
l_segm = Zone->m_Width >> 1; /* l_piste = demi largeur piste */ l_segm = Zone->m_Width >> 1; /* l_piste = demi largeur piste */
ux0 = Zone->m_Start.x ; uy0 = Zone->m_Start.y ; /* coord de depart */ 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 */ dx = Zone->m_End.x ; dy = Zone->m_End.y ; /* coord d'arrivee */
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx -= ux0 ; dy -= uy0 ; dx -= ux0 ; dy -= uy0 ;
spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ; spot_cX = ref_pos.x - ux0 ; spot_cY = ref_pos.y - uy0 ;
if((layer != -1) && (Zone->m_Layer != layer)) continue; if((layer != -1) && (Zone->m_Layer != layer)) continue;
if( distance(l_segm) ) return(Zone) ; if( distance(l_segm) ) return(Zone) ;
} }
return(NULL) ; return(NULL) ;
} }
...@@ -972,24 +1004,24 @@ int l_segm ; /* demi-largeur de la piste */ ...@@ -972,24 +1004,24 @@ int l_segm ; /* demi-largeur de la piste */
TEXTE_PCB * Locate_Texte_Pcb(EDA_BaseStruct * PtStruct, int LayerSearch, int typeloc) TEXTE_PCB * Locate_Texte_Pcb(EDA_BaseStruct * PtStruct, int LayerSearch, int typeloc)
/************************************************************************************/ /************************************************************************************/
/* localisation des inscriptions sur le Pcb: /* localisation des inscriptions sur le Pcb:
entree : EDA_BaseStruct pointeur sur le debut de la zone de recherche entree : EDA_BaseStruct pointeur sur le debut de la zone de recherche
retour : pointeur sur la description du texte localise retour : pointeur sur la description du texte localise
*/ */
{ {
wxPoint ref; wxPoint ref;
SET_REF_POS(ref); SET_REF_POS(ref);
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPETEXTE ) continue; if( PtStruct->m_StructType != TYPETEXTE ) continue;
TEXTE_PCB * pt_txt_pcb = (TEXTE_PCB *) PtStruct; TEXTE_PCB * pt_txt_pcb = (TEXTE_PCB *) PtStruct;
if( pt_txt_pcb->Locate(ref) ) if( pt_txt_pcb->Locate(ref) )
{ {
if ( pt_txt_pcb->m_Layer == LayerSearch ) if ( pt_txt_pcb->m_Layer == LayerSearch )
return pt_txt_pcb; return pt_txt_pcb;
} }
} }
return(NULL) ; return(NULL) ;
} }
...@@ -1001,270 +1033,270 @@ int distance(int seuil) ...@@ -1001,270 +1033,270 @@ int distance(int seuil)
/* /*
Calcul de la distance du curseur souris a un segment de droite : Calcul de la distance du curseur souris a un segment de droite :
( piste, edge, contour module .. ( piste, edge, contour module ..
retourne: retourne:
0 si distance > seuil 0 si distance > seuil
1 si distance <= seuil 1 si distance <= seuil
Variables utilisees ( doivent etre initialisees avant appel , et Variables utilisees ( doivent etre initialisees avant appel , et
sont ramenees au repere centre sur l'origine du segment) sont ramenees au repere centre sur l'origine du segment)
dx, dy = coord de l'extremite segment. dx, dy = coord de l'extremite segment.
spot_cX,spot_cY = coord du curseur souris spot_cX,spot_cY = coord du curseur souris
la recherche se fait selon 4 cas: la recherche se fait selon 4 cas:
segment horizontal segment horizontal
segment vertical segment vertical
segment 45 segment 45
segment quelconque segment quelconque
*/ */
{ {
int cXrot, cYrot , /* coord du point (souris) dans le repere tourne */ int cXrot, cYrot , /* coord du point (souris) dans le repere tourne */
segX, segY; /* coord extremite segment tj >= 0 */ segX, segY; /* coord extremite segment tj >= 0 */
int pointX, pointY; /* coord point a tester dans repere modifie dans lequel int pointX, pointY; /* coord point a tester dans repere modifie dans lequel
segX et segY sont >=0 */ segX et segY sont >=0 */
segX = dx ; segY = dy; pointX = spot_cX ; pointY = spot_cY ; segX = dx ; segY = dy; pointX = spot_cX ; pointY = spot_cY ;
/*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/ /*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 */ if (segX < 0) /* mise en >0 par symetrie par rapport a l'axe Y */
{ {
segX = -segX ; pointX = - pointX ; segX = -segX ; pointX = - pointX ;
} }
if (segY < 0) /* mise en > 0 par symetrie par rapport a l'axe X */ if (segY < 0) /* mise en > 0 par symetrie par rapport a l'axe X */
{ {
segY = -segY ; pointY = -pointY ; segY = -segY ; pointY = -pointY ;
} }
if ( segY == 0 ) /* piste Horizontale */ if ( segY == 0 ) /* piste Horizontale */
{ {
if(abs(pointY) <= seuil ) if(abs(pointY) <= seuil )
{ {
if((pointX >= 0) && (pointX <= segX) ) return(1); if((pointX >= 0) && (pointX <= segX) ) return(1);
/* Etude des extremites : cercle de rayon seuil */ /* Etude des extremites : cercle de rayon seuil */
if( (pointX < 0) && (pointX >= -seuil) ) if( (pointX < 0) && (pointX >= -seuil) )
{ {
if( ((pointX * pointX) + (pointY*pointY)) <= (seuil*seuil) ) if( ((pointX * pointX) + (pointY*pointY)) <= (seuil*seuil) )
return(1); return(1);
} }
if( (pointX > segX) && (pointX <= (segX+seuil)) ) if( (pointX > segX) && (pointX <= (segX+seuil)) )
{ {
if( (((pointX-segX) * (pointX-segX)) + (pointY*pointY)) <= (seuil*seuil) ) if( (((pointX-segX) * (pointX-segX)) + (pointY*pointY)) <= (seuil*seuil) )
return(1); return(1);
} }
} }
} }
else if ( segX == 0 ) /* piste verticale */ else if ( segX == 0 ) /* piste verticale */
{ {
if( abs(pointX) <= seuil) if( abs(pointX) <= seuil)
{ {
if((pointY >= 0 ) && (pointY <= segY) ) return(1); if((pointY >= 0 ) && (pointY <= segY) ) return(1);
if( (pointY < 0) && (pointY >= -seuil) ) if( (pointY < 0) && (pointY >= -seuil) )
{ {
if( ((pointY * pointY) + (pointX*pointX)) <= (seuil*seuil) ) if( ((pointY * pointY) + (pointX*pointX)) <= (seuil*seuil) )
return(1); return(1);
} }
if( (pointY > segY) && (pointY <= (segY+seuil)) ) if( (pointY > segY) && (pointY <= (segY+seuil)) )
{ {
if( ( ((pointY-segY) * (pointY-segY)) + (pointX*pointX)) <= (seuil*seuil) ) if( ( ((pointY-segY) * (pointY-segY)) + (pointX*pointX)) <= (seuil*seuil) )
return(1); return(1);
} }
} }
} }
else if ( segX == segY ) /* piste a 45 degre */ else if ( segX == segY ) /* piste a 45 degre */
{ {
/* on fait tourner les axes de 45 degre. la souris a alors les /* on fait tourner les axes de 45 degre. la souris a alors les
coord : x1 = x*cos45 + y*sin45 coord : x1 = x*cos45 + y*sin45
y1 = y*cos45 - x*sin45 y1 = y*cos45 - x*sin45
et le segment de piste est alors horizontal. et le segment de piste est alors horizontal.
recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10 recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10
remarque : sin ou cos45 = .707, et lors du recalcul des coord 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 dx45 et dy45, lec coeff .707 est neglige, dx et dy sont en fait .707 fois
trop grands. (c.a.d trop petits) trop grands. (c.a.d trop petits)
spot_cX,Y doit etre * par .707 * .707 = 0.5 */ spot_cX,Y doit etre * par .707 * .707 = 0.5 */
cXrot = (pointX + pointY) >> 1 ; cXrot = (pointX + pointY) >> 1 ;
cYrot = (pointY - pointX) >> 1 ; cYrot = (pointY - pointX) >> 1 ;
/* recalcul des coord de l'extremite du segment , qui sera vertical /* recalcul des coord de l'extremite du segment , qui sera vertical
suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY) suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY)
et est en fait 1,414 plus grand , et dy45 = 0 */ 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 doit etre * .707 pour tenir compte du coeff de reduction sur dx,dy
seuil *= 7 ; seuil /= 10 ; seuil *= 7 ; seuil /= 10 ;
if ( abs(cYrot) <= seuil) /* ok sur axe vertical) */ if ( abs(cYrot) <= seuil) /* ok sur axe vertical) */
{ {
if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ; if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ;
/* Etude des extremites : cercle de rayon seuil */ /* Etude des extremites : cercle de rayon seuil */
if( (cXrot < 0) && (cXrot >= -seuil) ) if( (cXrot < 0) && (cXrot >= -seuil) )
{ {
if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) ) if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) )
return(1); return(1);
} }
if( (cXrot > segX) && (cXrot <= (segX+seuil)) ) if( (cXrot > segX) && (cXrot <= (segX+seuil)) )
{ {
if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) ) if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) )
return(1); return(1);
} }
} }
} }
else /* orientation quelconque */ else /* orientation quelconque */
{ {
/* On fait un changement d'axe (rotation) de facon a ce que le segment /* On fait un changement d'axe (rotation) de facon a ce que le segment
de piste soit horizontal dans le nouveau repere */ de piste soit horizontal dans le nouveau repere */
int angle; int angle;
angle = (int)( atan2((float)segY, (float)segX) * 1800 / M_PI) ; angle = (int)( atan2((float)segY, (float)segX) * 1800 / M_PI) ;
cXrot = pointX; cYrot = pointY; cXrot = pointX; cYrot = pointY;
RotatePoint(&cXrot, &cYrot, angle); /* Rotation du point a tester */ RotatePoint(&cXrot, &cYrot, angle); /* Rotation du point a tester */
RotatePoint(&segX, &segY, angle) ; /* Rotation du segment */ RotatePoint(&segX, &segY, angle) ; /* Rotation du segment */
/*la piste est Horizontale , par suite des modifs de coordonnes /*la piste est Horizontale , par suite des modifs de coordonnes
et d'axe, donc segX = longueur du segment */ et d'axe, donc segX = longueur du segment */
if ( abs(cYrot) <= seuil ) /* ok sur axe vertical) */ if ( abs(cYrot) <= seuil ) /* ok sur axe vertical) */
{ {
if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ; if ((cXrot >= 0) && (cXrot <= segX) ) return(1) ;
/* Etude des extremites : cercle de rayon seuil */ /* Etude des extremites : cercle de rayon seuil */
if( (cXrot < 0) && (cXrot >= -seuil) ) if( (cXrot < 0) && (cXrot >= -seuil) )
{ {
if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) ) if( ((cXrot * cXrot) + (cYrot*cYrot)) <= (seuil*seuil) )
return(1); return(1);
} }
if( (cXrot > segX) && (cXrot <= (segX+seuil)) ) if( (cXrot > segX) && (cXrot <= (segX+seuil)) )
{ {
if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) ) if( (((cXrot-segX) * (cXrot-segX)) + (cYrot*cYrot)) <= (seuil*seuil) )
return(1); return(1);
} }
} }
} }
return(0) ; return(0) ;
} }
/*******************************************************************************/ /*******************************************************************************/
D_PAD * Fast_Locate_Pad_Connecte(BOARD * Pcb, const wxPoint & ref_pos, int masque_layer) D_PAD * Fast_Locate_Pad_Connecte(BOARD * Pcb, const wxPoint & ref_pos, int masque_layer)
/*******************************************************************************/ /*******************************************************************************/
/* Routine cherchant le pad de centre px,py, /* Routine cherchant le pad de centre px,py,
sur la couche indiquee par masque_layer (bit a bit) sur la couche indiquee par masque_layer (bit a bit)
( extremite de piste ) ( extremite de piste )
La liste des pads doit deja exister. La liste des pads doit deja exister.
retourne : retourne :
NULL si pas de pad localise. NULL si pas de pad localise.
pointeur sur la structure descr_pad correspondante si pad trouve pointeur sur la structure descr_pad correspondante si pad trouve
(bonne position ET bonne couche). (bonne position ET bonne couche).
*/ */
{ {
D_PAD * pad; D_PAD * pad;
LISTE_PAD * ptr_pad , * lim; LISTE_PAD * ptr_pad , * lim;
lim = (LISTE_PAD*)Pcb->m_Pads + Pcb->m_NbPads; lim = (LISTE_PAD*)Pcb->m_Pads + Pcb->m_NbPads;
for (ptr_pad = (LISTE_PAD*)Pcb->m_Pads; ptr_pad < lim ; ptr_pad++) for (ptr_pad = (LISTE_PAD*)Pcb->m_Pads; ptr_pad < lim ; ptr_pad++)
{ {
pad = * ptr_pad; pad = * ptr_pad;
if( pad->m_Pos != ref_pos ) continue ; if( pad->m_Pos != ref_pos ) continue ;
/* Pad peut-etre trouve ici : il doit etre sur la bonne couche */ /* Pad peut-etre trouve ici : il doit etre sur la bonne couche */
if (pad->m_Masque_Layer & masque_layer) return(pad) ; if (pad->m_Masque_Layer & masque_layer) return(pad) ;
} }
return(NULL); return(NULL);
} }
/***********************************************************************************/ /***********************************************************************************/
TRACK * Fast_Locate_Piste(TRACK *start_adr, TRACK* end_adr, TRACK * Fast_Locate_Piste(TRACK *start_adr, TRACK* end_adr,
const wxPoint & ref_pos, int MaskLayer) const wxPoint & ref_pos, int MaskLayer)
/***********************************************************************************/ /***********************************************************************************/
/* Localiste le segment dont une extremite coincide avec le point x,y /* Localiste le segment dont une extremite coincide avec le point x,y
sur les couches donnees par masklayer sur les couches donnees par masklayer
la recherche se fait de l'adresse start_adr a end_adr la recherche se fait de l'adresse start_adr a end_adr
si end_adr = NULL, recherche jusqu'a la fin de la liste si end_adr = NULL, recherche jusqu'a la fin de la liste
Les segments de piste marques avec le flag DELETED ne sont pas Les segments de piste marques avec le flag DELETED ne sont pas
pris en compte pris en compte
*/ */
{ {
TRACK * PtSegm; TRACK * PtSegm;
if( start_adr == NULL ) return(NULL); if( start_adr == NULL ) return(NULL);
for ( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext ) for ( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*) PtSegm->Pnext )
{ {
if( PtSegm->GetState(DELETED|BUSY) == 0) if( PtSegm->GetState(DELETED|BUSY) == 0)
{ {
if( ref_pos == PtSegm->m_Start ) if( ref_pos == PtSegm->m_Start )
{ /* Test des couches */ { /* Test des couches */
if(MaskLayer & PtSegm->ReturnMaskLayer() ) return(PtSegm); if(MaskLayer & PtSegm->ReturnMaskLayer() ) return(PtSegm);
} }
if( ref_pos == PtSegm->m_End ) if( ref_pos == PtSegm->m_End )
{ /* Test des couches */ { /* Test des couches */
if(MaskLayer & PtSegm->ReturnMaskLayer() ) return(PtSegm); if(MaskLayer & PtSegm->ReturnMaskLayer() ) return(PtSegm);
} }
} }
if( PtSegm == end_adr) break; if( PtSegm == end_adr) break;
} }
return (NULL); return (NULL);
} }
/*******************************************************************/ /*******************************************************************/
TRACK * Fast_Locate_Via(TRACK *start_adr, TRACK* end_adr, TRACK * Fast_Locate_Via(TRACK *start_adr, TRACK* end_adr,
const wxPoint & pos, int MaskLayer) const wxPoint & pos, int MaskLayer)
/*******************************************************************/ /*******************************************************************/
/* Localise la via de centre le point x,y , sur les couches donnees /* Localise la via de centre le point x,y , sur les couches donnees
par masklayer par masklayer
la recherche se fait de l'adresse start_adr a end_adr. la recherche se fait de l'adresse start_adr a end_adr.
si end_adr = NULL, recherche jusqu'a la fin de la liste 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 les vias dont le parametre State a le bit DELETED ou BUSY = 1 sont ignorees
*/ */
{ {
TRACK * PtSegm; TRACK * PtSegm;
for ( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*)PtSegm->Pnext ) for ( PtSegm = start_adr; PtSegm != NULL; PtSegm = (TRACK*)PtSegm->Pnext )
{ {
if(PtSegm->m_StructType == TYPEVIA) if(PtSegm->m_StructType == TYPEVIA)
{ {
if( pos == PtSegm->m_Start ) if( pos == PtSegm->m_Start )
{ {
if( PtSegm->GetState(BUSY|DELETED) == 0) if( PtSegm->GetState(BUSY|DELETED) == 0)
{/* Test des couches */ {/* Test des couches */
if( MaskLayer & PtSegm->ReturnMaskLayer() )return(PtSegm); if( MaskLayer & PtSegm->ReturnMaskLayer() )return(PtSegm);
} }
} }
} }
if( PtSegm == end_adr ) break; if( PtSegm == end_adr ) break;
} }
return (NULL); return (NULL);
} }
/***********************************************************************/ /***********************************************************************/
EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch, EDA_BaseStruct * Locate_MirePcb( EDA_BaseStruct * PtStruct, int LayerSearch,
int typeloc) int typeloc)
/***********************************************************************/ /***********************************************************************/
/* Serach for a photo target /* Serach for a photo target
*/ */
{ {
wxPoint ref_pos; /* coord du point de localisation */ wxPoint ref_pos; /* coord du point de localisation */
int dX, dY, rayon; int dX, dY, rayon;
if(PtStruct == NULL ) return(NULL); if(PtStruct == NULL ) return(NULL);
SET_REF_POS(ref_pos); SET_REF_POS(ref_pos);
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext)
{ {
MIREPCB* item; MIREPCB* item;
if( PtStruct->m_StructType != TYPEMIRE ) continue; if( PtStruct->m_StructType != TYPEMIRE ) continue;
item = (MIREPCB*) PtStruct; item = (MIREPCB*) PtStruct;
if( LayerSearch != -1 && item->m_Layer != LayerSearch ) continue; if( LayerSearch != -1 && item->m_Layer != LayerSearch ) continue;
dX = ref_pos.x - item->m_Pos.x; dX = ref_pos.x - item->m_Pos.x;
dY = ref_pos.y - item->m_Pos.y; dY = ref_pos.y - item->m_Pos.y;
rayon = item->m_Size / 2; rayon = item->m_Size / 2;
if( (abs(dX) <= rayon ) && ( abs(dY) <= rayon ) ) if( (abs(dX) <= rayon ) && ( abs(dY) <= rayon ) )
break; /* Mire Localisee */ break; /* Mire Localisee */
} }
return(PtStruct); return(PtStruct);
} }
...@@ -15,8 +15,12 @@ ...@@ -15,8 +15,12 @@
/* valeur de flag indicant si le pointeur de reference pour une localisation /* valeur de flag indicant si le pointeur de reference pour une localisation
est le curseur sur grille ou le curseur a deplacement fin hors grille */ est le curseur sur grille ou le curseur a deplacement fin hors grille */
#define CURSEUR_ON_GRILLE 0 #define CURSEUR_ON_GRILLE (0<<0)
#define CURSEUR_OFF_GRILLE 1 #define CURSEUR_OFF_GRILLE (1<<1)
#define IGNORE_LOCKED (1<<2) ///< if module is locked, do not select for single module operation
#define MATCH_LAYER (1<<3) ///< if module not on current layer, do not select
#define VISIBLE_ONLY (1<<4) ///< if module not on a visible layer, do not select
#define START 0 /* ctes parametre dans les routines de localisation */ #define START 0 /* ctes parametre dans les routines de localisation */
#define END 1 #define END 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment