searching and beautifying

This commit is contained in:
dickelbeck 2007-08-08 20:51:08 +00:00
parent 66080848cc
commit c1e3416a8f
20 changed files with 2975 additions and 2510 deletions

View File

@ -5,6 +5,20 @@ Please add newer entries at the top, list the date and your name with
email address. email address.
2007-Aug-08 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+ pcbnew & common
* Renamed locate.cpp's distance() to DistanceTest() and moved it to trigo.cpp.
Pass more parameters to DistanceTest and removed globals that were used by
distance() in locate.cpp.
Moved and renamed DistanceTest function proto from protos.h to trigo.h.
* Implemented HitTest() for class_cotation, class_mire, and a few other classes
by factoring out existing code from locate.cpp. locate.cpp should operate
exactly the same as before.
* Detected that the suspected class_module hit-testing bug was not real,
i.e. no bug found.
2007-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2007-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================ ================================================================================
+ eeschema + eeschema

View File

@ -9,6 +9,163 @@
#include "trigo.h" #include "trigo.h"
/*****************************/
bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY )
/*****************************/
/*
* Calcul de la distance du curseur souris a un segment de droite :
* ( piste, edge, contour module ..
* retourne:
* false si distance > seuil
* true si distance <= seuil
* Variables utilisees ( doivent etre initialisees avant appel , et
* sont ramenees au repere centre sur l'origine du segment)
* dx, dy = coord de l'extremite segment.
* spot_cX,spot_cY = coord du curseur souris
* la recherche se fait selon 4 cas:
* segment horizontal
* segment vertical
* segment 45
* segment quelconque
*/
{
int cXrot, cYrot, /* coord du point (souris) dans le repere tourne */
segX, segY; /* coord extremite segment tj >= 0 */
int pointX, pointY; /* coord point a tester dans repere modifie dans lequel
* segX et segY sont >=0 */
segX = dx; segY = dy; pointX = spot_cX; pointY = spot_cY;
/*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/
if( segX < 0 ) /* mise en >0 par symetrie par rapport a l'axe Y */
{
segX = -segX; pointX = -pointX;
}
if( segY < 0 ) /* mise en > 0 par symetrie par rapport a l'axe X */
{
segY = -segY; pointY = -pointY;
}
if( segY == 0 ) /* piste Horizontale */
{
if( abs( pointY ) <= seuil )
{
if( (pointX >= 0) && (pointX <= segX) )
return 1;
/* Etude des extremites : cercle de rayon seuil */
if( (pointX < 0) && (pointX >= -seuil) )
{
if( ( (pointX * pointX) + (pointY * pointY) ) <= (seuil * seuil) )
return true;
}
if( (pointX > segX) && ( pointX <= (segX + seuil) ) )
{
if( ( ( (pointX - segX) * (pointX - segX) ) + (pointY * pointY) ) <=
(seuil * seuil) )
return true;
}
}
}
else if( segX == 0 ) /* piste verticale */
{
if( abs( pointX ) <= seuil )
{
if( (pointY >= 0 ) && (pointY <= segY) )
return true;
if( (pointY < 0) && (pointY >= -seuil) )
{
if( ( (pointY * pointY) + (pointX * pointX) ) <= (seuil * seuil) )
return true;
}
if( (pointY > segY) && ( pointY <= (segY + seuil) ) )
{
if( ( ( (pointY - segY) * (pointY - segY) ) + (pointX * pointX) ) <=
(seuil * seuil) )
return true;
}
}
}
else if( segX == segY ) /* piste a 45 degre */
{
/* on fait tourner les axes de 45 degre. la souris a alors les
* coord : x1 = x*cos45 + y*sin45
* y1 = y*cos45 - x*sin45
* et le segment de piste est alors horizontal.
* recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10
* remarque : sin ou cos45 = .707, et lors du recalcul des coord
* dx45 et dy45, lec coeff .707 est neglige, dx et dy sont en fait .707 fois
* trop grands. (c.a.d trop petits)
* spot_cX,Y doit etre * par .707 * .707 = 0.5 */
cXrot = (pointX + pointY) >> 1;
cYrot = (pointY - pointX) >> 1;
/* recalcul des coord de l'extremite du segment , qui sera vertical
* suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY)
* et est en fait 1,414 plus grand , et dy45 = 0 */
// seuil doit etre * .707 pour tenir compte du coeff de reduction sur dx,dy
seuil *= 7; seuil /= 10;
if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */
{
if( (cXrot >= 0) && (cXrot <= segX) )
return true;
/* Etude des extremites : cercle de rayon seuil */
if( (cXrot < 0) && (cXrot >= -seuil) )
{
if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) )
return true;
}
if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) )
{
if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) )
return true;
}
}
}
else /* orientation quelconque */
{
/* On fait un changement d'axe (rotation) de facon a ce que le segment
* de piste soit horizontal dans le nouveau repere */
int angle;
angle = (int) ( atan2( (float) segY, (float) segX ) * 1800 / M_PI);
cXrot = pointX; cYrot = pointY;
RotatePoint( &cXrot, &cYrot, angle ); /* Rotation du point a tester */
RotatePoint( &segX, &segY, angle ); /* Rotation du segment */
/* la piste est Horizontale , par suite des modifs de coordonnes
* et d'axe, donc segX = longueur du segment */
if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */
{
if( (cXrot >= 0) && (cXrot <= segX) )
return true;
/* Etude des extremites : cercle de rayon seuil */
if( (cXrot < 0) && (cXrot >= -seuil) )
{
if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) )
return true;
}
if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) )
{
if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) )
return true;
}
}
}
return false;
}
/***********************************/ /***********************************/
int ArcTangente( int dy, int dx ) int ArcTangente( int dy, int dx )
/***********************************/ /***********************************/
@ -217,3 +374,5 @@ void RotatePoint( double* pX, double* pY, int angle )
*pY = fpy; *pY = fpy;
} }
} }

View File

@ -235,7 +235,6 @@ public:
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.
@ -264,7 +263,7 @@ public:
* @param typeloc * @param typeloc
* @return EDA_BaseStruct* - if a direct hit, else NULL. * @return EDA_BaseStruct* - if a direct hit, else NULL.
*/ */
EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer, int typeloc ); EDA_BaseStruct* FindPadOrModule( const wxPoint& refPos, int layer );
#endif #endif
}; };
@ -322,6 +321,27 @@ public:
void UnLink( void ); void UnLink( void );
void Copy( DRAWSEGMENT* source ); void Copy( DRAWSEGMENT* source );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& ref_pos );
#if defined(DEBUG)
/**
* Function GetClass
* returns the class name.
* @return wxString
*/
wxString GetClass() const
{
return wxT("pgraphic");
}
#endif
}; };

View File

@ -7,7 +7,7 @@
#define TRIGO_H #define TRIGO_H
/* Prototype des fonctions de TRIGO.CC */ /* Prototype des fonctions de trigo.cpp */
void RotatePoint(int *pX, int *pY, int angle); void RotatePoint(int *pX, int *pY, int angle);
void RotatePoint(int *pX, int *pY, int cx, int cy, int angle); void RotatePoint(int *pX, int *pY, int cx, int cy, int angle);
void RotatePoint(wxPoint *point, const wxPoint & centre, int angle); void RotatePoint(wxPoint *point, const wxPoint & centre, int angle);
@ -19,6 +19,7 @@ int ArcTangente(int dy, int dx);
Analogue a atan2 ( mais plus rapide pour les caculs si Analogue a atan2 ( mais plus rapide pour les caculs si
l'angle est souvent 0, -1800, ou +- 900 */ l'angle est souvent 0, -1800, ou +- 900 */
bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY );

View File

@ -290,75 +290,64 @@ void BOARD::Show( int nestLevel, std::ostream& os )
// see pcbstruct.h // see pcbstruct.h
EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer, int typeloc ) EDA_BaseStruct* BOARD::FindPadOrModule( const wxPoint& refPos, int layer )
{ {
class PadOrModule : public INSPECTOR class PadOrModule : public INSPECTOR
{ {
public: public:
EDA_BaseStruct* found; EDA_BaseStruct* found;
int layer; int layer;
int typeloc;
PadOrModule( int alayer, int atypeloc ) : PadOrModule( int alayer ) :
found(0), found(0), // found is NULL
layer(alayer), layer(alayer)
typeloc(atypeloc) {} {
}
SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData ) SEARCH_RESULT Inspect( EDA_BaseStruct* testItem, const void* testData )
{ {
const wxPoint* refPos = (const wxPoint*) testData; const wxPoint& refPos = *(const wxPoint*) testData;
if( testItem->m_StructType == TYPEMODULE ) if( testItem->m_StructType == TYPEPAD )
{
if( testItem->HitTest( refPos ) )
{
found = testItem;
return SEARCH_QUIT;
}
}
else if( testItem->m_StructType == TYPEMODULE )
{ {
int mlayer = ((MODULE*)testItem)->m_Layer; int mlayer = ((MODULE*)testItem)->m_Layer;
if( typeloc & MATCH_LAYER ) // consider only visible modules
if( IsModuleLayerVisible( mlayer ) )
{ {
if( layer != mlayer ) if( testItem->HitTest( refPos ) )
return SEARCH_CONTINUE;
}
if( typeloc & VISIBLE_ONLY )
{
if( !IsModuleLayerVisible(mlayer) )
return SEARCH_CONTINUE;
}
if( testItem->HitTest( *refPos ) )
{ {
// save regardless of layer test, but only quit if
// layer matches, otherwise use this item if no future
// layer match.
found = testItem; found = testItem;
if( layer == mlayer )
return SEARCH_QUIT; return SEARCH_QUIT;
} }
} }
else if( testItem->m_StructType == TYPEPAD )
{
if( testItem->HitTest( *refPos ) )
{
found = testItem;
return SEARCH_QUIT;
} }
}
else { int debug=1; /* this should not happen, because of scanTypes */ }
return SEARCH_CONTINUE; return SEARCH_CONTINUE;
} }
}; };
PadOrModule inspector1( layer, MATCH_LAYER ); PadOrModule inspector( layer );
PadOrModule inspector2( layer, VISIBLE_ONLY );
// search only for PADs first, then MODULES, and preferably a layer match
static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT }; static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT };
// search the current layer first IterateForward( m_Modules, &inspector, &refPos, scanTypes );
if( SEARCH_QUIT == IterateForward( m_Modules, &inspector1, &refPos, scanTypes ) )
return inspector1.found;
// if not found, set layer to don't care and search again return inspector.found;
if( SEARCH_QUIT == IterateForward( m_Modules, &inspector2, &refPos, scanTypes ) )
return inspector2.found;
return NULL;
} }
#endif #endif

View File

@ -7,8 +7,7 @@
#include "common.h" #include "common.h"
#include "pcbnew.h" #include "pcbnew.h"
#include "trigo.h"
COTATION::COTATION( EDA_BaseStruct* StructFather ) : COTATION::COTATION( EDA_BaseStruct* StructFather ) :
EDA_BaseStruct( StructFather, TYPECOTATION ) EDA_BaseStruct( StructFather, TYPECOTATION )
@ -21,14 +20,16 @@ COTATION::COTATION(EDA_BaseStruct * StructFather):
m_Text = new TEXTE_PCB( this ); m_Text = new TEXTE_PCB( this );
} }
/* Effacement memoire de la structure */ /* Effacement memoire de la structure */
COTATION::~COTATION( void ) COTATION::~COTATION( void )
{ {
delete m_Text; delete m_Text;
} }
/* supprime du chainage la structure Struct /* supprime du chainage la structure Struct
les structures arrieres et avant sont chainees directement * les structures arrieres et avant sont chainees directement
*/ */
void COTATION::UnLink( void ) void COTATION::UnLink( void )
{ {
@ -39,7 +40,6 @@ void COTATION::UnLink( void )
{ {
Pback->Pnext = Pnext; Pback->Pnext = Pnext;
} }
else /* Le chainage arriere pointe sur la structure "Pere" */ else /* Le chainage arriere pointe sur la structure "Pere" */
{ {
( (BOARD*) Pback )->m_Drawings = Pnext; ( (BOARD*) Pback )->m_Drawings = Pnext;
@ -47,11 +47,13 @@ void COTATION::UnLink( void )
} }
/* Modification du chainage avant */ /* Modification du chainage avant */
if( Pnext) Pnext->Pback = Pback; if( Pnext )
Pnext->Pback = Pback;
Pnext = Pback = NULL; Pnext = Pback = NULL;
} }
/* Changement du texte de la cotation */ /* Changement du texte de la cotation */
void COTATION:: SetText( const wxString& NewText ) void COTATION:: SetText( const wxString& NewText )
{ {
@ -97,7 +99,8 @@ char Line[2048], Text[2048];
while( GetLine( File, Line, LineNum ) != NULL ) while( GetLine( File, Line, LineNum ) != NULL )
{ {
if(strnicmp(Line,"$EndCOTATION",4) == 0) return TRUE; if( strnicmp( Line, "$EndCOTATION", 4 ) == 0 )
return TRUE;
if( Line[0] == 'V' ) if( Line[0] == 'V' )
{ {
@ -143,6 +146,7 @@ char Line[2048], Text[2048];
switch( Line[1] ) switch( Line[1] )
{ {
int Dummy; int Dummy;
case 'b': case 'b':
sscanf( Line + 2, " %d %d %d %d %d %d", sscanf( Line + 2, " %d %d %d %d %d %d",
&Dummy, &Dummy,
@ -203,6 +207,7 @@ char Line[2048], Text[2048];
continue; continue;
} }
} }
return FALSE; return FALSE;
} }
@ -211,7 +216,8 @@ char Line[2048], Text[2048];
bool COTATION::WriteCotationDescr( FILE* File ) bool COTATION::WriteCotationDescr( FILE* File )
/**************************************************/ /**************************************************/
{ {
if( GetState(DELETED) ) return FALSE; if( GetState( DELETED ) )
return FALSE;
fprintf( File, "$COTATION\n" ); fprintf( File, "$COTATION\n" );
@ -222,7 +228,8 @@ bool COTATION::WriteCotationDescr(FILE * File)
if( !m_Text->m_Text.IsEmpty() ) if( !m_Text->m_Text.IsEmpty() )
fprintf( File, "Te \"%s\"\n", CONV_TO_UTF8( m_Text->m_Text ) ); fprintf( File, "Te \"%s\"\n", CONV_TO_UTF8( m_Text->m_Text ) );
else fprintf( File,"Te \"?\"\n"); else
fprintf( File, "Te \"?\"\n" );
fprintf( File, "Po %d %d %d %d %d %d %d\n", fprintf( File, "Po %d %d %d %d %d %d %d\n",
m_Text->m_Pos.x, m_Text->m_Pos.y, m_Text->m_Pos.x, m_Text->m_Pos.y,
@ -261,16 +268,15 @@ bool COTATION::WriteCotationDescr(FILE * File)
fprintf( File, "$EndCOTATION\n" ); fprintf( File, "$EndCOTATION\n" );
return(1); return 1;
} }
/************************************************************************/ /************************************************************************/
void COTATION::Draw( WinEDA_DrawPanel* panel, wxDC* DC, void COTATION::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int mode_color ) const wxPoint& offset, int mode_color )
/************************************************************************/ /************************************************************************/
/* impression de 1 cotation : serie de n segments + 1 texte /* impression de 1 cotation : serie de n segments + 1 texte
*/ */
{ {
@ -283,17 +289,21 @@ int zoom = panel->GetScreen()->GetZoom();
m_Text->Draw( panel, DC, offset, mode_color ); m_Text->Draw( panel, DC, offset, mode_color );
gcolor = g_DesignSettings.m_LayerColor[m_Layer]; gcolor = g_DesignSettings.m_LayerColor[m_Layer];
if( (gcolor & ITEM_NOT_SHOW) != 0 ) return ; if( (gcolor & ITEM_NOT_SHOW) != 0 )
return;
GRSetDrawMode( DC, mode_color ); GRSetDrawMode( DC, mode_color );
typeaff = DisplayOpt.DisplayDrawItems; typeaff = DisplayOpt.DisplayDrawItems;
width = m_Width; width = m_Width;
if( width/zoom < 2 ) typeaff = FILAIRE; if( width / zoom < 2 )
typeaff = FILAIRE;
switch( typeaff ) switch( typeaff )
{ {
case FILAIRE: case FILAIRE:
width = 0; width = 0;
case FILLED: case FILLED:
GRLine( &panel->m_ClipBox, DC, GRLine( &panel->m_ClipBox, DC,
Barre_ox - ox, Barre_oy - oy, Barre_ox - ox, Barre_oy - oy,
@ -352,3 +362,121 @@ int zoom = panel->GetScreen()->GetZoom();
} }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool COTATION::HitTest( const wxPoint& ref_pos )
{
int ux0, uy0;
int dx, dy, spot_cX, spot_cY;
if( m_Text )
{
// because HitTest() is present in both base classes of TEXTE_PCB
// use a clarifying cast to tell compiler which HitTest()
// to call.
if( static_cast<EDA_TextStruct*>(m_Text)->HitTest( ref_pos ) )
return true;
}
/* Localisation des SEGMENTS ?) */
ux0 = Barre_ox;
uy0 = Barre_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Barre_fx - ux0;
dy = Barre_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
ux0 = TraitG_ox;
uy0 = TraitG_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = TraitG_fx - ux0;
dy = TraitG_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
/* detection : */
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
ux0 = TraitD_ox;
uy0 = TraitD_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = TraitD_fx - ux0;
dy = TraitD_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
/* detection : */
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
ux0 = FlecheD1_ox;
uy0 = FlecheD1_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = FlecheD1_fx - ux0;
dy = FlecheD1_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
/* detection : */
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
ux0 = FlecheD2_ox;
uy0 = FlecheD2_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = FlecheD2_fx - ux0;
dy = FlecheD2_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
ux0 = FlecheG1_ox;
uy0 = FlecheG1_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = FlecheG1_fx - ux0;
dy = FlecheG1_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
ux0 = FlecheG2_ox;
uy0 = FlecheG2_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = FlecheG2_fx - ux0;
dy = FlecheG2_fy - uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
return false;
}

View File

@ -42,6 +42,26 @@ class COTATION: public EDA_BaseStruct
void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int mode_color ); void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int mode_color );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& ref_pos );
#if defined(DEBUG)
/**
* Function GetClass
* returns the class name.
* @return wxString
*/
wxString GetClass() const
{
return wxT( "DIMENSION" );
}
#endif
}; };
#endif // #define COTATION_H #endif // #define COTATION_H

View File

@ -438,6 +438,73 @@ int EDGE_MODULE::ReadDescr( char* Line, FILE* File,
} }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool EDGE_MODULE::HitTest( const wxPoint& ref_pos )
{
int uxf, uyf;
int rayon, dist;
int dx, dy, spot_cX, spot_cY;
int ux0, uy0;
ux0 = m_Start.x;
uy0 = m_Start.y;
uxf = m_End.x;
uyf = m_End.y;
switch( m_Shape )
{
case S_SEGMENT:
/* recalcul des coordonnees avec ux0,uy0 = origine des coord. */
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
dx = uxf - ux0;
dy = uyf - uy0;
if( DistanceTest( m_Width/2, dx, dy, spot_cX, spot_cY ) )
return true;
break;
case S_CIRCLE:
rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) );
dist = (int) hypot( (double) (ref_pos.x - ux0), (double) (ref_pos.y - uy0) );
if( abs( rayon - dist ) <= m_Width )
return true;
break;
case S_ARC:
rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) );
dist = (int) hypot( (double) (ref_pos.x - ux0), (double) (ref_pos.y - uy0) );
if( abs( rayon - dist ) > m_Width )
break;
/* pour un arc, controle complementaire */
int mouseAngle = (int) ArcTangente( ref_pos.y - uy0, ref_pos.x - ux0 );
int stAngle = (int) ArcTangente( uyf - uy0, uxf - ux0 );
int endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
{
stAngle -= 3600;
endAngle -= 3600;
}
if( (mouseAngle >= stAngle) && (mouseAngle <= endAngle) )
return true;
break;
}
return false; // an unknown m_Shape also returns false
}
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function Show * Function Show

View File

@ -42,6 +42,14 @@ public:
int draw_mode ); int draw_mode );
void Draw3D( Pcb3D_GLCanvas* glcanvas ); void Draw3D( Pcb3D_GLCanvas* glcanvas );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function GetClass * Function GetClass
@ -50,7 +58,7 @@ public:
*/ */
virtual wxString GetClass() const virtual wxString GetClass() const
{ {
return wxT( "GRAPHIC" ); return wxT( "MGRAPHIC" );
// return wxT( "EDGE" ); ? // return wxT( "EDGE" ); ?
} }

View File

@ -9,7 +9,6 @@
#include "pcbnew.h" #include "pcbnew.h"
MIREPCB::MIREPCB( EDA_BaseStruct* StructFather ) : MIREPCB::MIREPCB( EDA_BaseStruct* StructFather ) :
EDA_BaseStruct( StructFather, TYPEMIRE ) EDA_BaseStruct( StructFather, TYPEMIRE )
{ {
@ -17,6 +16,7 @@ MIREPCB::MIREPCB(EDA_BaseStruct * StructFather):
m_Size = 5000; m_Size = 5000;
} }
MIREPCB::~MIREPCB( void ) MIREPCB::~MIREPCB( void )
{ {
} }
@ -25,8 +25,9 @@ MIREPCB::~MIREPCB(void)
/***************************/ /***************************/
void MIREPCB::UnLink( void ) void MIREPCB::UnLink( void )
/***************************/ /***************************/
/* supprime du chainage la structure Struct /* supprime du chainage la structure Struct
les structures arrieres et avant sont chainees directement * les structures arrieres et avant sont chainees directement
*/ */
{ {
/* Modification du chainage arriere */ /* Modification du chainage arriere */
@ -36,7 +37,6 @@ void MIREPCB::UnLink( void )
{ {
Pback->Pnext = Pnext; Pback->Pnext = Pnext;
} }
else /* Le chainage arriere pointe sur la structure "Pere" */ else /* Le chainage arriere pointe sur la structure "Pere" */
{ {
( (BOARD*) Pback )->m_Drawings = Pnext; ( (BOARD*) Pback )->m_Drawings = Pnext;
@ -44,7 +44,8 @@ void MIREPCB::UnLink( void )
} }
/* Modification du chainage avant */ /* Modification du chainage avant */
if( Pnext) Pnext->Pback = Pback; if( Pnext )
Pnext->Pback = Pback;
Pnext = Pback = NULL; Pnext = Pback = NULL;
} }
@ -66,6 +67,7 @@ void MIREPCB::Copy(MIREPCB * source)
/**************************************************************/ /**************************************************************/
bool MIREPCB::ReadMirePcbDescr( FILE* File, int* LineNum ) bool MIREPCB::ReadMirePcbDescr( FILE* File, int* LineNum )
/**************************************************************/ /**************************************************************/
/* Lecture de la description de 1 segment type Drawing PCB /* Lecture de la description de 1 segment type Drawing PCB
*/ */
{ {
@ -73,7 +75,8 @@ char Line[256];
while( GetLine( File, Line, LineNum ) != NULL ) while( GetLine( File, Line, LineNum ) != NULL )
{ {
if(strnicmp(Line,"$End",4 ) == 0 ) return TRUE; /* fin de liste */ if( strnicmp( Line, "$End", 4 ) == 0 )
return TRUE; /* fin de liste */
if( Line[0] == 'P' ) if( Line[0] == 'P' )
{ {
sscanf( Line + 2, " %X %d %d %d %d %d %lX", sscanf( Line + 2, " %X %d %d %d %d %d %lX",
@ -84,9 +87,9 @@ char Line[256];
m_Layer = FIRST_NO_COPPER_LAYER; m_Layer = FIRST_NO_COPPER_LAYER;
if( m_Layer > LAST_NO_COPPER_LAYER ) if( m_Layer > LAST_NO_COPPER_LAYER )
m_Layer = LAST_NO_COPPER_LAYER; m_Layer = LAST_NO_COPPER_LAYER;
}
}
}
}
return FALSE; return FALSE;
} }
@ -95,7 +98,8 @@ char Line[256];
bool MIREPCB::WriteMirePcbDescr( FILE* File ) bool MIREPCB::WriteMirePcbDescr( FILE* File )
/************************************************/ /************************************************/
{ {
if( GetState(DELETED) ) return FALSE; if( GetState( DELETED ) )
return FALSE;
fprintf( File, "$MIREPCB\n" ); fprintf( File, "$MIREPCB\n" );
fprintf( File, "Po %X %d %d %d %d %d %8.8lX\n", fprintf( File, "Po %X %d %d %d %d %d %8.8lX\n",
@ -111,9 +115,10 @@ bool MIREPCB::WriteMirePcbDescr(FILE * File)
void MIREPCB::Draw( WinEDA_DrawPanel* panel, wxDC* DC, void MIREPCB::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
const wxPoint& offset, int mode_color ) const wxPoint& offset, int mode_color )
/**********************************************************/ /**********************************************************/
/* Affichage de 1 mire : 2 segments + 1 cercle /* Affichage de 1 mire : 2 segments + 1 cercle
le cercle a pour rayon le demi rayon de la mire * le cercle a pour rayon le demi rayon de la mire
les 2 traits ont pour longueur le diametre de la mire * les 2 traits ont pour longueur le diametre de la mire
*/ */
{ {
int rayon, ox, oy, gcolor, width; int rayon, ox, oy, gcolor, width;
@ -125,21 +130,25 @@ int zoom;
oy = m_Pos.y + offset.y; oy = m_Pos.y + offset.y;
gcolor = g_DesignSettings.m_LayerColor[m_Layer]; gcolor = g_DesignSettings.m_LayerColor[m_Layer];
if ( (gcolor & ITEM_NOT_SHOW) != 0 ) return; if( (gcolor & ITEM_NOT_SHOW) != 0 )
return;
zoom = panel->GetZoom(); zoom = panel->GetZoom();
GRSetDrawMode( DC, mode_color ); GRSetDrawMode( DC, mode_color );
typeaff = DisplayOpt.DisplayDrawItems; typeaff = DisplayOpt.DisplayDrawItems;
width = m_Width; width = m_Width;
if( width/zoom < 2 ) typeaff = FILAIRE; if( width / zoom < 2 )
typeaff = FILAIRE;
/* Trace du cercle: */ /* Trace du cercle: */
rayon = m_Size / 4; rayon = m_Size / 4;
switch( typeaff ) switch( typeaff )
{ {
case FILAIRE: case FILAIRE:
width = 0; width = 0;
case FILLED: case FILLED:
GRCircle( &panel->m_ClipBox, DC, ox, oy, rayon, width, gcolor ); GRCircle( &panel->m_ClipBox, DC, ox, oy, rayon, width, gcolor );
break; break;
@ -183,3 +192,19 @@ int zoom;
} }
} }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool MIREPCB::HitTest( const wxPoint& refPos )
{
int dX = refPos.x - m_Pos.x;
int dY = refPos.y - m_Pos.y;
int rayon = m_Size / 2;
return abs(dX)<=rayon && abs(dY)<=rayon;
}

View File

@ -30,8 +30,15 @@ class MIREPCB: public EDA_BaseStruct
void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int mode_color ); void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int mode_color );
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
}; };
#endif // #define MIRE_H #endif // #define MIRE_H

View File

@ -144,7 +144,6 @@ public:
#if defined(DEBUG) #if defined(DEBUG)
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.

View File

@ -12,6 +12,7 @@
#include "cvpcb.h" #include "cvpcb.h"
#endif #endif
#include "trigo.h"
/**************************************/ /**************************************/
@ -31,16 +32,20 @@ TRACK::TRACK(EDA_BaseStruct * StructFather, DrawStructureType idtype):
m_Param = 0; m_Param = 0;
} }
SEGZONE::SEGZONE( EDA_BaseStruct* StructFather ) : SEGZONE::SEGZONE( EDA_BaseStruct* StructFather ) :
TRACK( StructFather, TYPEZONE ) TRACK( StructFather, TYPEZONE )
{ {
} }
SEGVIA::SEGVIA( EDA_BaseStruct* StructFather ) : SEGVIA::SEGVIA( EDA_BaseStruct* StructFather ) :
TRACK( StructFather, TYPEVIA ) TRACK( StructFather, TYPEVIA )
{ {
} }
/* Copy constructor */ /* Copy constructor */
TRACK::TRACK( const TRACK& Source ) : TRACK::TRACK( const TRACK& Source ) :
EDA_BaseLineStruct( Source.m_Parent, (DrawStructureType)Source.m_StructType ) EDA_BaseLineStruct( Source.m_Parent, (DrawStructureType)Source.m_StructType )
@ -58,68 +63,78 @@ TRACK::TRACK(const TRACK & Source):
m_Drill = Source.m_Drill; m_Drill = Source.m_Drill;
m_Sous_Netcode = Source.m_Sous_Netcode; m_Sous_Netcode = Source.m_Sous_Netcode;
m_Param = Source.m_Param; m_Param = Source.m_Param;
} }
/***********************/ /***********************/
bool TRACK::IsNull( void ) bool TRACK::IsNull( void )
/***********************/ /***********************/
// return TRUE if segment lenght = 0
// return TRUE if segment length = 0
{ {
if( ( m_StructType != TYPEVIA ) && ( m_Start == m_End ) ) if( ( m_StructType != TYPEVIA ) && ( m_Start == m_End ) )
return TRUE; return TRUE;
else return FALSE; else
return FALSE;
} }
/*************************************************************/ /*************************************************************/
int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist )
/*************************************************************/ /*************************************************************/
/* Return: /* Return:
STARTPOINT if point if near (dist = min_dist) star point * STARTPOINT if point if near (dist = min_dist) star point
ENDPOINT if point if near (dist = min_dist) end point * ENDPOINT if point if near (dist = min_dist) end point
STARTPOINT|ENDPOINT if point if near (dist = min_dist) both ends * STARTPOINT|ENDPOINT if point if near (dist = min_dist) both ends
0 if no * 0 if no
if min_dist < 0: min_dist = track_width/2 * if min_dist < 0: min_dist = track_width/2
*/ */
{ {
int dx, dy; int dx, dy;
int result = 0; int result = 0;
if ( min_dist < 0 ) min_dist = m_Width / 2; if( min_dist < 0 )
min_dist = m_Width / 2;
dx = m_Start.x - point.x; dx = m_Start.x - point.x;
dy = m_Start.y - point.y; dy = m_Start.y - point.y;
if( min_dist == 0 ) if( min_dist == 0 )
{ {
if( (dx == 0) && (dy == 0 ) ) result |= STARTPOINT; if( (dx == 0) && (dy == 0 ) )
result |= STARTPOINT;
} }
else else
{ {
double dist = ( (double) dx * dx ) + ( (double) dy * dy ); double dist = ( (double) dx * dx ) + ( (double) dy * dy );
dist = sqrt( dist ); dist = sqrt( dist );
if ( min_dist >= (int) dist ) result |= STARTPOINT; if( min_dist >= (int) dist )
result |= STARTPOINT;
} }
dx = m_End.x - point.x; dx = m_End.x - point.x;
dy = m_End.y - point.y; dy = m_End.y - point.y;
if( min_dist == 0 ) if( min_dist == 0 )
{ {
if( (dx == 0) && (dy == 0 ) ) result |= ENDPOINT; if( (dx == 0) && (dy == 0 ) )
result |= ENDPOINT;
} }
else else
{ {
double dist = ( (double) dx * dx ) + ( (double) dy * dy ); double dist = ( (double) dx * dx ) + ( (double) dy * dy );
dist = sqrt( dist ); dist = sqrt( dist );
if ( min_dist >= (int) dist ) result |= ENDPOINT; if( min_dist >= (int) dist )
result |= ENDPOINT;
} }
return result; return result;
} }
/******************************************/ /******************************************/
bool SEGVIA::IsViaOnLayer( int layer_number ) bool SEGVIA::IsViaOnLayer( int layer_number )
/******************************************/ /******************************************/
/* Retoune TRUE si Via sur layer layer_number /* Retoune TRUE si Via sur layer layer_number
*/ */
{ {
@ -127,8 +142,10 @@ int via_type = Shape();
if( via_type == VIA_NORMALE ) if( via_type == VIA_NORMALE )
{ {
if ( layer_number <= LAYER_CMP_N ) return TRUE; if( layer_number <= LAYER_CMP_N )
else return FALSE; return TRUE;
else
return FALSE;
} }
// VIA_BORGNE ou VIA_ENTERREE: // VIA_BORGNE ou VIA_ENTERREE:
@ -137,43 +154,50 @@ int bottom_layer, top_layer;
ReturnLayerPair( &top_layer, &bottom_layer ); ReturnLayerPair( &top_layer, &bottom_layer );
if( (bottom_layer <= layer_number) && (top_layer >= layer_number) ) if( (bottom_layer <= layer_number) && (top_layer >= layer_number) )
return TRUE; return TRUE;
else return FALSE; else
return FALSE;
} }
/***********************************/ /***********************************/
int TRACK::ReturnMaskLayer( void ) int TRACK::ReturnMaskLayer( void )
/***********************************/ /***********************************/
/* Retourne le masque (liste bit a bit ) des couches occupees par le segment /* Retourne le masque (liste bit a bit ) des couches occupees par le segment
de piste pointe par PtSegm. * de piste pointe par PtSegm.
Si PtSegm pointe une via, il y a plusieurs couches occupees * Si PtSegm pointe une via, il y a plusieurs couches occupees
*/ */
{ {
if( m_StructType == TYPEVIA ) if( m_StructType == TYPEVIA )
{ {
int via_type = m_Shape & 15; int via_type = m_Shape & 15;
if( via_type == VIA_NORMALE ) return (ALL_CU_LAYERS); if( via_type == VIA_NORMALE )
return ALL_CU_LAYERS;
// VIA_BORGNE ou VIA_ENTERREE: // VIA_BORGNE ou VIA_ENTERREE:
int bottom_layer = (m_Layer >> 4) & 15; int bottom_layer = (m_Layer >> 4) & 15;
int top_layer = m_Layer & 15; int top_layer = m_Layer & 15;
if ( bottom_layer > top_layer ) EXCHG (bottom_layer, top_layer); if( bottom_layer > top_layer )
EXCHG( bottom_layer, top_layer );
int layermask = 0; int layermask = 0;
while( bottom_layer <= top_layer ) while( bottom_layer <= top_layer )
{ {
layermask |= g_TabOneLayerMask[bottom_layer++]; layermask |= g_TabOneLayerMask[bottom_layer++];
} }
return (layermask);
}
else return(g_TabOneLayerMask[m_Layer]);
}
return layermask;
}
else
return g_TabOneLayerMask[m_Layer];
}
/*********************************************************/ /*********************************************************/
void SEGVIA::SetLayerPair( int top_layer, int bottom_layer ) void SEGVIA::SetLayerPair( int top_layer, int bottom_layer )
/*********************************************************/ /*********************************************************/
/* Met a jour .m_Layer pour une via: /* Met a jour .m_Layer pour une via:
m_Layer code les 2 couches limitant la via * m_Layer code les 2 couches limitant la via
*/ */
{ {
int via_type = m_Shape & 255; int via_type = m_Shape & 255;
@ -183,23 +207,29 @@ int via_type = m_Shape & 255;
top_layer = LAYER_CMP_N; bottom_layer = LAYER_CUIVRE_N; top_layer = LAYER_CMP_N; bottom_layer = LAYER_CUIVRE_N;
} }
if ( bottom_layer > top_layer ) EXCHG (bottom_layer, top_layer); if( bottom_layer > top_layer )
EXCHG( bottom_layer, top_layer );
m_Layer = (top_layer & 15) + ( (bottom_layer & 15) << 4 ); m_Layer = (top_layer & 15) + ( (bottom_layer & 15) << 4 );
} }
/***************************************************************/ /***************************************************************/
void SEGVIA::ReturnLayerPair( int* top_layer, int* bottom_layer ) void SEGVIA::ReturnLayerPair( int* top_layer, int* bottom_layer )
/***************************************************************/ /***************************************************************/
/* Retourne les 2 couches limitant la via /* Retourne les 2 couches limitant la via
les pointeurs top_layer et bottom_layer peuvent etre NULLs * les pointeurs top_layer et bottom_layer peuvent etre NULLs
*/ */
{ {
int b_layer = (m_Layer >> 4) & 15; int b_layer = (m_Layer >> 4) & 15;
int t_layer = m_Layer & 15; int t_layer = m_Layer & 15;
if ( b_layer > t_layer ) EXCHG (b_layer, t_layer); if( b_layer > t_layer )
if ( top_layer ) * top_layer = t_layer; EXCHG( b_layer, t_layer );
if ( bottom_layer ) * bottom_layer = b_layer; if( top_layer )
*top_layer = t_layer;
if( bottom_layer )
*bottom_layer = b_layer;
} }
@ -211,9 +241,8 @@ TRACK * TRACK::Next(void)
} }
/* supprime du chainage la structure Struct /* supprime du chainage la structure Struct
les structures arrieres et avant sont chainees directement * les structures arrieres et avant sont chainees directement
*/ */
void TRACK::UnLink( void ) void TRACK::UnLink( void )
{ {
@ -224,12 +253,12 @@ void TRACK::UnLink( void )
{ {
Pback->Pnext = Pnext; Pback->Pnext = Pnext;
} }
else /* Le chainage arriere pointe sur la structure "Pere" */ else /* Le chainage arriere pointe sur la structure "Pere" */
{ {
if( GetState( DELETED ) ) // A REVOIR car Pback = NULL si place en undelete if( GetState( DELETED ) ) // A REVOIR car Pback = NULL si place en undelete
{ {
if( g_UnDeleteStack ) g_UnDeleteStack[g_UnDeleteStackPtr-1] = Pnext; if( g_UnDeleteStack )
g_UnDeleteStack[g_UnDeleteStackPtr - 1] = Pnext;
} }
else else
{ {
@ -246,22 +275,26 @@ void TRACK::UnLink( void )
} }
/* Modification du chainage avant */ /* Modification du chainage avant */
if( Pnext) Pnext->Pback = Pback; if( Pnext )
Pnext->Pback = Pback;
Pnext = Pback = NULL; Pnext = Pback = NULL;
} }
/************************************************************/ /************************************************************/
void TRACK::Insert( BOARD* Pcb, EDA_BaseStruct* InsertPoint ) void TRACK::Insert( BOARD* Pcb, EDA_BaseStruct* InsertPoint )
/************************************************************/ /************************************************************/
/* Ajoute un element ou une liste a une liste de base /* Ajoute un element ou une liste a une liste de base
Si Insertpoint == NULL: insertion en debut de * Si Insertpoint == NULL: insertion en debut de
liste Pcb->Track ou Pcb->Zone * liste Pcb->Track ou Pcb->Zone
Insertion a la suite de InsertPoint * Insertion a la suite de InsertPoint
Si InsertPoint == NULL, insertion en tete de liste * Si InsertPoint == NULL, insertion en tete de liste
*/ */
{ {
TRACK* track, * NextS; TRACK* track, * NextS;
/* Insertion du debut de la chaine a greffer */ /* Insertion du debut de la chaine a greffer */
if( InsertPoint == NULL ) if( InsertPoint == NULL )
{ {
@ -275,7 +308,6 @@ TRACK* track, *NextS;
NextS = Pcb->m_Track; Pcb->m_Track = this; NextS = Pcb->m_Track; Pcb->m_Track = this;
} }
} }
else else
{ {
NextS = (TRACK*) InsertPoint->Pnext; NextS = (TRACK*) InsertPoint->Pnext;
@ -285,98 +317,123 @@ TRACK* track, *NextS;
/* Chainage de la fin de la liste a greffer */ /* Chainage de la fin de la liste a greffer */
track = this; track = this;
while ( track->Pnext ) track = (TRACK*) track->Pnext; while( track->Pnext )
track = (TRACK*) track->Pnext;
/* Track pointe la fin de la chaine a greffer */ /* Track pointe la fin de la chaine a greffer */
track->Pnext = NextS; track->Pnext = NextS;
if ( NextS ) NextS->Pback = track; if( NextS )
NextS->Pback = track;
} }
/***********************************************/ /***********************************************/
TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb ) TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb )
/***********************************************/ /***********************************************/
/* Recherche du meilleur point d'insertion pour le nouveau segment de piste /* Recherche du meilleur point d'insertion pour le nouveau segment de piste
Retourne * Retourne
un pointeur sur le segment de piste APRES lequel l'insertion * un pointeur sur le segment de piste APRES lequel l'insertion
doit se faire ( dernier segment du net d'apartenance ) * doit se faire ( dernier segment du net d'apartenance )
NULL si pas de piste ( liste vide ); * NULL si pas de piste ( liste vide );
*/ */
{ {
TRACK* track, * NextTrack; TRACK* track, * NextTrack;
if( m_StructType == TYPEZONE ) track = Pcb->m_Zone; if( m_StructType == TYPEZONE )
else track = Pcb->m_Track; track = Pcb->m_Zone;
else
track = Pcb->m_Track;
/* Traitement du debut de liste */ /* Traitement du debut de liste */
if ( track == NULL ) return(NULL); /* pas de piste ! */ if( track == NULL )
return NULL; /* pas de piste ! */
if( m_NetCode < track->m_NetCode ) /* insertion en tete de liste */ if( m_NetCode < track->m_NetCode ) /* insertion en tete de liste */
return(NULL); return NULL;
while( (NextTrack = (TRACK*) track->Pnext) != NULL ) while( (NextTrack = (TRACK*) track->Pnext) != NULL )
{ {
if ( NextTrack->m_NetCode > this->m_NetCode ) break; if( NextTrack->m_NetCode > this->m_NetCode )
break;
track = NextTrack; track = NextTrack;
} }
return ( track);
return track;
} }
/* Recherche du debut du net /* Recherche du debut du net
( les elements sont classes par net_code croissant ) * ( les elements sont classes par net_code croissant )
la recherche se fait a partir de this * la recherche se fait a partir de this
si net_code == -1 le netcode de this sera utilise * si net_code == -1 le netcode de this sera utilise
Retourne un pointeur sur le debut du net, ou NULL si net non trouve * Retourne un pointeur sur le debut du net, ou NULL si net non trouve
*/ */
TRACK* TRACK::GetStartNetCode( int NetCode ) TRACK* TRACK::GetStartNetCode( int NetCode )
{ {
TRACK* Track = this; TRACK* Track = this;
int ii = 0; int ii = 0;
if( NetCode == -1 ) NetCode = m_NetCode; if( NetCode == -1 )
NetCode = m_NetCode;
while( Track != NULL ) while( Track != NULL )
{ {
if ( Track->m_NetCode > NetCode ) break; if( Track->m_NetCode > NetCode )
break;
if( Track->m_NetCode == NetCode ) if( Track->m_NetCode == NetCode )
{ {
ii++; break; ii++; break;
} }
Track = (TRACK*) Track->Pnext; Track = (TRACK*) Track->Pnext;
} }
if ( ii ) return(Track);
else return (NULL); if( ii )
return Track;
else
return NULL;
} }
/* Recherche de la fin du net /* Recherche de la fin du net
Retourne un pointeur sur la fin du net, ou NULL si net non trouve * Retourne un pointeur sur la fin du net, ou NULL si net non trouve
*/ */
TRACK* TRACK::GetEndNetCode( int NetCode ) TRACK* TRACK::GetEndNetCode( int NetCode )
{ {
TRACK* NextS, * Track = this; TRACK* NextS, * Track = this;
int ii = 0; int ii = 0;
if( Track == NULL ) return(NULL); if( Track == NULL )
return NULL;
if( NetCode == -1 ) NetCode = m_NetCode; if( NetCode == -1 )
NetCode = m_NetCode;
while( Track != NULL ) while( Track != NULL )
{ {
NextS = (TRACK*) Track->Pnext; NextS = (TRACK*) Track->Pnext;
if(Track->m_NetCode == NetCode) ii++; if( Track->m_NetCode == NetCode )
if ( NextS == NULL ) break; ii++;
if ( NextS->m_NetCode > NetCode) break; if( NextS == NULL )
break;
if( NextS->m_NetCode > NetCode )
break;
Track = NextS; Track = NextS;
} }
if ( ii ) return(Track);
else return (NULL); if( ii )
return Track;
else
return NULL;
} }
/**********************************/ /**********************************/
TRACK* TRACK:: Copy( int NbSegm ) TRACK* TRACK:: Copy( int NbSegm )
/**********************************/ /**********************************/
/* Copie d'un Element ou d'une chaine de n elements /* Copie d'un Element ou d'une chaine de n elements
Retourne un pointeur sur le nouvel element ou le debut de la * Retourne un pointeur sur le nouvel element ou le debut de la
nouvelle chaine * nouvelle chaine
*/ */
{ {
TRACK* NewTrack, * FirstTrack, * OldTrack, * Source = this; TRACK* NewTrack, * FirstTrack, * OldTrack, * Source = this;
@ -387,15 +444,17 @@ int ii;
for( ii = 1; ii < NbSegm; ii++ ) for( ii = 1; ii < NbSegm; ii++ )
{ {
Source = Source->Next(); Source = Source->Next();
if( Source == NULL ) break; if( Source == NULL )
break;
OldTrack = NewTrack; OldTrack = NewTrack;
NewTrack = new TRACK( *Source ); NewTrack = new TRACK( *Source );
NewTrack->Insert( NULL, OldTrack ); NewTrack->Insert( NULL, OldTrack );
} }
return (FirstTrack); return FirstTrack;
} }
/********************************************/ /********************************************/
bool TRACK::WriteTrackDescr( FILE* File ) bool TRACK::WriteTrackDescr( FILE* File )
/********************************************/ /********************************************/
@ -403,9 +462,11 @@ bool TRACK::WriteTrackDescr(FILE * File)
int type; int type;
type = 0; type = 0;
if( m_StructType == TYPEVIA ) type = 1; if( m_StructType == TYPEVIA )
type = 1;
if( GetState(DELETED) ) return FALSE; if( GetState( DELETED ) )
return FALSE;
fprintf( File, "Po %d %d %d %d %d %d %d\n", m_Shape, fprintf( File, "Po %d %d %d %d %d %d %d\n", m_Shape,
m_Start.x, m_Start.y, m_End.x, m_End.y, m_Width, m_Drill ); m_Start.x, m_Start.y, m_End.x, m_End.y, m_Width, m_Drill );
@ -416,12 +477,14 @@ int type;
return TRUE; return TRUE;
} }
/**********************************************************************/ /**********************************************************************/
void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode ) void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode )
/*********************************************************************/ /*********************************************************************/
/* routine de trace de 1 segment de piste. /* routine de trace de 1 segment de piste.
Parametres : * Parametres :
draw_mode = mode ( GR_XOR, GR_OR..) * draw_mode = mode ( GR_XOR, GR_OR..)
*/ */
{ {
int l_piste; int l_piste;
@ -437,9 +500,11 @@ int curr_layer = ((PCB_SCREEN*)panel->GetScreen())->m_Active_Layer;
if( m_StructType == TYPEVIA ) /* VIA rencontree */ if( m_StructType == TYPEVIA ) /* VIA rencontree */
color = g_DesignSettings.m_ViaColor[m_Shape]; color = g_DesignSettings.m_ViaColor[m_Shape];
else color = g_DesignSettings.m_LayerColor[m_Layer]; else
color = g_DesignSettings.m_LayerColor[m_Layer];
if( (color & (ITEM_NOT_SHOW | HIGHT_LIGHT_FLAG)) == ITEM_NOT_SHOW) return ; if( ( color & (ITEM_NOT_SHOW | HIGHT_LIGHT_FLAG) ) == ITEM_NOT_SHOW )
return;
if( DisplayOpt.ContrastModeDisplay ) if( DisplayOpt.ContrastModeDisplay )
{ {
@ -460,8 +525,10 @@ int curr_layer = ((PCB_SCREEN*)panel->GetScreen())->m_Active_Layer;
if( draw_mode & GR_SURBRILL ) if( draw_mode & GR_SURBRILL )
{ {
if( draw_mode & GR_AND) color &= ~HIGHT_LIGHT_FLAG; if( draw_mode & GR_AND )
else color |= HIGHT_LIGHT_FLAG; color &= ~HIGHT_LIGHT_FLAG;
else
color |= HIGHT_LIGHT_FLAG;
} }
if( color & HIGHT_LIGHT_FLAG ) if( color & HIGHT_LIGHT_FLAG )
color = ColorRefs[color & MASKCOLOR].m_LightColor; color = ColorRefs[color & MASKCOLOR].m_LightColor;
@ -472,21 +539,25 @@ int curr_layer = ((PCB_SCREEN*)panel->GetScreen())->m_Active_Layer;
if( m_StructType == TYPEVIA ) /* VIA rencontree */ if( m_StructType == TYPEVIA ) /* VIA rencontree */
{ {
rayon = l_piste; if( rayon < zoom ) rayon = zoom; rayon = l_piste; if( rayon < zoom )
rayon = zoom;
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color );
if( rayon > (4 * zoom) ) if( rayon > (4 * zoom) )
{ {
int drill_rayon, inner_rayon = rayon - (2 * zoom); int drill_rayon, inner_rayon = rayon - (2 * zoom);
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
inner_rayon, color ); inner_rayon, color );
// Draw the via hole if the display option request it // Draw the via hole if the display option request it
if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW )
{ {
if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW)
|| ( m_Drill > 0 ) ) || ( m_Drill > 0 ) )
{ {
if ( m_Drill > 0 ) drill_rayon = m_Drill / 2; if( m_Drill > 0 )
else drill_rayon = g_DesignSettings.m_ViaDrill / 2; drill_rayon = m_Drill / 2;
else
drill_rayon = g_DesignSettings.m_ViaDrill / 2;
if( drill_rayon < inner_rayon ) // We can show the via hole if( drill_rayon < inner_rayon ) // We can show the via hole
{ {
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
@ -510,7 +581,6 @@ int curr_layer = ((PCB_SCREEN*)panel->GetScreen())->m_Active_Layer;
{ {
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color );
} }
else else
{ {
if( l_piste <= zoom ) /* trace simplifie si l_piste/zoom <= 1 */ if( l_piste <= zoom ) /* trace simplifie si l_piste/zoom <= 1 */
@ -560,3 +630,47 @@ int curr_layer = ((PCB_SCREEN*)panel->GetScreen())->m_Active_Layer;
} }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool TRACK::HitTest( const wxPoint& ref_pos )
{
int l_piste; /* demi-largeur de la piste */
int dx, dy, spot_cX, spot_cY;
int ux0, uy0;
/* calcul des coordonnees du segment teste */
l_piste = m_Width >> 1; /* l_piste = demi largeur piste */
ux0 = m_Start.x;
uy0 = m_Start.y; /* coord de depart */
dx = m_End.x;
dy = m_End.y; /* coord d'arrivee */
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx -= ux0;
dy -= uy0;
spot_cX = ref_pos.x - ux0;
spot_cY = ref_pos.y - uy0;
if( m_StructType == TYPEVIA ) /* VIA rencontree */
{
if( (abs( spot_cX ) <= l_piste ) && (abs( spot_cY ) <=l_piste) )
return true;
else
return false;
}
else
{
if( DistanceTest( l_piste, dx, dy, spot_cX, spot_cY ) )
return true;
}
return false;
}

View File

@ -27,7 +27,8 @@ public:
EDA_BaseStruct* start, * end; // pointers on a connected item (pad or track) EDA_BaseStruct* start, * end; // pointers on a connected item (pad or track)
int m_NetCode; // Net number int m_NetCode; // Net number
int m_Sous_Netcode; /* In rastnest routines : for the current net, int m_Sous_Netcode; /* In rastnest routines : for the current net,
block number (number common to the current connected items found) */ * block number (number common to the current connected items found) */
// chain = 0 indique une connexion non encore traitee // chain = 0 indique une connexion non encore traitee
int m_Param; // Auxiliary variable ( used in some computations ) int m_Param; // Auxiliary variable ( used in some computations )
@ -36,11 +37,13 @@ public:
TRACK( const TRACK& track ); TRACK( const TRACK& track );
TRACK* Next( void ); // Retourne le chainage avant TRACK* Next( void ); // Retourne le chainage avant
TRACK* Back( void ) // Retourne le chainage avant TRACK* Back( void ) // Retourne le chainage avant
{ {
return (TRACK*) Pback; return (TRACK*) Pback;
} }
/* supprime du chainage la structure Struct */ /* supprime du chainage la structure Struct */
void UnLink( void ); void UnLink( void );
@ -57,8 +60,9 @@ public:
TRACK* Copy( int NbSegm = 1 ); TRACK* Copy( int NbSegm = 1 );
/* Recherche du debut du net /* Recherche du debut du net
( les elements sont classes par net_code croissant ) */ * ( les elements sont classes par net_code croissant ) */
TRACK* GetStartNetCode( int NetCode ); TRACK* GetStartNetCode( int NetCode );
/* Recherche de la fin du net */ /* Recherche de la fin du net */
TRACK* GetEndNetCode( int NetCode ); TRACK* GetEndNetCode( int NetCode );
@ -71,12 +75,47 @@ public:
int ReturnMaskLayer( void ); int ReturnMaskLayer( void );
int IsPointOnEnds( const wxPoint& point, int min_dist = 0 ); int IsPointOnEnds( const wxPoint& point, int min_dist = 0 );
bool IsNull( void ); // return TRUE if segment lenght = 0 bool IsNull( void ); // return TRUE if segment lenght = 0
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
#if defined(DEBUG)
/**
* Function GetClass
* returns the class name.
* @return wxString
*/
wxString GetClass() const
{
return wxT("TRACK");
}
#endif
}; };
class SEGZONE : public TRACK class SEGZONE : public TRACK
{ {
public: public:
SEGZONE( EDA_BaseStruct* StructFather ); SEGZONE( EDA_BaseStruct* StructFather );
#if defined(DEBUG)
/**
* Function GetClass
* returns the class name.
* @return wxString
*/
wxString GetClass() const
{
return wxT("ZONE");
}
#endif
}; };
class SEGVIA : public TRACK class SEGVIA : public TRACK
@ -86,8 +125,20 @@ public:
bool IsViaOnLayer( int layer ); bool IsViaOnLayer( int layer );
void SetLayerPair( int top_layer, int bottom_layer ); void SetLayerPair( int top_layer, int bottom_layer );
void ReturnLayerPair( int* top_layer, int* bottom_layer ); void ReturnLayerPair( int* top_layer, int* bottom_layer );
#if defined(DEBUG)
/**
* Function GetClass
* returns the class name.
* @return wxString
*/
wxString GetClass() const
{
return wxT("VIA");
}
#endif
}; };
#endif /* CLASS_TRACK_H */ #endif /* CLASS_TRACK_H */

View File

@ -16,6 +16,7 @@
#endif #endif
#include "protos.h" #include "protos.h"
#include "trigo.h"
/**************************************************************/ /**************************************************************/
@ -165,6 +166,61 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( FILE* File, int* LineNum )
} }
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param ref_pos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool DRAWSEGMENT::HitTest( const wxPoint& ref_pos )
{
int ux0 = m_Start.x;
int uy0 = m_Start.y;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
int dx = m_End.x - ux0;
int dy = m_End.y - uy0;
int spot_cX = ref_pos.x - ux0;
int spot_cY = ref_pos.y - uy0;
if( m_Shape==S_CIRCLE || m_Shape==S_ARC )
{
int rayon, dist, stAngle, endAngle, mouseAngle;
rayon = (int) hypot( (double) (dx), (double) (dy) );
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
if( abs( rayon - dist ) <= (m_Width / 2) )
{
if( m_Shape == S_CIRCLE )
return true;
/* pour un arc, controle complementaire */
mouseAngle = (int) ArcTangente( spot_cY, spot_cX );
stAngle = (int) ArcTangente( dy, dx );
endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
{
stAngle -= 3600;
endAngle -= 3600;
}
if( mouseAngle >= stAngle && mouseAngle <= endAngle )
return true;
}
}
else
{
if( DistanceTest( m_Width / 2, dx, dy, spot_cX, spot_cY ) )
return true;
}
return false;
}
/*******************/ /*******************/
/* Classe MARQUEUR */ /* Classe MARQUEUR */
/*******************/ /*******************/

File diff suppressed because it is too large Load Diff

View File

@ -128,8 +128,7 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
#if defined(DEBUG) #if defined(DEBUG)
DrawStruct = m_Pcb->FindPadOrModule( DrawStruct = m_Pcb->FindPadOrModule(
GetScreen()->RefPos(true), GetScreen()->RefPos(true),
GetScreen()->m_Active_Layer, GetScreen()->m_Active_Layer );
VISIBLE_ONLY );
#else #else
DrawStruct = PcbGeneralLocateAndDisplay(); DrawStruct = PcbGeneralLocateAndDisplay();
#endif #endif

View File

@ -14,9 +14,6 @@
#include "protos.h" #include "protos.h"
/* variables locales */
int ux0, uy0, dx, dy, spot_cX, spot_cY; /* Variables utilisees pour
* 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 );
@ -302,72 +299,21 @@ EDGE_MODULE* Locate_Edge_Module( MODULE* module, int typeloc )
* NULL si rien trouve * NULL si rien trouve
*/ */
{ {
EDGE_MODULE* edge_mod;
EDA_BaseStruct* PtStruct;
int uxf, uyf, type_trace;
int rayon, dist;
wxPoint ref_pos; /* coord du point de localisation */
/* pour localisation d'arcs, angle du point de debut, de fin et du point de reference */
int StAngle, EndAngle, MouseAngle;
if( !module ) if( !module )
return NULL; return NULL;
ref_pos = RefPos( typeloc ); /* coord du point de localisation */
wxPoint ref_pos = RefPos( typeloc );
PtStruct = module->m_Drawings; EDA_BaseStruct* PtStruct = module->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPEEDGEMODULE ) if( PtStruct->m_StructType != TYPEEDGEMODULE )
continue; continue;
edge_mod = (EDGE_MODULE*) PtStruct; // calls virtual EDGE_MODULE::HitTest()
type_trace = edge_mod->m_Shape; if( PtStruct->HitTest( ref_pos ) )
ux0 = edge_mod->m_Start.x; uy0 = edge_mod->m_Start.y; return (EDGE_MODULE*) PtStruct;
uxf = edge_mod->m_End.x; uyf = edge_mod->m_End.y;
switch( type_trace )
{
case S_SEGMENT:
/* recalcul des coordonnees avec ux0,uy0 = origine des coord. */
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
dx = uxf - ux0; dy = uyf - uy0;
/* detection : */
if( distance( edge_mod->m_Width / 2 ) )
return edge_mod;
break;
case S_CIRCLE:
rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) );
dist = (int) hypot( (double) (ref_pos.x - ux0), (double) (ref_pos.y - uy0) );
if( abs( rayon - dist ) <= edge_mod->m_Width )
return edge_mod;
break;
case S_ARC:
rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) );
dist = (int) hypot( (double) (ref_pos.x - ux0), (double) (ref_pos.y - uy0) );
if( abs( rayon - dist ) > edge_mod->m_Width )
break;
/* pour un arc, controle complementaire */
MouseAngle = (int) ArcTangente( ref_pos.y - uy0, ref_pos.x - ux0 );
StAngle = (int) ArcTangente( uyf - uy0, uxf - ux0 );
EndAngle = StAngle + edge_mod->m_Angle;
if( EndAngle > 3600 )
{
StAngle -= 3600; EndAngle -= 3600;
}
if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) )
return edge_mod;
break;
}
} }
return NULL; return NULL;
@ -383,105 +329,17 @@ EDA_BaseStruct* Locate_Cotation( BOARD* Pcb, int LayerSearch, int typeloc )
* return a pointer to the located item, or NULL * return a pointer to the located item, or NULL
*/ */
{ {
EDA_BaseStruct* PtStruct; wxPoint ref_pos = RefPos( typeloc );
COTATION* Cotation;
TEXTE_PCB* pt_txt;
wxPoint ref_pos;
int ux0, uy0;
ref_pos = RefPos( typeloc ); EDA_BaseStruct* 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 ) if( PtStruct->m_StructType != TYPECOTATION )
continue; continue;
Cotation = (COTATION*) PtStruct; // calls virtual COTATION::HitTest()
if( (Cotation->m_Layer != LayerSearch) && (LayerSearch != -1) ) if( PtStruct->HitTest( ref_pos ) )
continue; return (COTATION*) PtStruct;
/* Localisation du texte ? */
pt_txt = Cotation->m_Text;
if( pt_txt )
{
// because HitTest() is present in both base classes of TEXTE_PCB
// use a dis-ambiguating cast to tell compiler which HitTest()
// to call.
if( static_cast<EDA_TextStruct*>(pt_txt)->HitTest( ref_pos ) )
return PtStruct;
}
/* Localisation des SEGMENTS ?) */
ux0 = Cotation->Barre_ox; uy0 = Cotation->Barre_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->Barre_fx - ux0; dy = Cotation->Barre_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
ux0 = Cotation->TraitG_ox; uy0 = Cotation->TraitG_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->TraitG_fx - ux0; dy = Cotation->TraitG_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
ux0 = Cotation->TraitD_ox; uy0 = Cotation->TraitD_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->TraitD_fx - ux0; dy = Cotation->TraitD_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
ux0 = Cotation->FlecheD1_ox; uy0 = Cotation->FlecheD1_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheD1_fx - ux0; dy = Cotation->FlecheD1_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
ux0 = Cotation->FlecheD2_ox; uy0 = Cotation->FlecheD2_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheD2_fx - ux0; dy = Cotation->FlecheD2_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
ux0 = Cotation->FlecheG1_ox; uy0 = Cotation->FlecheG1_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheG1_fx - ux0; dy = Cotation->FlecheG1_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
ux0 = Cotation->FlecheG2_ox; uy0 = Cotation->FlecheG2_oy;
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = Cotation->FlecheG2_fx - ux0; dy = Cotation->FlecheG2_fy - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( distance( Cotation->m_Width / 2 ) )
return PtStruct;
} }
return NULL; return NULL;
@ -499,75 +357,34 @@ DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc )
* Le segment sur la couche active est détecté en priorite * Le segment sur la couche active est détecté en priorite
*/ */
{ {
EDA_BaseStruct* PtStruct;
DRAWSEGMENT* pts, * locate_segm = NULL; DRAWSEGMENT* locate_segm = NULL;
wxPoint ref_pos;
PCB_SCREEN* screen = (PCB_SCREEN*) ActiveScreen; PCB_SCREEN* screen = (PCB_SCREEN*) ActiveScreen;
ref_pos = RefPos( typeloc ); wxPoint ref_pos = RefPos( typeloc );
PtStruct = Pcb->m_Drawings; EDA_BaseStruct* PtStruct = Pcb->m_Drawings;
for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
{ {
if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) if( PtStruct->m_StructType != TYPEDRAWSEGMENT )
continue; continue;
pts = (DRAWSEGMENT*) PtStruct;
DRAWSEGMENT* 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; if( pts->HitTest( ref_pos ) )
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx = pts->m_End.x - ux0; dy = pts->m_End.y - uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
/* detection : */
if( (pts->m_Shape == S_CIRCLE) || (pts->m_Shape == S_ARC) )
{
int rayon, dist, StAngle, EndAngle, MouseAngle;
rayon = (int) hypot( (double) (dx), (double) (dy) );
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
if( abs( rayon - dist ) <= (pts->m_Width / 2) )
{
if( pts->m_Shape == S_CIRCLE )
{ {
// return this hit if layer matches, else remember in
// case no layer match is found.
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;
}
/* pour un arc, controle complementaire */
MouseAngle = (int) ArcTangente( spot_cY, spot_cX );
StAngle = (int) ArcTangente( dy, dx );
EndAngle = StAngle + pts->m_Angle;
if( EndAngle > 3600 )
{
StAngle -= 3600; EndAngle -= 3600;
}
if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) )
{
if( pts->m_Layer == screen->m_Active_Layer )
return pts;
else if( !locate_segm ) else if( !locate_segm )
locate_segm = pts; locate_segm = pts;
} }
} }
}
else
{
if( distance( pts->m_Width / 2 ) )
{
if( pts->m_Layer == screen->m_Active_Layer )
return pts;
else if( !locate_segm )
locate_segm = pts;
}
}
}
return locate_segm; return locate_segm;
} }
@ -651,14 +468,6 @@ D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer )
D_PAD* pt_pad = module->m_Pads; D_PAD* 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 )
{ {
/*
wxPoint shape_pos = ReturnShapePos();
why the global ux0?
ux0 = shape_pos.x;
uy0 = shape_pos.y; // pos x,y du centre du pad
*/
/* ... et sur la bonne couche */ /* ... et sur la bonne couche */
if( (pt_pad->m_Masque_Layer & masque_layer) == 0 ) if( (pt_pad->m_Masque_Layer & masque_layer) == 0 )
continue; continue;
@ -704,8 +513,6 @@ MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() ) if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() )
continue; continue;
/* Localisation: test des dimensions minimales, choix du meilleur candidat */
/* calcul de priorite: la priorite est donnee a la couche /* calcul de priorite: la priorite est donnee a la couche
* d'appartenance du module et a la couche cuivre si le module * d'appartenance du module et a la couche cuivre si le module
* est sur couche serigr,adhesive cuivre, a la couche cmp si le module * est sur couche serigr,adhesive cuivre, a la couche cmp si le module
@ -718,6 +525,8 @@ MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc )
else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP ) else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP )
layer = CMP_N; layer = CMP_N;
/* Localisation: test des dimensions minimales, choix du meilleur candidat */
/* 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();
@ -998,41 +807,29 @@ TRACK* Locate_Pistes( TRACK* start_adresse, int MasqueLayer, int typeloc )
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 */ for( TRACK* Track = start_adresse; Track; Track = (TRACK*) Track->Pnext )
int l_piste; /* demi-largeur de la piste */
for( Track = start_adresse; Track != NULL; Track = (TRACK*) Track->Pnext )
{ {
if( Track->GetState( BUSY | DELETED ) ) if( Track->GetState( BUSY | DELETED ) )
continue; 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 */
l_piste = Track->m_Width >> 1; /* l_piste = demi largeur piste */
ux0 = Track->m_Start.x; uy0 = Track->m_Start.y; /* coord de depart */
dx = Track->m_End.x; dy = Track->m_End.y; /* coord d'arrivee */
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx -= ux0; dy -= uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
if( Track->m_StructType == TYPEVIA ) /* VIA rencontree */ if( Track->m_StructType == TYPEVIA ) /* VIA rencontree */
{ {
if( (abs( spot_cX ) <= l_piste ) && (abs( spot_cY ) <=l_piste) ) if( Track->HitTest( ref_pos ) )
{
return Track; return Track;
} }
continue; else
} {
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 ) ) if( Track->HitTest( ref_pos ) )
return Track; return Track;
} }
}
return NULL; return NULL;
} }
@ -1065,23 +862,12 @@ TRACK* Locate_Zone( TRACK* start_adresse, int layer, int typeloc )
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 */ for( TRACK* Zone = start_adresse; Zone; Zone = (TRACK*) Zone->Pnext )
int l_segm; /* demi-largeur de la piste */
for( Zone = start_adresse; Zone != NULL; Zone = (TRACK*) Zone->Pnext )
{ {
/* calcul des coordonnees du segment teste */
l_segm = Zone->m_Width >> 1; /* l_piste = demi largeur piste */
ux0 = Zone->m_Start.x; uy0 = Zone->m_Start.y; /* coord de depart */
dx = Zone->m_End.x; dy = Zone->m_End.y; /* coord d'arrivee */
/* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */
dx -= ux0; dy -= uy0;
spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0;
if( (layer != -1) && (Zone->m_Layer != layer) ) if( (layer != -1) && (Zone->m_Layer != layer) )
continue; continue;
if( distance( l_segm ) )
if( Zone->HitTest( ref_pos ) )
return Zone; return Zone;
} }
@ -1123,159 +909,6 @@ TEXTE_PCB* Locate_Texte_Pcb( EDA_BaseStruct* PtStruct, int LayerSearch, int type
} }
/*****************************/
int distance( int seuil )
/*****************************/
/*
* Calcul de la distance du curseur souris a un segment de droite :
* ( piste, edge, contour module ..
* retourne:
* 0 si distance > seuil
* 1 si distance <= seuil
* Variables utilisees ( doivent etre initialisees avant appel , et
* sont ramenees au repere centre sur l'origine du segment)
* dx, dy = coord de l'extremite segment.
* spot_cX,spot_cY = coord du curseur souris
* la recherche se fait selon 4 cas:
* segment horizontal
* segment vertical
* segment 45
* segment quelconque
*/
{
int cXrot, cYrot, /* coord du point (souris) dans le repere tourne */
segX, segY; /* coord extremite segment tj >= 0 */
int pointX, pointY; /* coord point a tester dans repere modifie dans lequel
* segX et segY sont >=0 */
segX = dx; segY = dy; pointX = spot_cX; pointY = spot_cY;
/*Recalcul coord pour que le segment soit dans 1er quadrant (coord >= 0)*/
if( segX < 0 ) /* mise en >0 par symetrie par rapport a l'axe Y */
{
segX = -segX; pointX = -pointX;
}
if( segY < 0 ) /* mise en > 0 par symetrie par rapport a l'axe X */
{
segY = -segY; pointY = -pointY;
}
if( segY == 0 ) /* piste Horizontale */
{
if( abs( pointY ) <= seuil )
{
if( (pointX >= 0) && (pointX <= segX) )
return 1;
/* Etude des extremites : cercle de rayon seuil */
if( (pointX < 0) && (pointX >= -seuil) )
{
if( ( (pointX * pointX) + (pointY * pointY) ) <= (seuil * seuil) )
return 1;
}
if( (pointX > segX) && ( pointX <= (segX + seuil) ) )
{
if( ( ( (pointX - segX) * (pointX - segX) ) + (pointY * pointY) ) <=
(seuil * seuil) )
return 1;
}
}
}
else if( segX == 0 ) /* piste verticale */
{
if( abs( pointX ) <= seuil )
{
if( (pointY >= 0 ) && (pointY <= segY) )
return 1;
if( (pointY < 0) && (pointY >= -seuil) )
{
if( ( (pointY * pointY) + (pointX * pointX) ) <= (seuil * seuil) )
return 1;
}
if( (pointY > segY) && ( pointY <= (segY + seuil) ) )
{
if( ( ( (pointY - segY) * (pointY - segY) ) + (pointX * pointX) ) <=
(seuil * seuil) )
return 1;
}
}
}
else if( segX == segY ) /* piste a 45 degre */
{
/* on fait tourner les axes de 45 degre. la souris a alors les
* coord : x1 = x*cos45 + y*sin45
* y1 = y*cos45 - x*sin45
* et le segment de piste est alors horizontal.
* recalcul des coord de la souris ( sin45 = cos45 = .707 = 7/10
* remarque : sin ou cos45 = .707, et lors du recalcul des coord
* dx45 et dy45, lec coeff .707 est neglige, dx et dy sont en fait .707 fois
* trop grands. (c.a.d trop petits)
* spot_cX,Y doit etre * par .707 * .707 = 0.5 */
cXrot = (pointX + pointY) >> 1;
cYrot = (pointY - pointX) >> 1;
/* recalcul des coord de l'extremite du segment , qui sera vertical
* suite a l'orientation des axes sur l'ecran : dx45 = pointX (ou pointY)
* et est en fait 1,414 plus grand , et dy45 = 0 */
// seuil doit etre * .707 pour tenir compte du coeff de reduction sur dx,dy
seuil *= 7; seuil /= 10;
if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */
{
if( (cXrot >= 0) && (cXrot <= segX) )
return 1;
/* Etude des extremites : cercle de rayon seuil */
if( (cXrot < 0) && (cXrot >= -seuil) )
{
if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) )
return 1;
}
if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) )
{
if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) )
return 1;
}
}
}
else /* orientation quelconque */
{
/* On fait un changement d'axe (rotation) de facon a ce que le segment
* de piste soit horizontal dans le nouveau repere */
int angle;
angle = (int) ( atan2( (float) segY, (float) segX ) * 1800 / M_PI);
cXrot = pointX; cYrot = pointY;
RotatePoint( &cXrot, &cYrot, angle ); /* Rotation du point a tester */
RotatePoint( &segX, &segY, angle ); /* Rotation du segment */
/* la piste est Horizontale , par suite des modifs de coordonnes
* et d'axe, donc segX = longueur du segment */
if( abs( cYrot ) <= seuil ) /* ok sur axe vertical) */
{
if( (cXrot >= 0) && (cXrot <= segX) )
return 1;
/* Etude des extremites : cercle de rayon seuil */
if( (cXrot < 0) && (cXrot >= -seuil) )
{
if( ( (cXrot * cXrot) + (cYrot * cYrot) ) <= (seuil * seuil) )
return 1;
}
if( (cXrot > segX) && ( cXrot <= (segX + seuil) ) )
{
if( ( ( (cXrot - segX) * (cXrot - segX) ) + (cYrot * cYrot) ) <= (seuil * seuil) )
return 1;
}
}
}
return 0;
}
/*******************************************************************************/ /*******************************************************************************/
D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int masque_layer ) D_PAD* Fast_Locate_Pad_Connecte( BOARD* Pcb, const wxPoint& ref_pos, int masque_layer )
@ -1396,11 +1029,10 @@ EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch,
int typeloc ) int typeloc )
/***********************************************************************/ /***********************************************************************/
/* Serach for a photo target /* Search for a photo target
*/ */
{ {
wxPoint ref_pos;/* coord du point de localisation */ wxPoint ref_pos;/* coord du point de localisation */
int dX, dY, rayon;
if( PtStruct == NULL ) if( PtStruct == NULL )
return NULL; return NULL;
@ -1417,13 +1049,10 @@ EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch,
if( LayerSearch != -1 && item->m_Layer != LayerSearch ) if( LayerSearch != -1 && item->m_Layer != LayerSearch )
continue; continue;
dX = ref_pos.x - item->m_Pos.x; if( item->HitTest( ref_pos ) )
dY = ref_pos.y - item->m_Pos.y; break;
rayon = item->m_Size / 2;
if( (abs( dX ) <= rayon ) && ( abs( dY ) <= rayon ) )
break; /* Mire Localisee */
} }
return PtStruct; return PtStruct;
} }

View File

@ -198,24 +198,6 @@ D_PAD * Fast_Locate_Pad_Connecte(BOARD * Pcb, const wxPoint & ref_pos, int layer
(bonne position ET bonne couche). */ (bonne position ET bonne couche). */
int distance(int seuil);
/*
Calcul de la distance du curseur souris a un segment de droite :
( piste, edge, contour module ..
retourne:
0 si distance > seuil
1 si distance <= seuil
Variables utilisees ( externes doivent etre initialisees avant appel , et
sont ramenees au repere centre sur l'origine du segment)
dx, dy = coord de l'extremite segment.
spot_cX,spot_cY = coord du curseur souris
la recherche se fait selon 4 cas:
segment horizontal
segment vertical
segment 45
segment quelconque
*/
TRACK * Locate_Zone(TRACK * start_adresse,int layer, int typeloc); TRACK * Locate_Zone(TRACK * start_adresse,int layer, int typeloc);
TRACK * Locate_Zone(TRACK * start_adresse, const wxPoint & ref_pos,int layer); TRACK * Locate_Zone(TRACK * start_adresse, const wxPoint & ref_pos,int layer);
/* /*

View File

@ -122,5 +122,5 @@ public:
WinEDA_PcbFrame * m_Parent; WinEDA_PcbFrame * m_Parent;
}; };
#endif #endif // _ZONES_H_
// _ZONES_H_