From c1e3416a8fdcaa7c95626602acbfb689aedc867e Mon Sep 17 00:00:00 2001 From: dickelbeck Date: Wed, 8 Aug 2007 20:51:08 +0000 Subject: [PATCH] searching and beautifying --- change_log.txt | 14 + common/trigo.cpp | 159 +++ include/pcbstruct.h | 24 +- include/trigo.h | 3 +- pcbnew/class_board.cpp | 75 +- pcbnew/class_cotation.cpp | 650 ++++++---- pcbnew/class_cotation.h | 76 +- pcbnew/class_edge_mod.cpp | 67 + pcbnew/class_edge_mod.h | 10 +- pcbnew/class_mire.cpp | 259 ++-- pcbnew/class_mire.h | 45 +- pcbnew/class_module.h | 1 - pcbnew/class_track.cpp | 908 ++++++++------ pcbnew/class_track.h | 153 ++- pcbnew/classpcb.cpp | 56 + pcbnew/drc.cpp | 2489 ++++++++++++++++++++----------------- pcbnew/edit.cpp | 3 +- pcbnew/locate.cpp | 471 +------ pcbnew/protos.h | 18 - pcbnew/zones.h | 4 +- 20 files changed, 2975 insertions(+), 2510 deletions(-) diff --git a/change_log.txt b/change_log.txt index e467916a0b..a4735e32ce 100644 --- a/change_log.txt +++ b/change_log.txt @@ -5,6 +5,20 @@ Please add newer entries at the top, list the date and your name with email address. +2007-Aug-08 UPDATE Dick Hollenbeck +================================================================================ ++ 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 ================================================================================ + eeschema diff --git a/common/trigo.cpp b/common/trigo.cpp index a8f194596e..8ef468a978 100644 --- a/common/trigo.cpp +++ b/common/trigo.cpp @@ -9,6 +9,163 @@ #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 ) /***********************************/ @@ -217,3 +374,5 @@ void RotatePoint( double* pX, double* pY, int angle ) *pY = fpy; } } + + diff --git a/include/pcbstruct.h b/include/pcbstruct.h index 65e89fc9fc..bfbfcb57e7 100644 --- a/include/pcbstruct.h +++ b/include/pcbstruct.h @@ -235,7 +235,6 @@ public: #if defined(DEBUG) - /** * Function GetClass * returns the class name. @@ -264,7 +263,7 @@ public: * @param typeloc * @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 }; @@ -322,6 +321,27 @@ public: void UnLink( void ); 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 + }; diff --git a/include/trigo.h b/include/trigo.h index 73a650fb6b..c55ec32bce 100644 --- a/include/trigo.h +++ b/include/trigo.h @@ -7,7 +7,7 @@ #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 cx, int cy, 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 l'angle est souvent 0, -1800, ou +- 900 */ +bool DistanceTest( int seuil, int dx, int dy, int spot_cX, int spot_cY ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 96e5aca7e6..ddd45bd911 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -290,75 +290,64 @@ void BOARD::Show( int nestLevel, std::ostream& os ) // 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 { public: EDA_BaseStruct* found; int layer; - int typeloc; - PadOrModule( int alayer, int atypeloc ) : - found(0), - layer(alayer), - typeloc(atypeloc) {} + PadOrModule( int alayer ) : + found(0), // found is NULL + layer(alayer) + { + } 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 ) { - int mlayer = ((MODULE*)testItem)->m_Layer; - - if( typeloc & MATCH_LAYER ) - { - if( layer != mlayer ) - return SEARCH_CONTINUE; - } - - if( typeloc & VISIBLE_ONLY ) - { - if( !IsModuleLayerVisible(mlayer) ) - return SEARCH_CONTINUE; - } - - if( testItem->HitTest( *refPos ) ) + if( testItem->HitTest( refPos ) ) { found = testItem; 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 */ } + else if( testItem->m_StructType == TYPEMODULE ) + { + int mlayer = ((MODULE*)testItem)->m_Layer; + + // consider only visible modules + if( IsModuleLayerVisible( mlayer ) ) + { + 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; + + if( layer == mlayer ) + return SEARCH_QUIT; + } + } + } return SEARCH_CONTINUE; } - }; - PadOrModule inspector1( layer, MATCH_LAYER ); - PadOrModule inspector2( layer, VISIBLE_ONLY ); + PadOrModule inspector( layer ); + // search only for PADs first, then MODULES, and preferably a layer match static const KICAD_T scanTypes[] = { TYPEPAD, TYPEMODULE, EOT }; - // search the current layer first - if( SEARCH_QUIT == IterateForward( m_Modules, &inspector1, &refPos, scanTypes ) ) - return inspector1.found; - - // if not found, set layer to don't care and search again - if( SEARCH_QUIT == IterateForward( m_Modules, &inspector2, &refPos, scanTypes ) ) - return inspector2.found; + IterateForward( m_Modules, &inspector, &refPos, scanTypes ); - return NULL; + return inspector.found; } #endif diff --git a/pcbnew/class_cotation.cpp b/pcbnew/class_cotation.cpp index 0733dcb8be..6b8d4cf8cb 100644 --- a/pcbnew/class_cotation.cpp +++ b/pcbnew/class_cotation.cpp @@ -7,348 +7,476 @@ #include "common.h" #include "pcbnew.h" +#include "trigo.h" - - -COTATION::COTATION(EDA_BaseStruct * StructFather): - EDA_BaseStruct( StructFather, TYPECOTATION) +COTATION::COTATION( EDA_BaseStruct* StructFather ) : + EDA_BaseStruct( StructFather, TYPECOTATION ) { - m_Layer = DRAW_LAYER; - m_Width = 50; - m_Value = 0; - m_Shape = 0; - m_Unit = INCHES; - m_Text = new TEXTE_PCB(this); + m_Layer = DRAW_LAYER; + m_Width = 50; + m_Value = 0; + m_Shape = 0; + m_Unit = INCHES; + m_Text = new TEXTE_PCB( this ); } + /* Effacement memoire de la structure */ -COTATION::~COTATION(void) +COTATION::~COTATION( void ) { - delete m_Text; + delete m_Text; } + /* 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 ) { - /* Modification du chainage arriere */ - if( Pback ) - { - if( Pback->m_StructType != TYPEPCB) - { - Pback->Pnext = Pnext; - } + /* Modification du chainage arriere */ + if( Pback ) + { + if( Pback->m_StructType != TYPEPCB ) + { + Pback->Pnext = Pnext; + } + else /* Le chainage arriere pointe sur la structure "Pere" */ + { + ( (BOARD*) Pback )->m_Drawings = Pnext; + } + } - else /* Le chainage arriere pointe sur la structure "Pere" */ - { - ((BOARD*)Pback)->m_Drawings = Pnext; - } - } + /* Modification du chainage avant */ + if( Pnext ) + Pnext->Pback = Pback; - /* Modification du chainage avant */ - if( Pnext) Pnext->Pback = Pback; - - Pnext = Pback = NULL; + Pnext = Pback = NULL; } + /* Changement du texte de la cotation */ -void COTATION:: SetText(const wxString & NewText) +void COTATION:: SetText( const wxString& NewText ) { - m_Text->m_Text = NewText; + m_Text->m_Text = NewText; } /*************************************/ -void COTATION::Copy(COTATION * source) +void COTATION::Copy( COTATION* source ) /*************************************/ { - m_Value = source->m_Value; - m_Layer = source->m_Layer; - m_Width = source->m_Width; - m_Pos = source->m_Pos; - m_Shape = source->m_Shape; - m_Unit = source->m_Unit; - m_TimeStamp = GetTimeStamp(); - m_Text->Copy(source->m_Text); + m_Value = source->m_Value; + m_Layer = source->m_Layer; + m_Width = source->m_Width; + m_Pos = source->m_Pos; + m_Shape = source->m_Shape; + m_Unit = source->m_Unit; + m_TimeStamp = GetTimeStamp(); + m_Text->Copy( source->m_Text ); - Barre_ox = source->Barre_ox; Barre_oy = source->Barre_oy; - Barre_fx = source->Barre_fx; Barre_fy = source->Barre_fy; - TraitG_ox = source->TraitG_ox; TraitG_oy = source->TraitG_oy; - TraitG_fx = source->TraitG_fx; TraitG_fy = source->TraitG_fy; - TraitD_ox = source->TraitD_ox; TraitD_oy = source->TraitD_oy; - TraitD_fx = source->TraitD_fx; TraitD_fy = source->TraitD_fy; - FlecheD1_ox = source->FlecheD1_ox; FlecheD1_oy = source->FlecheD1_oy; - FlecheD1_fx = source->FlecheD1_fx; FlecheD1_fy = source->FlecheD1_fy; - FlecheD2_ox = source->FlecheD2_ox; FlecheD2_oy = source->FlecheD2_oy; - FlecheD2_fx = source->FlecheD2_fx; FlecheD2_fy = source->FlecheD2_fy; - FlecheG1_ox = source->FlecheG1_ox; FlecheG1_oy = source->FlecheG1_oy; - FlecheG1_fx = source->FlecheG1_fx; FlecheG1_fy = source->FlecheG1_fy; - FlecheG2_ox = source->FlecheG2_ox; FlecheG2_oy = source->FlecheG2_oy; - FlecheG2_fx = source->FlecheG2_fx; FlecheG2_fy = source->FlecheG2_fy; + Barre_ox = source->Barre_ox; Barre_oy = source->Barre_oy; + Barre_fx = source->Barre_fx; Barre_fy = source->Barre_fy; + TraitG_ox = source->TraitG_ox; TraitG_oy = source->TraitG_oy; + TraitG_fx = source->TraitG_fx; TraitG_fy = source->TraitG_fy; + TraitD_ox = source->TraitD_ox; TraitD_oy = source->TraitD_oy; + TraitD_fx = source->TraitD_fx; TraitD_fy = source->TraitD_fy; + FlecheD1_ox = source->FlecheD1_ox; FlecheD1_oy = source->FlecheD1_oy; + FlecheD1_fx = source->FlecheD1_fx; FlecheD1_fy = source->FlecheD1_fy; + FlecheD2_ox = source->FlecheD2_ox; FlecheD2_oy = source->FlecheD2_oy; + FlecheD2_fx = source->FlecheD2_fx; FlecheD2_fy = source->FlecheD2_fy; + FlecheG1_ox = source->FlecheG1_ox; FlecheG1_oy = source->FlecheG1_oy; + FlecheG1_fx = source->FlecheG1_fx; FlecheG1_fy = source->FlecheG1_fy; + FlecheG2_ox = source->FlecheG2_ox; FlecheG2_oy = source->FlecheG2_oy; + FlecheG2_fx = source->FlecheG2_fx; FlecheG2_fy = source->FlecheG2_fy; } /***************************************************************/ -bool COTATION::ReadCotationDescr(FILE * File, int * LineNum) +bool COTATION::ReadCotationDescr( FILE* File, int* LineNum ) /***************************************************************/ { -char Line[2048], Text[2048]; + char Line[2048], Text[2048]; - while( GetLine(File, Line, LineNum ) != NULL ) - { - if(strnicmp(Line,"$EndCOTATION",4) == 0) return TRUE; + while( GetLine( File, Line, LineNum ) != NULL ) + { + if( strnicmp( Line, "$EndCOTATION", 4 ) == 0 ) + return TRUE; - if(Line[0] == 'V') - { - sscanf( Line+2," %d",&m_Value); - continue; - } + if( Line[0] == 'V' ) + { + sscanf( Line + 2, " %d", &m_Value ); + continue; + } - if(Line[0] == 'G') - { - sscanf( Line+2," %d %d %lX",&m_Shape, &m_Layer, &m_TimeStamp); + if( Line[0] == 'G' ) + { + sscanf( Line + 2, " %d %d %lX", &m_Shape, &m_Layer, &m_TimeStamp ); - /* Mise a jour des param .layer des sous structures */ - if ( m_Layer < FIRST_NO_COPPER_LAYER ) - m_Layer = FIRST_NO_COPPER_LAYER; - if ( m_Layer > LAST_NO_COPPER_LAYER ) - m_Layer = LAST_NO_COPPER_LAYER; + /* Mise a jour des param .layer des sous structures */ + if( m_Layer < FIRST_NO_COPPER_LAYER ) + m_Layer = FIRST_NO_COPPER_LAYER; + if( m_Layer > LAST_NO_COPPER_LAYER ) + m_Layer = LAST_NO_COPPER_LAYER; - m_Text->m_Layer = m_Layer; - continue; - } + m_Text->m_Layer = m_Layer; + continue; + } - if(Line[0] == 'T') - { - ReadDelimitedText(Text, Line+2, sizeof(Text) ); - m_Text->m_Text = CONV_FROM_UTF8(Text); - continue; - } + if( Line[0] == 'T' ) + { + ReadDelimitedText( Text, Line + 2, sizeof(Text) ); + m_Text->m_Text = CONV_FROM_UTF8( Text ); + continue; + } - if(Line[0] == 'P') - { - sscanf( Line+2," %d %d %d %d %d %d %d", - &m_Text->m_Pos.x, &m_Text->m_Pos.y, - &m_Text->m_Size.x, &m_Text->m_Size.y, - &m_Text->m_Width,&m_Text->m_Orient, - &m_Text->m_Miroir); + if( Line[0] == 'P' ) + { + sscanf( Line + 2, " %d %d %d %d %d %d %d", + &m_Text->m_Pos.x, &m_Text->m_Pos.y, + &m_Text->m_Size.x, &m_Text->m_Size.y, + &m_Text->m_Width, &m_Text->m_Orient, + &m_Text->m_Miroir ); - m_Pos = m_Text->m_Pos; - continue; - } + m_Pos = m_Text->m_Pos; + continue; + } - if( Line[0] == 'S') - { - switch( Line[1] ) - { - int Dummy; - case 'b' : - sscanf( Line+2," %d %d %d %d %d %d", - &Dummy, - &Barre_ox, &Barre_oy, - &Barre_fx, &Barre_fy, - &m_Width ); - break; + if( Line[0] == 'S' ) + { + switch( Line[1] ) + { + int Dummy; - case 'd': - sscanf( Line+2," %d %d %d %d %d %d", - &Dummy, - &TraitD_ox, &TraitD_oy, - &TraitD_fx, &TraitD_fy, - &Dummy ); - break; + case 'b': + sscanf( Line + 2, " %d %d %d %d %d %d", + &Dummy, + &Barre_ox, &Barre_oy, + &Barre_fx, &Barre_fy, + &m_Width ); + break; - case 'g': - sscanf( Line+2," %d %d %d %d %d %d", - &Dummy, - &TraitG_ox, &TraitG_oy, - &TraitG_fx, &TraitG_fy, - &Dummy ); - break; + case 'd': + sscanf( Line + 2, " %d %d %d %d %d %d", + &Dummy, + &TraitD_ox, &TraitD_oy, + &TraitD_fx, &TraitD_fy, + &Dummy ); + break; - case '1': - sscanf( Line+2," %d %d %d %d %d %d", - &Dummy, - &FlecheD1_ox, &FlecheD1_oy, - &FlecheD1_fx, &FlecheD1_fy, - &Dummy ); - break; + case 'g': + sscanf( Line + 2, " %d %d %d %d %d %d", + &Dummy, + &TraitG_ox, &TraitG_oy, + &TraitG_fx, &TraitG_fy, + &Dummy ); + break; - case '2': - sscanf( Line+2," %d %d %d %d %d %d", - &Dummy, - &FlecheD2_ox, &FlecheD2_oy, - &FlecheD2_fx, &FlecheD2_fy, - &Dummy ); - break; + case '1': + sscanf( Line + 2, " %d %d %d %d %d %d", + &Dummy, + &FlecheD1_ox, &FlecheD1_oy, + &FlecheD1_fx, &FlecheD1_fy, + &Dummy ); + break; - case '3': - sscanf( Line+2," %d %d %d %d %d %d\n", - &Dummy, - &FlecheG1_ox, &FlecheG1_oy, - &FlecheG1_fx, &FlecheG1_fy, - &Dummy); - break; + case '2': + sscanf( Line + 2, " %d %d %d %d %d %d", + &Dummy, + &FlecheD2_ox, &FlecheD2_oy, + &FlecheD2_fx, &FlecheD2_fy, + &Dummy ); + break; - case '4': - sscanf( Line+2," %d %d %d %d %d %d", - &Dummy, - &FlecheG2_ox, &FlecheG2_oy, - &FlecheG2_fx, &FlecheG2_fy, - &Dummy ); - break; - } + case '3': + sscanf( Line + 2, " %d %d %d %d %d %d\n", + &Dummy, + &FlecheG1_ox, &FlecheG1_oy, + &FlecheG1_fx, &FlecheG1_fy, + &Dummy ); + break; - continue; - } - } - return FALSE; + case '4': + sscanf( Line + 2, " %d %d %d %d %d %d", + &Dummy, + &FlecheG2_ox, &FlecheG2_oy, + &FlecheG2_fx, &FlecheG2_fy, + &Dummy ); + break; + } + + continue; + } + } + + return FALSE; } /**************************************************/ -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" ); - fprintf( File,"Ge %d %d %lX\n",m_Shape, - m_Layer, m_TimeStamp); + fprintf( File, "Ge %d %d %lX\n", m_Shape, + m_Layer, m_TimeStamp ); - fprintf( File,"Va %d\n",m_Value); + fprintf( File, "Va %d\n", m_Value ); - if( ! m_Text->m_Text.IsEmpty() ) - fprintf( File,"Te \"%s\"\n",CONV_TO_UTF8(m_Text->m_Text)); - else fprintf( File,"Te \"?\"\n"); + if( !m_Text->m_Text.IsEmpty() ) + fprintf( File, "Te \"%s\"\n", CONV_TO_UTF8( m_Text->m_Text ) ); + else + fprintf( File, "Te \"?\"\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_Size.x, m_Text->m_Size.y, - m_Text->m_Width,m_Text->m_Orient, - m_Text->m_Miroir); + fprintf( File, "Po %d %d %d %d %d %d %d\n", + m_Text->m_Pos.x, m_Text->m_Pos.y, + m_Text->m_Size.x, m_Text->m_Size.y, + m_Text->m_Width, m_Text->m_Orient, + m_Text->m_Miroir ); - fprintf( File,"Sb %d %d %d %d %d %d\n",S_SEGMENT, - Barre_ox, Barre_oy, - Barre_fx, Barre_fy, m_Width ); + fprintf( File, "Sb %d %d %d %d %d %d\n", S_SEGMENT, + Barre_ox, Barre_oy, + Barre_fx, Barre_fy, m_Width ); - fprintf( File,"Sd %d %d %d %d %d %d\n",S_SEGMENT, - TraitD_ox, TraitD_oy, - TraitD_fx, TraitD_fy, m_Width ); + fprintf( File, "Sd %d %d %d %d %d %d\n", S_SEGMENT, + TraitD_ox, TraitD_oy, + TraitD_fx, TraitD_fy, m_Width ); - fprintf( File,"Sg %d %d %d %d %d %d\n",S_SEGMENT, - TraitG_ox, TraitG_oy, - TraitG_fx, TraitG_fy, m_Width ); + fprintf( File, "Sg %d %d %d %d %d %d\n", S_SEGMENT, + TraitG_ox, TraitG_oy, + TraitG_fx, TraitG_fy, m_Width ); - fprintf( File,"S1 %d %d %d %d %d %d\n",S_SEGMENT, - FlecheD1_ox, FlecheD1_oy, - FlecheD1_fx, FlecheD1_fy, m_Width ); + fprintf( File, "S1 %d %d %d %d %d %d\n", S_SEGMENT, + FlecheD1_ox, FlecheD1_oy, + FlecheD1_fx, FlecheD1_fy, m_Width ); - fprintf( File,"S2 %d %d %d %d %d %d\n",S_SEGMENT, - FlecheD2_ox, FlecheD2_oy, - FlecheD2_fx, FlecheD2_fy, m_Width ); + fprintf( File, "S2 %d %d %d %d %d %d\n", S_SEGMENT, + FlecheD2_ox, FlecheD2_oy, + FlecheD2_fx, FlecheD2_fy, m_Width ); - fprintf( File,"S3 %d %d %d %d %d %d\n",S_SEGMENT, - FlecheG1_ox, FlecheG1_oy, - FlecheG1_fx, FlecheG1_fy, m_Width ); + fprintf( File, "S3 %d %d %d %d %d %d\n", S_SEGMENT, + FlecheG1_ox, FlecheG1_oy, + FlecheG1_fx, FlecheG1_fy, m_Width ); - fprintf( File,"S4 %d %d %d %d %d %d\n",S_SEGMENT, - FlecheG2_ox, FlecheG2_oy, - FlecheG2_fx, FlecheG2_fy, m_Width ); + fprintf( File, "S4 %d %d %d %d %d %d\n", S_SEGMENT, + FlecheG2_ox, FlecheG2_oy, + FlecheG2_fx, FlecheG2_fy, m_Width ); - fprintf( File, "$EndCOTATION\n"); + fprintf( File, "$EndCOTATION\n" ); - return(1); + return 1; } - - /************************************************************************/ -void COTATION::Draw(WinEDA_DrawPanel * panel , wxDC * DC, - const wxPoint & offset, int mode_color) +void COTATION::Draw( WinEDA_DrawPanel* panel, wxDC* DC, + const wxPoint& offset, int mode_color ) /************************************************************************/ + /* impression de 1 cotation : serie de n segments + 1 texte -*/ + */ { -int ox, oy, typeaff, width, gcolor; -int zoom = panel->GetScreen()->GetZoom(); + int ox, oy, typeaff, width, gcolor; + int zoom = panel->GetScreen()->GetZoom(); - ox = offset.x; - oy = offset.y; + ox = offset.x; + oy = offset.y; - m_Text->Draw(panel, DC, offset, mode_color ); + m_Text->Draw( panel, DC, offset, mode_color ); - gcolor = g_DesignSettings.m_LayerColor[m_Layer]; - if( (gcolor & ITEM_NOT_SHOW) != 0 ) return ; + gcolor = g_DesignSettings.m_LayerColor[m_Layer]; + if( (gcolor & ITEM_NOT_SHOW) != 0 ) + return; - GRSetDrawMode(DC, mode_color); - typeaff = DisplayOpt.DisplayDrawItems; - width = m_Width; - if( width/zoom < 2 ) typeaff = FILAIRE; + GRSetDrawMode( DC, mode_color ); + typeaff = DisplayOpt.DisplayDrawItems; + + width = m_Width; + if( width / zoom < 2 ) + typeaff = FILAIRE; - switch( typeaff ) - { - case FILAIRE: - width = 0; - case FILLED: - GRLine(&panel->m_ClipBox, DC, - Barre_ox - ox, Barre_oy - oy, - Barre_fx - ox, Barre_fy- oy, width, gcolor); - GRLine(&panel->m_ClipBox, DC, - TraitG_ox - ox, TraitG_oy - oy, - TraitG_fx - ox, TraitG_fy- oy, width, gcolor); - GRLine(&panel->m_ClipBox, DC, - TraitD_ox - ox, TraitD_oy - oy, - TraitD_fx - ox, TraitD_fy- oy, width, gcolor); - GRLine(&panel->m_ClipBox, DC, - FlecheD1_ox - ox, FlecheD1_oy - oy, - FlecheD1_fx - ox, FlecheD1_fy- oy, width, gcolor); - GRLine(&panel->m_ClipBox, DC, - FlecheD2_ox - ox, FlecheD2_oy - oy, - FlecheD2_fx - ox, FlecheD2_fy- oy, width, gcolor); - GRLine(&panel->m_ClipBox, DC, - FlecheG1_ox - ox, FlecheG1_oy - oy, - FlecheG1_fx - ox, FlecheG1_fy- oy, width, gcolor); - GRLine(&panel->m_ClipBox, DC, - FlecheG2_ox - ox, FlecheG2_oy - oy, - FlecheG2_fx - ox, FlecheG2_fy- oy, width, gcolor); - break; + switch( typeaff ) + { + case FILAIRE: + width = 0; - case SKETCH: - GRCSegm(&panel->m_ClipBox, DC, - Barre_ox - ox, Barre_oy - oy, - Barre_fx - ox, Barre_fy- oy, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, - TraitG_ox - ox, TraitG_oy - oy, - TraitG_fx - ox, TraitG_fy- oy, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, - TraitD_ox - ox, TraitD_oy - oy, - TraitD_fx - ox, TraitD_fy- oy, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, - FlecheD1_ox - ox, FlecheD1_oy - oy, - FlecheD1_fx - ox, FlecheD1_fy- oy, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, - FlecheD2_ox - ox, FlecheD2_oy - oy, - FlecheD2_fx - ox, FlecheD2_fy- oy, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, - FlecheG1_ox - ox, FlecheG1_oy - oy, - FlecheG1_fx - ox, FlecheG1_fy- oy, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, - FlecheG2_ox - ox, FlecheG2_oy - oy, - FlecheG2_fx - ox, FlecheG2_fy - oy, - width, gcolor); - break; - } + case FILLED: + GRLine( &panel->m_ClipBox, DC, + Barre_ox - ox, Barre_oy - oy, + Barre_fx - ox, Barre_fy - oy, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, + TraitG_ox - ox, TraitG_oy - oy, + TraitG_fx - ox, TraitG_fy - oy, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, + TraitD_ox - ox, TraitD_oy - oy, + TraitD_fx - ox, TraitD_fy - oy, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, + FlecheD1_ox - ox, FlecheD1_oy - oy, + FlecheD1_fx - ox, FlecheD1_fy - oy, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, + FlecheD2_ox - ox, FlecheD2_oy - oy, + FlecheD2_fx - ox, FlecheD2_fy - oy, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, + FlecheG1_ox - ox, FlecheG1_oy - oy, + FlecheG1_fx - ox, FlecheG1_fy - oy, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, + FlecheG2_ox - ox, FlecheG2_oy - oy, + FlecheG2_fx - ox, FlecheG2_fy - oy, width, gcolor ); + break; + + case SKETCH: + GRCSegm( &panel->m_ClipBox, DC, + Barre_ox - ox, Barre_oy - oy, + Barre_fx - ox, Barre_fy - oy, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, + TraitG_ox - ox, TraitG_oy - oy, + TraitG_fx - ox, TraitG_fy - oy, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, + TraitD_ox - ox, TraitD_oy - oy, + TraitD_fx - ox, TraitD_fy - oy, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, + FlecheD1_ox - ox, FlecheD1_oy - oy, + FlecheD1_fx - ox, FlecheD1_fy - oy, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, + FlecheD2_ox - ox, FlecheD2_oy - oy, + FlecheD2_fx - ox, FlecheD2_fy - oy, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, + FlecheG1_ox - ox, FlecheG1_oy - oy, + FlecheG1_fx - ox, FlecheG1_fy - oy, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, + FlecheG2_ox - ox, FlecheG2_oy - oy, + FlecheG2_fx - ox, FlecheG2_fy - oy, + width, gcolor ); + break; + } } +/** + * 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(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; +} + diff --git a/pcbnew/class_cotation.h b/pcbnew/class_cotation.h index 9148bcd9c9..7da75cd619 100644 --- a/pcbnew/class_cotation.h +++ b/pcbnew/class_cotation.h @@ -6,42 +6,62 @@ #include "base_struct.h" -class COTATION: public EDA_BaseStruct +class COTATION : public EDA_BaseStruct { - public: - int m_Layer; // 0.. 32 ( NON bit a bit) - int m_Width; - wxPoint m_Pos; - int m_Shape; - int m_Unit; /* 0 = inches, 1 = mm */ - int m_Value; /* valeur en unites PCB de la cote */ +public: + int m_Layer; // 0.. 32 ( NON bit a bit) + int m_Width; + wxPoint m_Pos; + int m_Shape; + int m_Unit; /* 0 = inches, 1 = mm */ + int m_Value; /* valeur en unites PCB de la cote */ - TEXTE_PCB * m_Text; /* pour affichage du texte */ - int Barre_ox, Barre_oy, Barre_fx, Barre_fy; - int TraitG_ox, TraitG_oy, TraitG_fx, TraitG_fy; - int TraitD_ox, TraitD_oy, TraitD_fx, TraitD_fy; - int FlecheD1_ox, FlecheD1_oy, FlecheD1_fx, FlecheD1_fy; - int FlecheD2_ox, FlecheD2_oy, FlecheD2_fx, FlecheD2_fy; - int FlecheG1_ox, FlecheG1_oy, FlecheG1_fx, FlecheG1_fy; - int FlecheG2_ox, FlecheG2_oy, FlecheG2_fx, FlecheG2_fy; + TEXTE_PCB* m_Text; /* pour affichage du texte */ + int Barre_ox, Barre_oy, Barre_fx, Barre_fy; + int TraitG_ox, TraitG_oy, TraitG_fx, TraitG_fy; + int TraitD_ox, TraitD_oy, TraitD_fx, TraitD_fy; + int FlecheD1_ox, FlecheD1_oy, FlecheD1_fx, FlecheD1_fy; + int FlecheD2_ox, FlecheD2_oy, FlecheD2_fx, FlecheD2_fy; + int FlecheG1_ox, FlecheG1_oy, FlecheG1_fx, FlecheG1_fy; + int FlecheG2_ox, FlecheG2_oy, FlecheG2_fx, FlecheG2_fy; - public: - COTATION(EDA_BaseStruct * StructFather); - ~COTATION(void); +public: + COTATION( EDA_BaseStruct* StructFather ); + ~COTATION( void ); - bool ReadCotationDescr(FILE * File, int * LineNum); - bool WriteCotationDescr(FILE * File); + bool ReadCotationDescr( FILE* File, int* LineNum ); + bool WriteCotationDescr( FILE* File ); - /* supprime du chainage la structure Struct */ - void UnLink( void ); + /* supprime du chainage la structure Struct */ + void UnLink( void ); - /* Modification du texte de la cotation */ - void SetText(const wxString & NewText); + /* Modification du texte de la cotation */ + void SetText( const wxString& NewText ); - void Copy(COTATION * source); + void Copy( COTATION* source ); - 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 diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp index cf45cb25f3..0ab755eb33 100644 --- a/pcbnew/class_edge_mod.cpp +++ b/pcbnew/class_edge_mod.cpp @@ -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) /** * Function Show diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 843be47d65..0b9b9b9f74 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -41,6 +41,14 @@ public: void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int draw_mode ); 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) /** @@ -50,7 +58,7 @@ public: */ virtual wxString GetClass() const { - return wxT( "GRAPHIC" ); + return wxT( "MGRAPHIC" ); // return wxT( "EDGE" ); ? } diff --git a/pcbnew/class_mire.cpp b/pcbnew/class_mire.cpp index 7d2325262b..e4b81732fa 100644 --- a/pcbnew/class_mire.cpp +++ b/pcbnew/class_mire.cpp @@ -9,15 +9,15 @@ #include "pcbnew.h" - -MIREPCB::MIREPCB(EDA_BaseStruct * StructFather): - EDA_BaseStruct( StructFather, TYPEMIRE) +MIREPCB::MIREPCB( EDA_BaseStruct* StructFather ) : + EDA_BaseStruct( StructFather, TYPEMIRE ) { - m_Shape = 0; - m_Size = 5000; + m_Shape = 0; + m_Size = 5000; } -MIREPCB::~MIREPCB(void) + +MIREPCB::~MIREPCB( void ) { } @@ -25,161 +25,186 @@ MIREPCB::~MIREPCB(void) /***************************/ void MIREPCB::UnLink( void ) /***************************/ + /* 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 */ - if( Pback ) - { - if( Pback->m_StructType != TYPEPCB) - { - Pback->Pnext = Pnext; - } + /* Modification du chainage arriere */ + if( Pback ) + { + if( Pback->m_StructType != TYPEPCB ) + { + Pback->Pnext = Pnext; + } + else /* Le chainage arriere pointe sur la structure "Pere" */ + { + ( (BOARD*) Pback )->m_Drawings = Pnext; + } + } - else /* Le chainage arriere pointe sur la structure "Pere" */ - { - ((BOARD*)Pback)->m_Drawings = Pnext; - } - } + /* Modification du chainage avant */ + if( Pnext ) + Pnext->Pback = Pback; - /* Modification du chainage avant */ - if( Pnext) Pnext->Pback = Pback; - - Pnext = Pback = NULL; + Pnext = Pback = NULL; } /**********************************/ -void MIREPCB::Copy(MIREPCB * source) +void MIREPCB::Copy( MIREPCB* source ) /**********************************/ { - m_Layer = source->m_Layer; - m_Width = source->m_Width; - m_Pos = source->m_Pos; - m_Shape = source->m_Shape; - m_Size = source->m_Size; - m_TimeStamp = GetTimeStamp(); + m_Layer = source->m_Layer; + m_Width = source->m_Width; + m_Pos = source->m_Pos; + m_Shape = source->m_Shape; + m_Size = source->m_Size; + m_TimeStamp = GetTimeStamp(); } /**************************************************************/ -bool MIREPCB::ReadMirePcbDescr(FILE * File, int * LineNum) +bool MIREPCB::ReadMirePcbDescr( FILE* File, int* LineNum ) /**************************************************************/ + /* Lecture de la description de 1 segment type Drawing PCB -*/ + */ { -char Line[256]; + char Line[256]; - while( GetLine(File, Line, LineNum ) != NULL ) - { - if(strnicmp(Line,"$End",4 ) == 0 ) return TRUE; /* fin de liste */ - if(Line[0] == 'P') - { - sscanf( Line+2," %X %d %d %d %d %d %lX", - &m_Shape, &m_Layer, - &m_Pos.x, &m_Pos.y, - &m_Size, &m_Width, &m_TimeStamp ); - if ( m_Layer < FIRST_NO_COPPER_LAYER ) - m_Layer = FIRST_NO_COPPER_LAYER; - if ( m_Layer > LAST_NO_COPPER_LAYER ) - m_Layer = LAST_NO_COPPER_LAYER; + while( GetLine( File, Line, LineNum ) != NULL ) + { + if( strnicmp( Line, "$End", 4 ) == 0 ) + return TRUE; /* fin de liste */ + if( Line[0] == 'P' ) + { + sscanf( Line + 2, " %X %d %d %d %d %d %lX", + &m_Shape, &m_Layer, + &m_Pos.x, &m_Pos.y, + &m_Size, &m_Width, &m_TimeStamp ); + if( m_Layer < FIRST_NO_COPPER_LAYER ) + m_Layer = FIRST_NO_COPPER_LAYER; + if( m_Layer > LAST_NO_COPPER_LAYER ) + m_Layer = LAST_NO_COPPER_LAYER; + } + } - } - } - return FALSE; + return FALSE; } /************************************************/ -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,"Po %X %d %d %d %d %d %8.8lX\n", - m_Shape, m_Layer, - m_Pos.x, m_Pos.y, - m_Size, m_Width, m_TimeStamp ); - fprintf( File, "$EndMIREPCB\n"); - return TRUE; + fprintf( File, "$MIREPCB\n" ); + fprintf( File, "Po %X %d %d %d %d %d %8.8lX\n", + m_Shape, m_Layer, + m_Pos.x, m_Pos.y, + m_Size, m_Width, m_TimeStamp ); + fprintf( File, "$EndMIREPCB\n" ); + return TRUE; } /**********************************************************/ -void MIREPCB::Draw(WinEDA_DrawPanel * panel, wxDC * DC, - const wxPoint & offset, int mode_color) +void MIREPCB::Draw( WinEDA_DrawPanel* panel, wxDC* DC, + const wxPoint& offset, int mode_color ) /**********************************************************/ + /* Affichage de 1 mire : 2 segments + 1 cercle - le cercle a pour rayon le demi rayon de la mire - les 2 traits ont pour longueur le diametre 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 + */ { -int rayon, ox, oy, gcolor, width; -int dx1,dx2, dy1, dy2; -int typeaff; -int zoom; + int rayon, ox, oy, gcolor, width; + int dx1, dx2, dy1, dy2; + int typeaff; + int zoom; - ox = m_Pos.x + offset.x; - oy = m_Pos.y + offset.y; + ox = m_Pos.x + offset.x; + oy = m_Pos.y + offset.y; - gcolor = g_DesignSettings.m_LayerColor[m_Layer]; - if ( (gcolor & ITEM_NOT_SHOW) != 0 ) return; + gcolor = g_DesignSettings.m_LayerColor[m_Layer]; + if( (gcolor & ITEM_NOT_SHOW) != 0 ) + return; - zoom = panel->GetZoom(); + zoom = panel->GetZoom(); - GRSetDrawMode(DC, mode_color); - typeaff = DisplayOpt.DisplayDrawItems; - width = m_Width; - if( width/zoom < 2 ) typeaff = FILAIRE; + GRSetDrawMode( DC, mode_color ); + typeaff = DisplayOpt.DisplayDrawItems; + width = m_Width; + if( width / zoom < 2 ) + typeaff = FILAIRE; - /* Trace du cercle: */ - rayon = m_Size / 4; - switch( typeaff ) - { - case FILAIRE: - width = 0; - case FILLED: - GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon, width, gcolor); - break; + /* Trace du cercle: */ + rayon = m_Size / 4; - case SKETCH: - GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon + (width/2), gcolor) ; - GRCircle(&panel->m_ClipBox, DC, ox, oy, rayon - (width/2), gcolor) ; - break; - } + switch( typeaff ) + { + case FILAIRE: + width = 0; + + case FILLED: + GRCircle( &panel->m_ClipBox, DC, ox, oy, rayon, width, gcolor ); + break; + + case SKETCH: + GRCircle( &panel->m_ClipBox, DC, ox, oy, rayon + (width / 2), gcolor ); + GRCircle( &panel->m_ClipBox, DC, ox, oy, rayon - (width / 2), gcolor ); + break; + } - /* Trace des 2 traits */ - rayon = m_Size/2; - dx1 = rayon, dy1 = 0; - dx2 = 0, dy2 = rayon; + /* Trace des 2 traits */ + rayon = m_Size / 2; + dx1 = rayon, dy1 = 0; + dx2 = 0, dy2 = rayon; - if( m_Shape) /* Forme X */ - { - dx1 = dy1 = (rayon * 7)/5; - dx2 = dx1; dy2 = -dy1; - } + if( m_Shape ) /* Forme X */ + { + dx1 = dy1 = (rayon * 7) / 5; + dx2 = dx1; dy2 = -dy1; + } - switch( typeaff ) - { - case FILAIRE: - case FILLED: - GRLine(&panel->m_ClipBox, DC, ox - dx1, oy - dy1, - ox + dx1, oy + dy1, width, gcolor); - GRLine(&panel->m_ClipBox, DC, ox - dx2, oy - dy2, - ox + dx2, oy + dy2, width, gcolor); - break; + switch( typeaff ) + { + case FILAIRE: + case FILLED: + GRLine( &panel->m_ClipBox, DC, ox - dx1, oy - dy1, + ox + dx1, oy + dy1, width, gcolor ); + GRLine( &panel->m_ClipBox, DC, ox - dx2, oy - dy2, + ox + dx2, oy + dy2, width, gcolor ); + break; - case SKETCH: - GRCSegm(&panel->m_ClipBox, DC, ox - dx1, oy - dy1, - ox + dx1, oy + dy1, - width, gcolor); - GRCSegm(&panel->m_ClipBox, DC, ox - dx2, oy - dy2, - ox + dx2, oy + dy2, - width, gcolor); - break; - } + case SKETCH: + GRCSegm( &panel->m_ClipBox, DC, ox - dx1, oy - dy1, + ox + dx1, oy + dy1, + width, gcolor ); + GRCSegm( &panel->m_ClipBox, DC, ox - dx2, oy - dy2, + ox + dx2, oy + dy2, + width, gcolor ); + break; + } +} + + +/** + * 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; } diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index 4c3c551c4c..ee1f5279be 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -7,31 +7,38 @@ #include "base_struct.h" -class MIREPCB: public EDA_BaseStruct - { - public: - int m_Layer; // 0.. 32 ( NON bit a bit) - int m_Width; - wxPoint m_Pos; - int m_Shape; // bit 0 : 0 = forme +, 1 = forme X - int m_Size; +class MIREPCB : public EDA_BaseStruct +{ +public: + int m_Layer; // 0.. 32 ( NON bit a bit) + int m_Width; + wxPoint m_Pos; + int m_Shape; // bit 0 : 0 = forme +, 1 = forme X + int m_Size; - public: - MIREPCB(EDA_BaseStruct * StructFather); - ~MIREPCB(void); +public: + MIREPCB( EDA_BaseStruct* StructFather ); + ~MIREPCB( void ); - bool WriteMirePcbDescr(FILE * File); - bool ReadMirePcbDescr(FILE * File, int * LineNum); + bool WriteMirePcbDescr( FILE* File ); + bool ReadMirePcbDescr( FILE* File, int* LineNum ); - /* supprime du chainage la structure Struct */ - void UnLink( void ); + /* supprime du chainage la structure Struct */ + void UnLink( void ); - void Copy(MIREPCB * source); + void Copy( MIREPCB* source ); - 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 diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 783bc59eb8..ffff2d6dc5 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -144,7 +144,6 @@ public: #if defined(DEBUG) - /** * Function GetClass * returns the class name. diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 6a228e8f88..93bbc3db70 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -12,551 +12,665 @@ #include "cvpcb.h" #endif +#include "trigo.h" - /**************************************/ - /* Classes pour Pistes, Vias et Zones */ - /**************************************/ +/**************************************/ +/* Classes pour Pistes, Vias et Zones */ +/**************************************/ /* Constructeur des classes type pistes, vias et zones */ -TRACK::TRACK(EDA_BaseStruct * StructFather, DrawStructureType idtype): - EDA_BaseLineStruct( StructFather, idtype) +TRACK::TRACK( EDA_BaseStruct* StructFather, DrawStructureType idtype ) : + EDA_BaseLineStruct( StructFather, idtype ) { - m_Shape = S_SEGMENT; - start = end = NULL; - m_NetCode = 0; - m_Sous_Netcode = 0; - m_Drill = -1; - m_Param = 0; + m_Shape = S_SEGMENT; + start = end = NULL; + m_NetCode = 0; + m_Sous_Netcode = 0; + m_Drill = -1; + m_Param = 0; } -SEGZONE::SEGZONE(EDA_BaseStruct * StructFather): - TRACK( StructFather, TYPEZONE) + +SEGZONE::SEGZONE( EDA_BaseStruct* StructFather ) : + TRACK( StructFather, TYPEZONE ) { } -SEGVIA::SEGVIA(EDA_BaseStruct * StructFather): - TRACK( StructFather, TYPEVIA) + +SEGVIA::SEGVIA( EDA_BaseStruct* StructFather ) : + TRACK( StructFather, TYPEVIA ) { } + + /* Copy constructor */ -TRACK::TRACK(const TRACK & Source): - EDA_BaseLineStruct( Source.m_Parent, (DrawStructureType)Source.m_StructType) +TRACK::TRACK( const TRACK& Source ) : + EDA_BaseLineStruct( Source.m_Parent, (DrawStructureType)Source.m_StructType ) { - m_StructType = Source.m_StructType; - m_Shape = Source.m_Shape; - m_NetCode = Source.m_NetCode; - m_Flags = Source.m_Flags; - m_TimeStamp = Source.m_TimeStamp; - SetStatus(Source.ReturnStatus() ); - m_Layer = Source.m_Layer; - m_Start = Source.m_Start; - m_End = Source.m_End; - m_Width = Source.m_Width; - m_Drill = Source.m_Drill; - m_Sous_Netcode = Source.m_Sous_Netcode; - m_Param = Source.m_Param; - + m_StructType = Source.m_StructType; + m_Shape = Source.m_Shape; + m_NetCode = Source.m_NetCode; + m_Flags = Source.m_Flags; + m_TimeStamp = Source.m_TimeStamp; + SetStatus( Source.ReturnStatus() ); + m_Layer = Source.m_Layer; + m_Start = Source.m_Start; + m_End = Source.m_End; + m_Width = Source.m_Width; + m_Drill = Source.m_Drill; + m_Sous_Netcode = Source.m_Sous_Netcode; + 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 ) ) - return TRUE; - else return FALSE; + if( ( m_StructType != TYPEVIA ) && ( m_Start == m_End ) ) + return TRUE; + else + return FALSE; } + /*************************************************************/ -int TRACK::IsPointOnEnds(const wxPoint & point, int min_dist) +int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) /*************************************************************/ + /* Return: - STARTPOINT if point if near (dist = min_dist) star point - ENDPOINT if point if near (dist = min_dist) end point - STARTPOINT|ENDPOINT if point if near (dist = min_dist) both ends - 0 if no - if min_dist < 0: min_dist = track_width/2 -*/ + * STARTPOINT if point if near (dist = min_dist) star point + * ENDPOINT if point if near (dist = min_dist) end point + * STARTPOINT|ENDPOINT if point if near (dist = min_dist) both ends + * 0 if no + * if min_dist < 0: min_dist = track_width/2 + */ { -int dx, dy; -int result = 0; + int dx, dy; + 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; - dy = m_Start.y - point.y; - if ( min_dist == 0 ) - { - if( (dx == 0) && (dy == 0 ) ) result |= STARTPOINT; - } - else - { - double dist = ((double)dx *dx) + ((double)dy*dy); - dist = sqrt(dist); - if ( min_dist >= (int) dist ) result |= STARTPOINT; - } + dx = m_Start.x - point.x; + dy = m_Start.y - point.y; + if( min_dist == 0 ) + { + if( (dx == 0) && (dy == 0 ) ) + result |= STARTPOINT; + } + else + { + double dist = ( (double) dx * dx ) + ( (double) dy * dy ); + dist = sqrt( dist ); + if( min_dist >= (int) dist ) + result |= STARTPOINT; + } - dx = m_End.x - point.x; - dy = m_End.y - point.y; - if ( min_dist == 0 ) - { - if( (dx == 0) && (dy == 0 ) ) result |= ENDPOINT; - } - else - { - double dist = ((double)dx *dx) + ((double)dy*dy); - dist = sqrt(dist); - if ( min_dist >= (int) dist ) result |= ENDPOINT; - } + dx = m_End.x - point.x; + dy = m_End.y - point.y; + if( min_dist == 0 ) + { + if( (dx == 0) && (dy == 0 ) ) + result |= ENDPOINT; + } + else + { + double dist = ( (double) dx * dx ) + ( (double) dy * dy ); + dist = sqrt( dist ); + 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 -*/ + */ { -int via_type = Shape(); + int via_type = Shape(); - if( via_type == VIA_NORMALE ) - { - if ( layer_number <= LAYER_CMP_N ) return TRUE; - else return FALSE; - } + if( via_type == VIA_NORMALE ) + { + if( layer_number <= LAYER_CMP_N ) + return TRUE; + else + return FALSE; + } - // VIA_BORGNE ou VIA_ENTERREE: + // VIA_BORGNE ou VIA_ENTERREE: -int bottom_layer, top_layer; - ReturnLayerPair(& top_layer, & bottom_layer); - if ( (bottom_layer <= layer_number) && (top_layer >= layer_number) ) - return TRUE; - else return FALSE; + int bottom_layer, top_layer; + ReturnLayerPair( &top_layer, &bottom_layer ); + if( (bottom_layer <= layer_number) && (top_layer >= layer_number) ) + return TRUE; + else + return FALSE; } /***********************************/ -int TRACK::ReturnMaskLayer(void) +int TRACK::ReturnMaskLayer( void ) /***********************************/ + /* Retourne le masque (liste bit a bit ) des couches occupees par le segment - de piste pointe par PtSegm. - Si PtSegm pointe une via, il y a plusieurs couches occupees -*/ + * de piste pointe par PtSegm. + * Si PtSegm pointe une via, il y a plusieurs couches occupees + */ { - if( m_StructType == TYPEVIA ) - { - int via_type = m_Shape & 15; - if( via_type == VIA_NORMALE ) return (ALL_CU_LAYERS); - // VIA_BORGNE ou VIA_ENTERREE: - int bottom_layer = (m_Layer >> 4) & 15; - int top_layer = m_Layer & 15; - if ( bottom_layer > top_layer ) EXCHG (bottom_layer, top_layer); - int layermask = 0; - while ( bottom_layer <= top_layer ) - { - layermask |= g_TabOneLayerMask[bottom_layer++]; - } - return (layermask); - } - else return(g_TabOneLayerMask[m_Layer]); + if( m_StructType == TYPEVIA ) + { + int via_type = m_Shape & 15; + if( via_type == VIA_NORMALE ) + return ALL_CU_LAYERS; + + // VIA_BORGNE ou VIA_ENTERREE: + int bottom_layer = (m_Layer >> 4) & 15; + int top_layer = m_Layer & 15; + if( bottom_layer > top_layer ) + EXCHG( bottom_layer, top_layer ); + int layermask = 0; + while( bottom_layer <= top_layer ) + { + layermask |= g_TabOneLayerMask[bottom_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: - 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; - if( via_type == VIA_NORMALE ) - { - top_layer = LAYER_CMP_N; bottom_layer = LAYER_CUIVRE_N; - } + if( via_type == VIA_NORMALE ) + { + top_layer = LAYER_CMP_N; bottom_layer = LAYER_CUIVRE_N; + } - if ( bottom_layer > top_layer ) EXCHG (bottom_layer, top_layer); - m_Layer = (top_layer & 15) + ( (bottom_layer & 15) << 4 ); + if( bottom_layer > top_layer ) + EXCHG( bottom_layer, top_layer ); + 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 - 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 t_layer = m_Layer & 15; + int b_layer = (m_Layer >> 4) & 15; + int t_layer = m_Layer & 15; - if ( b_layer > t_layer ) EXCHG (b_layer, t_layer); - if ( top_layer ) * top_layer = t_layer; - if ( bottom_layer ) * bottom_layer = b_layer; + if( b_layer > t_layer ) + EXCHG( b_layer, t_layer ); + if( top_layer ) + *top_layer = t_layer; + if( bottom_layer ) + *bottom_layer = b_layer; } /************************/ -TRACK * TRACK::Next(void) +TRACK* TRACK::Next( void ) /************************/ { - return (TRACK *) Pnext; + return (TRACK*) Pnext; } - /* 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 ) { - /* Modification du chainage arriere */ - if( Pback ) - { - if( Pback->m_StructType != TYPEPCB) - { - Pback->Pnext = Pnext; - } + /* Modification du chainage arriere */ + if( Pback ) + { + if( Pback->m_StructType != TYPEPCB ) + { + Pback->Pnext = Pnext; + } + else /* Le chainage arriere pointe sur la structure "Pere" */ + { + if( GetState( DELETED ) ) // A REVOIR car Pback = NULL si place en undelete + { + if( g_UnDeleteStack ) + g_UnDeleteStack[g_UnDeleteStackPtr - 1] = Pnext; + } + else + { + if( m_StructType == TYPEZONE ) + { + ( (BOARD*) Pback )->m_Zone = (TRACK*) Pnext; + } + else + { + ( (BOARD*) Pback )->m_Track = (TRACK*) Pnext; + } + } + } + } - else /* Le chainage arriere pointe sur la structure "Pere" */ - { - if ( GetState(DELETED) ) // A REVOIR car Pback = NULL si place en undelete - { - if( g_UnDeleteStack ) g_UnDeleteStack[g_UnDeleteStackPtr-1] = Pnext; - } - else - { - if (m_StructType == TYPEZONE) - { - ((BOARD*)Pback)->m_Zone = (TRACK*)Pnext; - } - else - { - ((BOARD*)Pback)->m_Track = (TRACK*)Pnext; - } - } - } - } + /* Modification du chainage avant */ + if( Pnext ) + Pnext->Pback = Pback; - /* Modification du chainage avant */ - 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 - Si Insertpoint == NULL: insertion en debut de - liste Pcb->Track ou Pcb->Zone - Insertion a la suite de InsertPoint - Si InsertPoint == NULL, insertion en tete de liste -*/ + * Si Insertpoint == NULL: insertion en debut de + * liste Pcb->Track ou Pcb->Zone + * Insertion a la suite de InsertPoint + * Si InsertPoint == NULL, insertion en tete de liste + */ { -TRACK* track, *NextS; - /* Insertion du debut de la chaine a greffer */ - if (InsertPoint == NULL) - { - Pback = Pcb; - if (m_StructType == TYPEZONE) - { - NextS = Pcb->m_Zone; Pcb->m_Zone = this; - } - else - { - NextS = Pcb->m_Track; Pcb->m_Track = this; - } - } + TRACK* track, * NextS; - else - { - NextS = (TRACK*)InsertPoint->Pnext; - Pback = InsertPoint; - InsertPoint->Pnext = this; - } + /* Insertion du debut de la chaine a greffer */ + if( InsertPoint == NULL ) + { + Pback = Pcb; + if( m_StructType == TYPEZONE ) + { + NextS = Pcb->m_Zone; Pcb->m_Zone = this; + } + else + { + NextS = Pcb->m_Track; Pcb->m_Track = this; + } + } + else + { + NextS = (TRACK*) InsertPoint->Pnext; + Pback = InsertPoint; + InsertPoint->Pnext = this; + } - /* Chainage de la fin de la liste a greffer */ - track = this; - while ( track->Pnext ) track = (TRACK*) track->Pnext; - /* Track pointe la fin de la chaine a greffer */ - track->Pnext = NextS; - if ( NextS ) NextS->Pback = track; + /* Chainage de la fin de la liste a greffer */ + track = this; + while( track->Pnext ) + track = (TRACK*) track->Pnext; + + /* Track pointe la fin de la chaine a greffer */ + track->Pnext = NextS; + 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 - Retourne - un pointeur sur le segment de piste APRES lequel l'insertion - doit se faire ( dernier segment du net d'apartenance ) - NULL si pas de piste ( liste vide ); -*/ + * Retourne + * un pointeur sur le segment de piste APRES lequel l'insertion + * doit se faire ( dernier segment du net d'apartenance ) + * NULL si pas de piste ( liste vide ); + */ { -TRACK * track, * NextTrack; + TRACK* track, * NextTrack; - if( m_StructType == TYPEZONE ) track = Pcb->m_Zone; - else track = Pcb->m_Track; + if( m_StructType == TYPEZONE ) + track = Pcb->m_Zone; + else + track = Pcb->m_Track; - /* Traitement du debut de liste */ - if ( track == NULL ) return(NULL); /* pas de piste ! */ - if ( m_NetCode < track->m_NetCode ) /* insertion en tete de liste */ - return(NULL); + /* Traitement du debut de liste */ + if( track == NULL ) + return NULL; /* pas de piste ! */ + if( m_NetCode < track->m_NetCode ) /* insertion en tete de liste */ + return NULL; - while( (NextTrack = (TRACK*)track->Pnext) != NULL ) - { - if ( NextTrack->m_NetCode > this->m_NetCode ) break; - track = NextTrack; - } - return ( track); + while( (NextTrack = (TRACK*) track->Pnext) != NULL ) + { + if( NextTrack->m_NetCode > this->m_NetCode ) + break; + track = NextTrack; + } + + return track; } + /* Recherche du debut du net - ( les elements sont classes par net_code croissant ) - la recherche se fait a partir de this - si net_code == -1 le netcode de this sera utilise - Retourne un pointeur sur le debut du net, ou NULL si net non trouve -*/ -TRACK * TRACK::GetStartNetCode(int NetCode ) + * ( les elements sont classes par net_code croissant ) + * la recherche se fait a partir de this + * si net_code == -1 le netcode de this sera utilise + * Retourne un pointeur sur le debut du net, ou NULL si net non trouve + */ +TRACK* TRACK::GetStartNetCode( int NetCode ) { -TRACK * Track = this; -int ii = 0; + TRACK* Track = this; + int ii = 0; - if( NetCode == -1 ) NetCode = m_NetCode; + if( NetCode == -1 ) + NetCode = m_NetCode; - while( Track != NULL) - { - if ( Track->m_NetCode > NetCode ) break; - if ( Track->m_NetCode == NetCode ) - { - ii++; break; - } - Track = (TRACK*) Track->Pnext; - } - if ( ii ) return(Track); - else return (NULL); + while( Track != NULL ) + { + if( Track->m_NetCode > NetCode ) + break; + if( Track->m_NetCode == NetCode ) + { + ii++; break; + } + Track = (TRACK*) Track->Pnext; + } + + if( ii ) + return Track; + else + return NULL; } + /* Recherche de la fin du net - Retourne un pointeur sur la fin du net, ou NULL si net non trouve -*/ -TRACK * TRACK::GetEndNetCode(int NetCode) + * Retourne un pointeur sur la fin du net, ou NULL si net non trouve + */ +TRACK* TRACK::GetEndNetCode( int NetCode ) { -TRACK * NextS, * Track = this; -int ii = 0; + TRACK* NextS, * Track = this; + 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) - { - NextS = (TRACK*)Track->Pnext; - if(Track->m_NetCode == NetCode) ii++; - if ( NextS == NULL ) break; - if ( NextS->m_NetCode > NetCode) break; - Track = NextS; - } - if ( ii ) return(Track); - else return (NULL); + while( Track != NULL ) + { + NextS = (TRACK*) Track->Pnext; + if( Track->m_NetCode == NetCode ) + ii++; + if( NextS == NULL ) + break; + if( NextS->m_NetCode > NetCode ) + break; + Track = NextS; + } + + 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 - Retourne un pointeur sur le nouvel element ou le debut de la - nouvelle chaine -*/ + * Retourne un pointeur sur le nouvel element ou le debut de la + * nouvelle chaine + */ { -TRACK * NewTrack, * FirstTrack, *OldTrack, * Source = this; -int ii; + TRACK* NewTrack, * FirstTrack, * OldTrack, * Source = this; + int ii; - FirstTrack = NewTrack = new TRACK(*Source); + FirstTrack = NewTrack = new TRACK( *Source ); - for( ii = 1; ii < NbSegm; ii++ ) - { - Source = Source->Next(); - if( Source == NULL ) break; - OldTrack = NewTrack; - NewTrack = new TRACK(*Source); - NewTrack->Insert(NULL, OldTrack); - } + for( ii = 1; ii < NbSegm; ii++ ) + { + Source = Source->Next(); + if( Source == NULL ) + break; + OldTrack = NewTrack; + NewTrack = new TRACK( *Source ); + NewTrack->Insert( NULL, OldTrack ); + } - return (FirstTrack); + return FirstTrack; } + /********************************************/ -bool TRACK::WriteTrackDescr(FILE * File) +bool TRACK::WriteTrackDescr( FILE* File ) /********************************************/ { -int type; + int type; - type = 0; - if( m_StructType == TYPEVIA ) type = 1; + type = 0; + 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, - m_Start.x, m_Start.y, m_End.x, m_End.y, m_Width, m_Drill); + 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 ); - fprintf( File,"De %d %d %d %lX %X\n", - m_Layer, type ,m_NetCode, - m_TimeStamp, ReturnStatus()); - return TRUE; + fprintf( File, "De %d %d %d %lX %X\n", + m_Layer, type, m_NetCode, + m_TimeStamp, ReturnStatus() ); + 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. -Parametres : - draw_mode = mode ( GR_XOR, GR_OR..) -*/ + +/* routine de trace de 1 segment de piste. + * Parametres : + * draw_mode = mode ( GR_XOR, GR_OR..) + */ { -int l_piste; -int color; -int zoom; -int rayon; -int curr_layer = ((PCB_SCREEN*)panel->GetScreen())->m_Active_Layer; + int l_piste; + int color; + int zoom; + int rayon; + int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; - if(m_StructType == TYPEZONE && (! DisplayOpt.DisplayZones) ) - return; + if( m_StructType == TYPEZONE && (!DisplayOpt.DisplayZones) ) + return; - GRSetDrawMode(DC, draw_mode); + GRSetDrawMode( DC, draw_mode ); - if ( m_StructType == TYPEVIA ) /* VIA rencontree */ - color = g_DesignSettings.m_ViaColor[m_Shape]; - else color = g_DesignSettings.m_LayerColor[m_Layer]; + if( m_StructType == TYPEVIA ) /* VIA rencontree */ + color = g_DesignSettings.m_ViaColor[m_Shape]; + 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 ( m_StructType == TYPEVIA ) - { - if ( ! ((SEGVIA*)this)->IsViaOnLayer(curr_layer) ) - { - color &= ~MASKCOLOR; - color |= DARKDARKGRAY; - } - } - else if ( m_Layer != curr_layer) - { - color &= ~MASKCOLOR; - color |= DARKDARKGRAY; - } - } + if( DisplayOpt.ContrastModeDisplay ) + { + if( m_StructType == TYPEVIA ) + { + if( !( (SEGVIA*) this )->IsViaOnLayer( curr_layer ) ) + { + color &= ~MASKCOLOR; + color |= DARKDARKGRAY; + } + } + else if( m_Layer != curr_layer ) + { + color &= ~MASKCOLOR; + color |= DARKDARKGRAY; + } + } - if( draw_mode & GR_SURBRILL) - { - if( draw_mode & GR_AND) color &= ~HIGHT_LIGHT_FLAG; - else color |= HIGHT_LIGHT_FLAG; - } - if ( color & HIGHT_LIGHT_FLAG) - color = ColorRefs[color & MASKCOLOR].m_LightColor; + if( draw_mode & GR_SURBRILL ) + { + if( draw_mode & GR_AND ) + color &= ~HIGHT_LIGHT_FLAG; + else + color |= HIGHT_LIGHT_FLAG; + } + if( color & HIGHT_LIGHT_FLAG ) + color = ColorRefs[color & MASKCOLOR].m_LightColor; - zoom = panel->GetZoom(); + zoom = panel->GetZoom(); - l_piste = m_Width >> 1; + l_piste = m_Width >> 1; - if ( m_StructType == TYPEVIA ) /* VIA rencontree */ - { - rayon = l_piste; if( rayon < zoom ) rayon = zoom; - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color) ; - if ( rayon > (4*zoom) ) - { - int drill_rayon, inner_rayon = rayon-(2*zoom); - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - inner_rayon, color); - // Draw the via hole if the display option request it - if ( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW) - { - if ( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) - || ( m_Drill > 0 ) ) - { - if ( m_Drill > 0 ) drill_rayon = m_Drill / 2; - else drill_rayon = g_DesignSettings.m_ViaDrill / 2; - if( drill_rayon < inner_rayon ) // We can show the via hole - { - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - drill_rayon , color); - } - } - } + if( m_StructType == TYPEVIA ) /* VIA rencontree */ + { + rayon = l_piste; if( rayon < zoom ) + rayon = zoom; + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); + if( rayon > (4 * zoom) ) + { + int drill_rayon, inner_rayon = rayon - (2 * zoom); + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + inner_rayon, color ); - if(DisplayOpt.DisplayTrackIsol) - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - rayon + g_DesignSettings.m_TrackClearence, color); - } - return; - } + // Draw the via hole if the display option request it + if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) + { + if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) + || ( m_Drill > 0 ) ) + { + if( m_Drill > 0 ) + drill_rayon = m_Drill / 2; + else + drill_rayon = g_DesignSettings.m_ViaDrill / 2; + if( drill_rayon < inner_rayon ) // We can show the via hole + { + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + drill_rayon, color ); + } + } + } - if(m_Shape == S_CIRCLE) - { - rayon = (int)hypot((double)(m_End.x - m_Start.x), - (double)(m_End.y - m_Start.y) ); - if ( (l_piste/zoom) < L_MIN_DESSIN) - { - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon , color) ; - } + if( DisplayOpt.DisplayTrackIsol ) + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + rayon + g_DesignSettings.m_TrackClearence, color ); + } + return; + } - else - { - if(l_piste <= zoom) /* trace simplifie si l_piste/zoom <= 1 */ - { - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color); - } - else if( ( ! DisplayOpt.DisplayPcbTrackFill) || GetState(FORCE_SKETCH)) - { - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon-l_piste, color); - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon+l_piste, color); - } - else - { - GRCircle(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, - m_Width, color); - } - } - return; - } + if( m_Shape == S_CIRCLE ) + { + rayon = (int) hypot( (double) (m_End.x - m_Start.x), + (double) (m_End.y - m_Start.y) ); + if( (l_piste / zoom) < L_MIN_DESSIN ) + { + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); + } + else + { + if( l_piste <= zoom ) /* trace simplifie si l_piste/zoom <= 1 */ + { + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, color ); + } + else if( ( !DisplayOpt.DisplayPcbTrackFill) || GetState( FORCE_SKETCH ) ) + { + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon - l_piste, color ); + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon + l_piste, color ); + } + else + { + GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, rayon, + m_Width, color ); + } + } + return; + } - if ( (l_piste/zoom) < L_MIN_DESSIN) - { - GRLine(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, 0, color); - return; - } + if( (l_piste / zoom) < L_MIN_DESSIN ) + { + GRLine( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + m_End.x, m_End.y, 0, color ); + return; + } - if( (! DisplayOpt.DisplayPcbTrackFill) || GetState(FORCE_SKETCH) ) - { - GRCSegm(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, m_Width, color) ; - } - else - { - GRFillCSegm(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, m_Width, color) ; - } + if( (!DisplayOpt.DisplayPcbTrackFill) || GetState( FORCE_SKETCH ) ) + { + GRCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + m_End.x, m_End.y, m_Width, color ); + } + else + { + GRFillCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + m_End.x, m_End.y, m_Width, color ); + } - /* Trace de l'isolation (pour segments type CUIVRE et TRACK uniquement */ - if( (DisplayOpt.DisplayTrackIsol) && (m_Layer <= CMP_N ) - && ( m_StructType == TYPETRACK) ) - { - GRCSegm(&panel->m_ClipBox, DC, m_Start.x, m_Start.y, - m_End.x, m_End.y, - m_Width + (g_DesignSettings.m_TrackClearence*2), color) ; - } + /* Trace de l'isolation (pour segments type CUIVRE et TRACK uniquement */ + if( (DisplayOpt.DisplayTrackIsol) && (m_Layer <= CMP_N ) + && ( m_StructType == TYPETRACK) ) + { + GRCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, + m_End.x, m_End.y, + m_Width + (g_DesignSettings.m_TrackClearence * 2), 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 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; +} + diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 30235a17d9..3562dfe32b 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -10,84 +10,135 @@ /* Type des Vias (shape)*/ /* Forme des Vias ( parametre .shape ) */ -#define VIA_NORMALE 3 /* type via : traversante (throught via) */ -#define VIA_ENTERREE 2 /* type via : enterree ou aveugle (blind via) */ -#define VIA_BORGNE 1 /* type via : borgne ou demi-traversante (buried via) */ -#define VIA_NOT_DEFINED 0 /* reserved */ -#define SQUARE_VIA 0x80000000 /* Flag pour forme carree */ +#define VIA_NORMALE 3 /* type via : traversante (throught via) */ +#define VIA_ENTERREE 2 /* type via : enterree ou aveugle (blind via) */ +#define VIA_BORGNE 1 /* type via : borgne ou demi-traversante (buried via) */ +#define VIA_NOT_DEFINED 0 /* reserved */ +#define SQUARE_VIA 0x80000000 /* Flag pour forme carree */ /***/ -class TRACK: public EDA_BaseLineStruct +class TRACK : public EDA_BaseLineStruct { public: - int m_Shape; // vias: shape and type, Track = shape.. - int m_Drill; // for vias: via drill (- 1 for default value) - EDA_BaseStruct * start,* end; // pointers on a connected item (pad or track) - int m_NetCode; // Net number - int m_Sous_Netcode; /* In rastnest routines : for the current net, - block number (number common to the current connected items found) */ - // chain = 0 indique une connexion non encore traitee - int m_Param; // Auxiliary variable ( used in some computations ) + int m_Shape; // vias: shape and type, Track = shape.. + int m_Drill; // for vias: via drill (- 1 for default value) + EDA_BaseStruct* start, * end; // pointers on a connected item (pad or track) + int m_NetCode; // Net number + int m_Sous_Netcode; /* In rastnest routines : for the current net, + * block number (number common to the current connected items found) */ + + // chain = 0 indique une connexion non encore traitee + int m_Param; // Auxiliary variable ( used in some computations ) public: - TRACK(EDA_BaseStruct * StructFather, DrawStructureType idtype = TYPETRACK); - TRACK(const TRACK & track); + TRACK( EDA_BaseStruct* StructFather, DrawStructureType idtype = TYPETRACK ); + TRACK( const TRACK& track ); - TRACK * Next(void); // Retourne le chainage avant - TRACK * Back(void) // Retourne le chainage avant - { - return (TRACK*) Pback; - } + TRACK* Next( void ); // Retourne le chainage avant - /* supprime du chainage la structure Struct */ - void UnLink( void ); + TRACK* Back( void ) // Retourne le chainage avant + { + return (TRACK*) Pback; + } - // Read/write data - bool WriteTrackDescr(FILE * File); - /* Ajoute un element a la liste */ - void Insert(BOARD * Pcb, EDA_BaseStruct * InsertPoint); + /* supprime du chainage la structure Struct */ + void UnLink( void ); - /* Recherche du meilleur point d'insertion */ - TRACK * GetBestInsertPoint( BOARD * Pcb); + // Read/write data + bool WriteTrackDescr( FILE* File ); - /* Copie d'un Element d'une chaine de n elements */ - TRACK * Copy( int NbSegm = 1 ); + /* Ajoute un element a la liste */ + void Insert( BOARD* Pcb, EDA_BaseStruct* InsertPoint ); - /* Recherche du debut du net - ( les elements sont classes par net_code croissant ) */ - TRACK * GetStartNetCode(int NetCode ); - /* Recherche de la fin du net */ - TRACK * GetEndNetCode(int NetCode); + /* Recherche du meilleur point d'insertion */ + TRACK* GetBestInsertPoint( BOARD* Pcb ); - /* Display on screen: */ - void Draw(WinEDA_DrawPanel * panel, wxDC * DC, int draw_mode); + /* Copie d'un Element d'une chaine de n elements */ + TRACK* Copy( int NbSegm = 1 ); - /* divers */ - int Shape(void) { return m_Shape & 0xFF; } + /* Recherche du debut du net + * ( les elements sont classes par net_code croissant ) */ + TRACK* GetStartNetCode( int NetCode ); - int ReturnMaskLayer(void); - int IsPointOnEnds(const wxPoint & point, int min_dist = 0); - bool IsNull(void); // return TRUE if segment lenght = 0 + /* Recherche de la fin du net */ + TRACK* GetEndNetCode( int NetCode ); + + /* Display on screen: */ + void Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode ); + + /* divers */ + int Shape( void ) { return m_Shape & 0xFF; } + + int ReturnMaskLayer( void ); + int IsPointOnEnds( const wxPoint& point, int min_dist = 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: - 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 { public: - SEGVIA(EDA_BaseStruct * StructFather); - bool IsViaOnLayer(int layer); - void SetLayerPair(int top_layer, int bottom_layer); - void ReturnLayerPair(int * top_layer, int * bottom_layer); + SEGVIA( EDA_BaseStruct* StructFather ); + bool IsViaOnLayer( int layer ); + void SetLayerPair( 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 */ diff --git a/pcbnew/classpcb.cpp b/pcbnew/classpcb.cpp index 0613ac792f..c7b9d8d261 100644 --- a/pcbnew/classpcb.cpp +++ b/pcbnew/classpcb.cpp @@ -16,6 +16,7 @@ #endif #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 */ /*******************/ diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 6d34840eab..fab88cf317 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -1,6 +1,6 @@ - /****************************/ - /* DRC control */ - /****************************/ +/****************************/ +/* DRC control */ +/****************************/ #include "fctsys.h" #include "gr_basic.h" @@ -14,1345 +14,1542 @@ /* variables locales */ class WinEDA_DrcFrame; -WinEDA_DrcFrame * DrcFrame; +WinEDA_DrcFrame* DrcFrame; /* saving drc options */ -static bool s_Pad2PadTestOpt = true; -static bool s_UnconnectedTestOpt = true; -static bool s_ZonesTestOpt = false; -static bool s_CreateRptFileOpt = false; -static FILE * s_RptFile = NULL; -static wxString s_RptFilename; +static bool s_Pad2PadTestOpt = true; +static bool s_UnconnectedTestOpt = true; +static bool s_ZonesTestOpt = false; +static bool s_CreateRptFileOpt = false; +static FILE* s_RptFile = NULL; +static wxString s_RptFilename; -static int ErrorsDRC_Count; -static MARQUEUR * current_marqueur; /* Pour gestion des marqueurs sur pcb */ +static int ErrorsDRC_Count; +static MARQUEUR* current_marqueur; /* Pour gestion des marqueurs sur pcb */ -static bool AbortDrc, DrcInProgress = FALSE; -static int spot_cX, spot_cY; /* position d'elements a tester */ -static int finx, finy; // coord relatives de l'extremite du segm de reference -static int segm_angle; // angle d'inclinaison du segment de reference en 0,1 degre -static int segm_long; // longueur du segment de reference -static int xcliplo,ycliplo,xcliphi,ycliphi ; /* coord de la surface de securite du segment a comparer */ +static bool AbortDrc, DrcInProgress = FALSE; +static int spot_cX, spot_cY; /* position d'elements a tester */ +static int finx, finy; // coord relatives de l'extremite du segm de reference +static int segm_angle; // angle d'inclinaison du segment de reference en 0,1 degre +static int segm_long; // longueur du segment de reference +static int xcliplo, ycliplo, xcliphi, ycliphi; /* coord de la surface de securite du segment a comparer */ /* Routines Locales */ -static int Pad_to_Pad_Isol(D_PAD * pad_ref, D_PAD * pad, const int dist_min); -static bool Test_Pad_to_Pads_Drc(WinEDA_BasePcbFrame *frame, wxDC * DC, D_PAD * pad_ref, - LISTE_PAD * start_buffer, LISTE_PAD * end_buffer, int max_size, bool show_err); -static int TestClearanceSegmToPad(const D_PAD* pad_to_test, int seg_width, int isol); -static int TestMarginToCircle(int cx, int cy, int rayon, int longueur); -static int Tst_Ligne(int x1,int y1,int x2,int y2); -static void Affiche_Erreur_DRC(WinEDA_DrawPanel * panel, wxDC * DC, BOARD * Pcb, - TRACK * pt_ref, void * pt_item, int errnumber); -static void Affiche_Erreur_DRC(WinEDA_DrawPanel * panel, wxDC * DC, - BOARD * Pcb, D_PAD * pad1, D_PAD * pad2); +static int Pad_to_Pad_Isol( D_PAD* pad_ref, D_PAD* pad, const int dist_min ); +static bool Test_Pad_to_Pads_Drc( WinEDA_BasePcbFrame* frame, + wxDC* DC, + D_PAD* pad_ref, + LISTE_PAD* start_buffer, + LISTE_PAD* end_buffer, + int max_size, + bool show_err ); +static int TestClearanceSegmToPad( const D_PAD* pad_to_test, int seg_width, int isol ); +static int TestMarginToCircle( int cx, int cy, int rayon, int longueur ); +static int Tst_Ligne( int x1, int y1, int x2, int y2 ); +static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, + TRACK* pt_ref, void* pt_item, int errnumber ); +static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, + BOARD* Pcb, D_PAD* pad1, D_PAD* pad2 ); - - /*******************************************/ - /* Frame d'option et execution DRC general */ - /*******************************************/ +/*******************************************/ +/* Frame d'option et execution DRC general */ +/*******************************************/ #include "dialog_drc.cpp" /***************************************************************/ -void WinEDA_DrcFrame::ListUnconnectedPads(wxCommandEvent & event) +void WinEDA_DrcFrame::ListUnconnectedPads( wxCommandEvent& event ) /***************************************************************/ { - if( (m_Parent->m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 ) - { - m_Parent->Compile_Ratsnest( m_DC, TRUE); - } - if( m_Parent->m_Pcb->m_Ratsnest == NULL ) return; + if( (m_Parent->m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 ) + { + m_Parent->Compile_Ratsnest( m_DC, TRUE ); + } + if( m_Parent->m_Pcb->m_Ratsnest == NULL ) + return; -CHEVELU* Ratsnest = m_Parent->m_Pcb->m_Ratsnest; -int draw_mode = GR_SURBRILL | GR_OR; -WinEDA_DrawPanel * panel = m_Parent->DrawPanel; -int ii; -wxString msg; -float convert = 0.0001; + CHEVELU* Ratsnest = m_Parent->m_Pcb->m_Ratsnest; + int draw_mode = GR_SURBRILL | GR_OR; + WinEDA_DrawPanel* panel = m_Parent->DrawPanel; + int ii; + wxString msg; + float convert = 0.0001; - msg = _("Look for active routes\n"); - m_logWindow->AppendText(msg); - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); + msg = _( "Look for active routes\n" ); + m_logWindow->AppendText( msg ); + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - m_UnconnectedCount = 0; - for( ii = m_Parent->m_Pcb->GetNumRatsnests() ;ii > 0; Ratsnest++, ii--) - { - if( (Ratsnest->status & CH_ACTIF) == 0) continue; - m_UnconnectedCount++; - if ( m_UnconnectedCount == 1 ) m_logWindow->AppendText(_("Unconnected found:\n") ); - D_PAD * pad = Ratsnest->pad_start; - pad->Draw(panel, m_DC, wxPoint(0,0),draw_mode); - wxString pad_name = pad->ReturnStringPadName(); - wxString module_name = ((MODULE*)(pad->m_Parent))->m_Reference->m_Text; - msg.Printf(_("%d > Pad %s (%s) @ %.4f,%.4f and "), m_UnconnectedCount, - pad_name.GetData(), module_name.GetData(), pad->m_Pos.x * convert, pad->m_Pos.y * convert); - m_logWindow->AppendText(msg); - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); + m_UnconnectedCount = 0; + for( ii = m_Parent->m_Pcb->GetNumRatsnests(); ii > 0; Ratsnest++, ii-- ) + { + if( (Ratsnest->status & CH_ACTIF) == 0 ) + continue; + m_UnconnectedCount++; + if( m_UnconnectedCount == 1 ) + m_logWindow->AppendText( _( "Unconnected found:\n" ) ); + D_PAD* pad = Ratsnest->pad_start; + pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode ); + wxString pad_name = pad->ReturnStringPadName(); + wxString module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text; + msg.Printf( _( "%d > Pad %s (%s) @ %.4f,%.4f and " ), m_UnconnectedCount, + pad_name.GetData(), module_name.GetData( + ), pad->m_Pos.x * convert, pad->m_Pos.y * convert ); + m_logWindow->AppendText( msg ); + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - pad = Ratsnest->pad_end; - pad->Draw(panel, m_DC, wxPoint(0,0),draw_mode); - pad_name = pad->ReturnStringPadName(); - module_name = ((MODULE*)(pad->m_Parent))->m_Reference->m_Text; - msg.Printf(_("Pad %s (%s) @ %.4f,%.4f\n"), - pad_name.GetData(), module_name.GetData(), pad->m_Pos.x * convert, pad->m_Pos.y * convert); - m_logWindow->AppendText(msg); - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); - } + pad = Ratsnest->pad_end; + pad->Draw( panel, m_DC, wxPoint( 0, 0 ), draw_mode ); + pad_name = pad->ReturnStringPadName(); + module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text; + msg.Printf( _( "Pad %s (%s) @ %.4f,%.4f\n" ), + pad_name.GetData(), module_name.GetData( + ), pad->m_Pos.x * convert, pad->m_Pos.y * convert ); + m_logWindow->AppendText( msg ); + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); + } - if ( m_UnconnectedCount ) msg.Printf(_("Active routes: %d\n"), m_UnconnectedCount); - else msg = _("OK! (No active routes)\n"); - m_logWindow->AppendText(msg); - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); + if( m_UnconnectedCount ) + msg.Printf( _( "Active routes: %d\n" ), m_UnconnectedCount ); + else + msg = _( "OK! (No active routes)\n" ); + m_logWindow->AppendText( msg ); + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); } /****************************************************/ -void WinEDA_DrcFrame::TestDrc(wxCommandEvent & event) +void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event ) /****************************************************/ { -int errors; -wxString msg; - - if ( ! DrcInProgress ) - { - if ( m_CreateRptCtrl->IsChecked() ) // Create a file rpt - { - s_RptFilename = m_RptFilenameCtrl->GetValue(); - if ( s_RptFilename.IsEmpty() ) OnButtonBrowseRptFileClick( event ); - if ( ! s_RptFilename.IsEmpty() ) s_RptFile = wxFopen(s_RptFilename, wxT("w")); - else s_RptFile = NULL; - } - - if ( s_RptFile ) - { - fprintf(s_RptFile, "Drc report for %s\n", CONV_TO_UTF8(m_Parent->m_CurrentScreen->m_FileName) ); - char line[256]; - fprintf(s_RptFile, "Created on %s\n", DateAndTime(line)); - } + int errors; + wxString msg; - s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked(); - s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked(); - s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked(); - AbortDrc = FALSE; - m_logWindow->Clear(); - g_DesignSettings.m_TrackClearence = - ReturnValueFromTextCtrl(*m_SetClearance, m_Parent->m_InternalUnits); - /* Test DRC errors (clearance errors, bad connections .. */ - errors = m_Parent->Test_DRC(m_DC, m_Pad2PadTestCtrl->IsChecked(), m_ZonesTestCtrl->IsChecked()); - /* Search for active routes (unconnected pads) */ - if ( m_UnconnectedTestCtrl->IsChecked() ) ListUnconnectedPads(event); - else m_UnconnectedCount = 0; - if ( errors ) - msg.Printf(_("** End Drc: %d errors **\n"),errors); - else if ( m_UnconnectedCount == 0 ) - msg = _("** End Drc: No Error **\n"); - m_logWindow->AppendText(msg); - - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); - - if ( s_RptFile ) - { - msg.Printf( _("Report file <%s> created\n"), s_RptFilename.GetData()); - m_logWindow->AppendText(msg); - fclose(s_RptFile); - s_RptFile = NULL; - } + if( !DrcInProgress ) + { + if( m_CreateRptCtrl->IsChecked() ) // Create a file rpt + { + s_RptFilename = m_RptFilenameCtrl->GetValue(); + if( s_RptFilename.IsEmpty() ) + OnButtonBrowseRptFileClick( event ); + if( !s_RptFilename.IsEmpty() ) + s_RptFile = wxFopen( s_RptFilename, wxT( "w" ) ); + else + s_RptFile = NULL; + } - } - else wxBell(); + if( s_RptFile ) + { + fprintf( s_RptFile, "Drc report for %s\n", + CONV_TO_UTF8( m_Parent->m_CurrentScreen->m_FileName ) ); + char line[256]; + fprintf( s_RptFile, "Created on %s\n", DateAndTime( line ) ); + } + + s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked(); + s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked(); + s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked(); + AbortDrc = FALSE; + m_logWindow->Clear(); + g_DesignSettings.m_TrackClearence = + ReturnValueFromTextCtrl( *m_SetClearance, m_Parent->m_InternalUnits ); + /* Test DRC errors (clearance errors, bad connections .. */ + errors = m_Parent->Test_DRC( m_DC, m_Pad2PadTestCtrl->IsChecked( + ), m_ZonesTestCtrl->IsChecked() ); + /* Search for active routes (unconnected pads) */ + if( m_UnconnectedTestCtrl->IsChecked() ) + ListUnconnectedPads( event ); + else + m_UnconnectedCount = 0; + if( errors ) + msg.Printf( _( "** End Drc: %d errors **\n" ), errors ); + else if( m_UnconnectedCount == 0 ) + msg = _( "** End Drc: No Error **\n" ); + m_logWindow->AppendText( msg ); + + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); + + if( s_RptFile ) + { + msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() ); + m_logWindow->AppendText( msg ); + fclose( s_RptFile ); + s_RptFile = NULL; + } + } + else + wxBell(); } + /*********************************************************/ -void WinEDA_DrcFrame::DelDRCMarkers(wxCommandEvent & event) +void WinEDA_DrcFrame::DelDRCMarkers( wxCommandEvent& event ) /*********************************************************/ { - if ( ! DrcInProgress ) - { - m_Parent->Erase_Marqueurs(); - m_Parent->DrawPanel->ReDraw(m_DC,TRUE); - } - else wxBell(); + if( !DrcInProgress ) + { + m_Parent->Erase_Marqueurs(); + m_Parent->DrawPanel->ReDraw( m_DC, TRUE ); + } + else + wxBell(); } + /******************************************************/ -void WinEDA_PcbFrame::Install_Test_DRC_Frame(wxDC * DC) +void WinEDA_PcbFrame::Install_Test_DRC_Frame( wxDC* DC ) /******************************************************/ + /* Test des isolements : teste les isolements des pistes et place un - marqueur sur les divers segments en defaut - Principe: - Appelle la routine drc() pour chaque segment de piste existant -*/ + * marqueur sur les divers segments en defaut + * Principe: + * Appelle la routine drc() pour chaque segment de piste existant + */ { - AbortDrc = FALSE; - DrcFrame = new WinEDA_DrcFrame(this, DC); - DrcFrame->ShowModal(); DrcFrame->Destroy(); - DrcFrame = NULL; + AbortDrc = FALSE; + DrcFrame = new WinEDA_DrcFrame( this, DC ); + DrcFrame->ShowModal(); DrcFrame->Destroy(); + DrcFrame = NULL; } /************************************************************************/ -int WinEDA_PcbFrame::Test_DRC(wxDC * DC, bool TestPad2Pad, bool TestZone) +int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone ) /************************************************************************/ + /* Test des isolements : teste les isolements des pistes et place un - marqueur sur les divers segments en defaut - Principe: - Appelle la routine drc() pour chaque segment de piste existant -*/ + * marqueur sur les divers segments en defaut + * Principe: + * Appelle la routine drc() pour chaque segment de piste existant + */ { -int ii, jj, old_net; -int flag_err_Drc; -TRACK * pt_segm; -D_PAD * pad; -MARQUEUR * Marqueur; -EDA_BaseStruct * PtStruct; -wxString Line; -#define PRINT_NB_PAD_POS 42 -#define PRINT_PAD_ERR_POS 48 -#define PRINT_TST_POS 20 -#define PRINT_NB_SEGM_POS 26 -#define PRINT_TRACK_ERR_POS 32 + int ii, jj, old_net; + int flag_err_Drc; + TRACK* pt_segm; + D_PAD* pad; + MARQUEUR* Marqueur; + EDA_BaseStruct* PtStruct; + wxString Line; + +#define PRINT_NB_PAD_POS 42 +#define PRINT_PAD_ERR_POS 48 +#define PRINT_TST_POS 20 +#define PRINT_NB_SEGM_POS 26 +#define PRINT_TRACK_ERR_POS 32 #define PRINT_NB_ZONESEGM_POS 60 -#define PRINT_ZONE_ERR_POS 70 +#define PRINT_ZONE_ERR_POS 70 - DrcInProgress = TRUE; + DrcInProgress = TRUE; ErrorsDRC_Count = 0; - Compile_Ratsnest(DC, TRUE); + Compile_Ratsnest( DC, TRUE ); - MsgPanel->EraseMsgBox(); + MsgPanel->EraseMsgBox(); - m_CurrentScreen->SetRefreshReq(); + m_CurrentScreen->SetRefreshReq(); - /* Effacement des anciens marqueurs */ - Erase_Marqueurs(); + /* Effacement des anciens marqueurs */ + Erase_Marqueurs(); - if ( TestPad2Pad ) /* Test DRC des pads entre eux */ - { - Line.Printf( wxT("%d"),m_Pcb->m_NbPads) ; - Affiche_1_Parametre(this, PRINT_NB_PAD_POS, wxT("NbPad"),Line,RED) ; - Affiche_1_Parametre(this, PRINT_PAD_ERR_POS, wxT("Pad Err"), wxT("0"), LIGHTRED); - if ( DrcFrame ) DrcFrame->m_logWindow->AppendText(_("Tst Pad to Pad\n")); - LISTE_PAD * pad_list_start = CreateSortedPadListByXCoord(m_Pcb); - LISTE_PAD * pad_list_limit = &pad_list_start[m_Pcb->m_NbPads]; - int max_size = 0; - LISTE_PAD * pad_list; - /* Compute the max size of the pads ( used to stop the test) */ - for ( pad_list = pad_list_start; pad_list < pad_list_limit; pad_list++) - { - pad = * pad_list; - if ( pad->m_Rayon > max_size ) max_size = pad->m_Rayon; - } - /* Test the pads */ - for ( pad_list = pad_list_start; pad_list < pad_list_limit; pad_list++) - { - pad = * pad_list; - if ( Test_Pad_to_Pads_Drc(this, DC, pad, pad_list, pad_list_limit, max_size, TRUE) == BAD_DRC ) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError(this, wxT("Test_Drc(): internal err")); - return ErrorsDRC_Count; - } - Line.Printf( wxT("%d"),ErrorsDRC_Count) ; - Affiche_1_Parametre(this, PRINT_PAD_ERR_POS,wxEmptyString,Line, LIGHTRED); - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; + if( TestPad2Pad ) /* Test DRC des pads entre eux */ + { + Line.Printf( wxT( "%d" ), m_Pcb->m_NbPads ); + Affiche_1_Parametre( this, PRINT_NB_PAD_POS, wxT( "NbPad" ), Line, RED ); + Affiche_1_Parametre( this, PRINT_PAD_ERR_POS, wxT( "Pad Err" ), wxT( "0" ), LIGHTRED ); + + if( DrcFrame ) + DrcFrame->m_logWindow->AppendText( _( "Tst Pad to Pad\n" ) ); + + LISTE_PAD* pad_list_start = CreateSortedPadListByXCoord( m_Pcb ); + LISTE_PAD* pad_list_limit = &pad_list_start[m_Pcb->m_NbPads]; + int max_size = 0; + LISTE_PAD* pad_list; + /* Compute the max size of the pads ( used to stop the test) */ + for( pad_list = pad_list_start; pad_list < pad_list_limit; pad_list++ ) + { + pad = *pad_list; + if( pad->m_Rayon > max_size ) + max_size = pad->m_Rayon; + } - PtStruct = m_Pcb->m_Drawings; - if(PtStruct) PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; - } - } - free(pad_list_start); - } - - /* Test track segments */ - Line.Printf( wxT("%d"),m_Pcb->m_NbSegmTrack) ; - Affiche_1_Parametre(this, PRINT_NB_SEGM_POS,_("SegmNb"),Line,RED) ; - Affiche_1_Parametre(this, PRINT_TRACK_ERR_POS,_("Track Err"), wxT("0"), LIGHTRED); - pt_segm = m_Pcb->m_Track; + /* Test the pads */ + for( pad_list = pad_list_start; pad_list < pad_list_limit; pad_list++ ) + { + pad = *pad_list; + if( Test_Pad_to_Pads_Drc( this, DC, pad, pad_list, pad_list_limit, max_size, + TRUE ) == BAD_DRC ) + { + Marqueur = current_marqueur; + current_marqueur = NULL; + if( Marqueur == NULL ) + { + DisplayError( this, wxT( "Test_Drc(): internal err" ) ); + return ErrorsDRC_Count; + } + Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); + Affiche_1_Parametre( this, PRINT_PAD_ERR_POS, wxEmptyString, Line, LIGHTRED ); + Marqueur->Pnext = m_Pcb->m_Drawings; + Marqueur->Pback = m_Pcb; - if ( DrcFrame ) DrcFrame->m_logWindow->AppendText( _("Tst Tracks\n") ); - for( ii = 0, old_net = -1, jj = 0; pt_segm != NULL; pt_segm = (TRACK*)pt_segm->Pnext, ii++, jj--) - { - if( pt_segm->Pnext == NULL) break; - if ( jj == 0 ) - { - jj = 10; - wxYield(); - if(AbortDrc) - { - AbortDrc = FALSE; break; - } - /* Print stats */ - Line.Printf( wxT("%d"),ii); - Affiche_1_Parametre(this, PRINT_TST_POS, wxT("Test"),Line,CYAN) ; - } + PtStruct = m_Pcb->m_Drawings; + if( PtStruct ) + PtStruct->Pback = Marqueur; + m_Pcb->m_Drawings = Marqueur; + } + } - if ( old_net != pt_segm->m_NetCode) - { - wxString msg; - jj = 1; - EQUIPOT * equipot = GetEquipot(m_Pcb, pt_segm->m_NetCode); - if ( equipot ) msg = equipot->m_Netname + wxT(" "); - else msg = wxT(""); - Affiche_1_Parametre(this, 0,_("Netname"),msg, YELLOW); - old_net = pt_segm->m_NetCode; - } + free( pad_list_start ); + } - g_HightLigth_NetCode = pt_segm->m_NetCode; - flag_err_Drc = Drc(this, DC, pt_segm,(TRACK*)pt_segm->Pnext, 1); - if(flag_err_Drc == BAD_DRC) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError(this, wxT("Test_Drc(): internal err")); - return ErrorsDRC_Count; - } - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; + /* Test track segments */ + Line.Printf( wxT( "%d" ), m_Pcb->m_NbSegmTrack ); + Affiche_1_Parametre( this, PRINT_NB_SEGM_POS, _( "SegmNb" ), Line, RED ); + Affiche_1_Parametre( this, PRINT_TRACK_ERR_POS, _( "Track Err" ), wxT( "0" ), LIGHTRED ); + pt_segm = m_Pcb->m_Track; - PtStruct = m_Pcb->m_Drawings; - if(PtStruct) PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; + if( DrcFrame ) + DrcFrame->m_logWindow->AppendText( _( "Tst Tracks\n" ) ); + + for( ii = 0, old_net = -1, jj = 0; + pt_segm != NULL; + pt_segm = (TRACK*) pt_segm->Pnext, ii++, jj-- ) + { + if( pt_segm->Pnext == NULL ) + break; + if( jj == 0 ) + { + jj = 10; + wxYield(); + if( AbortDrc ) + { + AbortDrc = FALSE; break; + } + /* Print stats */ + Line.Printf( wxT( "%d" ), ii ); + Affiche_1_Parametre( this, PRINT_TST_POS, wxT( "Test" ), Line, CYAN ); + } - GRSetDrawMode(DC, GR_OR); - pt_segm->Draw(DrawPanel, DC, RED^LIGHTRED ); - Line.Printf( wxT("%d"),ErrorsDRC_Count); - Affiche_1_Parametre(this, PRINT_TRACK_ERR_POS,wxEmptyString,Line, LIGHTRED); - } - } + if( old_net != pt_segm->m_NetCode ) + { + wxString msg; + jj = 1; + EQUIPOT* equipot = GetEquipot( m_Pcb, pt_segm->m_NetCode ); + if( equipot ) + msg = equipot->m_Netname + wxT( " " ); + else + msg = wxT( "" ); + Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); + old_net = pt_segm->m_NetCode; + } - /* Test zone segments segments */ - if ( TestZone ) - { - m_Pcb->m_NbSegmZone = 0; - for( pt_segm = (TRACK*)m_Pcb->m_Zone; pt_segm != NULL; pt_segm = (TRACK*)pt_segm->Pnext) - m_Pcb->m_NbSegmZone++; - Line.Printf( wxT("%d"),m_Pcb->m_NbSegmZone) ; - Affiche_1_Parametre(this, PRINT_NB_ZONESEGM_POS,_("SegmNb"),Line,RED) ; - Affiche_1_Parametre(this, PRINT_ZONE_ERR_POS,_("Zone Err"), wxT("0"), LIGHTRED); + g_HightLigth_NetCode = pt_segm->m_NetCode; + flag_err_Drc = Drc( this, DC, pt_segm, (TRACK*) pt_segm->Pnext, 1 ); + if( flag_err_Drc == BAD_DRC ) + { + Marqueur = current_marqueur; + current_marqueur = NULL; + if( Marqueur == NULL ) + { + DisplayError( this, wxT( "Test_Drc(): internal err" ) ); + return ErrorsDRC_Count; + } + Marqueur->Pnext = m_Pcb->m_Drawings; + Marqueur->Pback = m_Pcb; - if ( DrcFrame ) DrcFrame->m_logWindow->AppendText( _("Tst Zones\n") ); - - pt_segm = (TRACK*)m_Pcb->m_Zone; - for( ii = 0, old_net = -1, jj = 0; pt_segm != NULL; pt_segm = (TRACK*)pt_segm->Pnext, ii++, jj--) - { - if( pt_segm->Pnext == NULL) break; - if ( jj == 0 ) - { - jj = 100; - wxYield(); - if(AbortDrc) - { - AbortDrc = FALSE; break; - } - /* Print stats */ - Line.Printf( wxT("%d"),ii); - Affiche_1_Parametre(this, PRINT_TST_POS, wxT("Test"),Line,CYAN) ; - } + PtStruct = m_Pcb->m_Drawings; + if( PtStruct ) + PtStruct->Pback = Marqueur; + m_Pcb->m_Drawings = Marqueur; - if ( old_net != pt_segm->m_NetCode) - { - jj = 1; - wxString msg; - EQUIPOT * equipot = GetEquipot(m_Pcb, pt_segm->m_NetCode); - if ( equipot ) msg = equipot->m_Netname + wxT(" "); - else msg = wxT(""); - Affiche_1_Parametre(this, 0,_("Netname"),msg, YELLOW); - old_net = pt_segm->m_NetCode; - } - g_HightLigth_NetCode = pt_segm->m_NetCode; - /* Test drc with other zone segments, and pads */ - flag_err_Drc = Drc(this, DC, pt_segm,(TRACK*)pt_segm->Pnext, 1); - if(flag_err_Drc == BAD_DRC) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError(this, wxT("Test_Drc(): internal err")); - return ErrorsDRC_Count; - } - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; + GRSetDrawMode( DC, GR_OR ); + pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED ); + Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); + Affiche_1_Parametre( this, PRINT_TRACK_ERR_POS, wxEmptyString, Line, LIGHTRED ); + } + } - PtStruct = m_Pcb->m_Drawings; - if(PtStruct) PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; + /* Test zone segments segments */ + if( TestZone ) + { + m_Pcb->m_NbSegmZone = 0; + for( pt_segm = (TRACK*) m_Pcb->m_Zone; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) + m_Pcb->m_NbSegmZone++; - GRSetDrawMode(DC, GR_OR); - pt_segm->Draw(DrawPanel, DC, RED^LIGHTRED ); - Line.Printf( wxT("%d"),ErrorsDRC_Count); - Affiche_1_Parametre(this, PRINT_ZONE_ERR_POS, wxEmptyString, Line, LIGHTRED); - } - - /* Test drc with track segments */ - int tmp = m_Pcb->m_NbPads; m_Pcb->m_NbPads = 0; // Pads already tested: disable pad test - flag_err_Drc = Drc(this, DC, pt_segm, m_Pcb->m_Track, 1); - m_Pcb->m_NbPads = tmp; - if(flag_err_Drc == BAD_DRC) - { - Marqueur = current_marqueur; - current_marqueur = NULL; - if( Marqueur == NULL ) - { - DisplayError(this, wxT("Test_Drc(): internal err")); - return ErrorsDRC_Count; - } - Marqueur->Pnext = m_Pcb->m_Drawings; - Marqueur->Pback = m_Pcb; + Line.Printf( wxT( "%d" ), m_Pcb->m_NbSegmZone ); + Affiche_1_Parametre( this, PRINT_NB_ZONESEGM_POS, _( "SegmNb" ), Line, RED ); + Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, _( "Zone Err" ), wxT( "0" ), LIGHTRED ); - PtStruct = m_Pcb->m_Drawings; - if(PtStruct) PtStruct->Pback = Marqueur; - m_Pcb->m_Drawings = Marqueur; + if( DrcFrame ) + DrcFrame->m_logWindow->AppendText( _( "Tst Zones\n" ) ); - GRSetDrawMode(DC, GR_OR); - pt_segm->Draw(DrawPanel, DC, RED^LIGHTRED ); - Line.Printf( wxT("%d"),ErrorsDRC_Count); - Affiche_1_Parametre(this, PRINT_ZONE_ERR_POS, wxEmptyString, Line, LIGHTRED); - } - } - } + pt_segm = (TRACK*) m_Pcb->m_Zone; + for( ii = 0, old_net = -1, jj = 0; + pt_segm != NULL; + pt_segm = (TRACK*) pt_segm->Pnext, ii++, jj-- ) + { + if( pt_segm->Pnext == NULL ) + break; + if( jj == 0 ) + { + jj = 100; + wxYield(); + if( AbortDrc ) + { + AbortDrc = FALSE; break; + } + /* Print stats */ + Line.Printf( wxT( "%d" ), ii ); + Affiche_1_Parametre( this, PRINT_TST_POS, wxT( "Test" ), Line, CYAN ); + } + + if( old_net != pt_segm->m_NetCode ) + { + jj = 1; + wxString msg; + EQUIPOT* equipot = GetEquipot( m_Pcb, pt_segm->m_NetCode ); + if( equipot ) + msg = equipot->m_Netname + wxT( " " ); + else + msg = wxT( "" ); + Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); + old_net = pt_segm->m_NetCode; + } + g_HightLigth_NetCode = pt_segm->m_NetCode; + /* Test drc with other zone segments, and pads */ + flag_err_Drc = Drc( this, DC, pt_segm, (TRACK*) pt_segm->Pnext, 1 ); + if( flag_err_Drc == BAD_DRC ) + { + Marqueur = current_marqueur; + current_marqueur = NULL; + if( Marqueur == NULL ) + { + DisplayError( this, wxT( "Test_Drc(): internal err" ) ); + return ErrorsDRC_Count; + } + Marqueur->Pnext = m_Pcb->m_Drawings; + Marqueur->Pback = m_Pcb; + + PtStruct = m_Pcb->m_Drawings; + if( PtStruct ) + PtStruct->Pback = Marqueur; + m_Pcb->m_Drawings = Marqueur; + + GRSetDrawMode( DC, GR_OR ); + pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED ); + Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); + Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, wxEmptyString, Line, LIGHTRED ); + } + + /* Test drc with track segments */ + int tmp = m_Pcb->m_NbPads; m_Pcb->m_NbPads = 0; // Pads already tested: disable pad test + flag_err_Drc = Drc( this, DC, pt_segm, m_Pcb->m_Track, 1 ); + + m_Pcb->m_NbPads = tmp; + + if( flag_err_Drc == BAD_DRC ) + { + Marqueur = current_marqueur; + current_marqueur = NULL; + if( Marqueur == NULL ) + { + DisplayError( this, wxT( "Test_Drc(): internal err" ) ); + return ErrorsDRC_Count; + } + Marqueur->Pnext = m_Pcb->m_Drawings; + Marqueur->Pback = m_Pcb; + + PtStruct = m_Pcb->m_Drawings; + if( PtStruct ) + PtStruct->Pback = Marqueur; + m_Pcb->m_Drawings = Marqueur; + + GRSetDrawMode( DC, GR_OR ); + pt_segm->Draw( DrawPanel, DC, RED ^ LIGHTRED ); + Line.Printf( wxT( "%d" ), ErrorsDRC_Count ); + Affiche_1_Parametre( this, PRINT_ZONE_ERR_POS, wxEmptyString, Line, LIGHTRED ); + } + } + } - AbortDrc = FALSE; - DrcInProgress = FALSE; - return ErrorsDRC_Count; + AbortDrc = FALSE; + DrcInProgress = FALSE; + return ErrorsDRC_Count; } /***********************************************************************/ -int Drc(WinEDA_BasePcbFrame *frame, wxDC * DC, - TRACK * pt_segment, TRACK * StartBuffer, int show_err) +int Drc( WinEDA_BasePcbFrame* frame, wxDC* DC, + TRACK* pt_segment, TRACK* StartBuffer, int show_err ) /***********************************************************************/ + /* -Teste le segment en cours de trace: - pt_segment = pointeur sur segment a controler - StartBuffer = adresse de la zone des pistes a controler - (typiquement m_Pcb->m_Track) - show_err (flag) si 0 pas d'affichage d'erreur sur ecran - retourne : - BAD_DRC (1) si Violation DRC - OK_DRC (0) si OK -*/ + * Teste le segment en cours de trace: + * pt_segment = pointeur sur segment a controler + * StartBuffer = adresse de la zone des pistes a controler + * (typiquement m_Pcb->m_Track) + * show_err (flag) si 0 pas d'affichage d'erreur sur ecran + * retourne : + * BAD_DRC (1) si Violation DRC + * OK_DRC (0) si OK + */ { -int ii ; -TRACK * pttrack; -int x0,y0,xf,yf ; // coord des extremites du segment teste dans le repere modifie -int dx, dy; // utilise pour calcul des dim x et dim y des segments -int w_dist; -int MaskLayer ; -int net_code_ref; -int org_X, org_Y; // Origine sur le PCB des axes du repere centre sur - // l'origine du segment de reference -wxPoint shape_pos; + int ii; + TRACK* pttrack; + int x0, y0, xf, yf; // coord des extremites du segment teste dans le repere modifie + int dx, dy; // utilise pour calcul des dim x et dim y des segments + int w_dist; + int MaskLayer; + int net_code_ref; + int org_X, org_Y; // Origine sur le PCB des axes du repere centre sur + // l'origine du segment de reference + wxPoint shape_pos; - org_X = pt_segment->m_Start.x; org_Y = pt_segment->m_Start.y ; - finx = dx = pt_segment->m_End.x - org_X ; - finy = dy = pt_segment->m_End.y - org_Y ; - MaskLayer = pt_segment->ReturnMaskLayer(); - net_code_ref = pt_segment->m_NetCode; + org_X = pt_segment->m_Start.x; org_Y = pt_segment->m_Start.y; + finx = dx = pt_segment->m_End.x - org_X; + finy = dy = pt_segment->m_End.y - org_Y; + MaskLayer = pt_segment->ReturnMaskLayer(); + net_code_ref = pt_segment->m_NetCode; - segm_angle = 0; - if( dx || dy) - { - /* calcul de l'angle d'inclinaison en 0,1 degre */ - segm_angle = ArcTangente(dy,dx); - /* Calcul de la longueur du segment en segm_long : dx = longueur */ - RotatePoint(&dx, &dy, segm_angle); /* segm_long = longueur, yf = 0 */ - } + segm_angle = 0; + if( dx || dy ) + { + /* calcul de l'angle d'inclinaison en 0,1 degre */ + segm_angle = ArcTangente( dy, dx ); + /* Calcul de la longueur du segment en segm_long : dx = longueur */ + RotatePoint( &dx, &dy, segm_angle ); /* segm_long = longueur, yf = 0 */ + } - /* Ici le segment a ete tourne de segm_angle, et est horizontal, dx > 0 */ - segm_long = dx; + /* Ici le segment a ete tourne de segm_angle, et est horizontal, dx > 0 */ + segm_long = dx; - /******************************************/ - /* Phase 1 : test DRC track to pads :*/ - /******************************************/ + /******************************************/ + /* Phase 1 : test DRC track to pads :*/ + /******************************************/ - /* calcul de la distance min aux pads : */ - w_dist = (unsigned)(pt_segment->m_Width >> 1 ) ; - for ( ii = 0 ; ii < frame->m_Pcb->m_NbPads ; ii++) - { - D_PAD * pt_pad = frame->m_Pcb->m_Pads[ii]; + /* calcul de la distance min aux pads : */ + w_dist = (unsigned) (pt_segment->m_Width >> 1 ); + for( ii = 0; ii < frame->m_Pcb->m_NbPads; ii++ ) + { + D_PAD* pt_pad = frame->m_Pcb->m_Pads[ii]; - /* Pas de probleme si les pads sont en surface autre que la couche, - sauf si le trou de percage gene (cas des pastilles percées simple - face sur CI double face */ - if( (pt_pad->m_Masque_Layer & MaskLayer ) == 0 ) - { - /* We must test the pad hole. In order to use the function "TestClearanceSegmToPad", - a pseudo pad is used, with a shape and a size like the hole */ - if ( pt_pad->m_Drill.x == 0 ) continue; - D_PAD pseudo_pad((MODULE*)NULL); - pseudo_pad.m_Size = pt_pad->m_Drill; - pseudo_pad.m_Pos = pt_pad->m_Pos; - pseudo_pad.m_PadShape = pt_pad->m_DrillShape; - pseudo_pad.m_Orient = pt_pad->m_Orient; - pseudo_pad.ComputeRayon(); - spot_cX = pseudo_pad.m_Pos.x - org_X; - spot_cY = pseudo_pad.m_Pos.y - org_Y; - if( TestClearanceSegmToPad(&pseudo_pad, w_dist, g_DesignSettings.m_TrackClearence) != OK_DRC ) - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC(frame->DrawPanel, DC, - frame->m_Pcb, pt_segment,pt_pad,0); - return(BAD_DRC); - } - continue; - } + /* Pas de probleme si les pads sont en surface autre que la couche, + * sauf si le trou de percage gene (cas des pastilles percďż˝s simple + * face sur CI double face */ + if( (pt_pad->m_Masque_Layer & MaskLayer ) == 0 ) + { + /* We must test the pad hole. In order to use the function "TestClearanceSegmToPad", + * a pseudo pad is used, with a shape and a size like the hole */ + if( pt_pad->m_Drill.x == 0 ) + continue; + D_PAD pseudo_pad( (MODULE*) NULL ); - /* Le pad doit faire partie d'un net mais pas de probleme - si le pad est du meme net */ - if( pt_pad->m_NetCode && (net_code_ref == pt_pad->m_NetCode) ) - continue ; + pseudo_pad.m_Size = pt_pad->m_Drill; + pseudo_pad.m_Pos = pt_pad->m_Pos; + pseudo_pad.m_PadShape = pt_pad->m_DrillShape; + pseudo_pad.m_Orient = pt_pad->m_Orient; + pseudo_pad.ComputeRayon(); + spot_cX = pseudo_pad.m_Pos.x - org_X; + spot_cY = pseudo_pad.m_Pos.y - org_Y; + if( TestClearanceSegmToPad( &pseudo_pad, w_dist, + g_DesignSettings.m_TrackClearence ) != OK_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, + frame->m_Pcb, pt_segment, pt_pad, 0 ); + return BAD_DRC; + } + continue; + } - /* Test DRC pour les pads */ + /* Le pad doit faire partie d'un net mais pas de probleme + * si le pad est du meme net */ + if( pt_pad->m_NetCode && (net_code_ref == pt_pad->m_NetCode) ) + continue; + + /* Test DRC pour les pads */ shape_pos = pt_pad->ReturnShapePos(); - spot_cX = shape_pos.x - org_X; - spot_cY = shape_pos.y - org_Y; - if( TestClearanceSegmToPad(pt_pad, w_dist, g_DesignSettings.m_TrackClearence) == OK_DRC ) continue ; + spot_cX = shape_pos.x - org_X; + spot_cY = shape_pos.y - org_Y; + if( TestClearanceSegmToPad( pt_pad, w_dist, g_DesignSettings.m_TrackClearence ) == OK_DRC ) + continue; - /* extremite sur pad ou defaut d'isolation trouve */ - else - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC(frame->DrawPanel, DC, - frame->m_Pcb, pt_segment,pt_pad,1); - return(BAD_DRC); - } - } + /* extremite sur pad ou defaut d'isolation trouve */ + else + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, + frame->m_Pcb, pt_segment, pt_pad, 1 ); + return BAD_DRC; + } + } - /**********************************************/ - /* Phase 2 : test DRC avec les autres pistes :*/ - /**********************************************/ + /**********************************************/ + /* Phase 2 : test DRC avec les autres pistes :*/ + /**********************************************/ - /* Ici le segment de reference est sur l'axe X */ + /* Ici le segment de reference est sur l'axe X */ - /* Comparaison du segment de reference aux autres segments de piste */ - pttrack = StartBuffer ; - for ( ;pttrack != NULL ; pttrack = (TRACK*) pttrack->Pnext ) - { - //pas de probleme si le segment a tester est du meme net: - if( net_code_ref == pttrack->m_NetCode ) continue ; - //pas de probleme si le segment a tester est sur une autre couche : - if( (MaskLayer & pttrack->ReturnMaskLayer() ) == 0 ) continue ; + /* Comparaison du segment de reference aux autres segments de piste */ + pttrack = StartBuffer; + for( ; pttrack != NULL; pttrack = (TRACK*) pttrack->Pnext ) + { + //pas de probleme si le segment a tester est du meme net: + if( net_code_ref == pttrack->m_NetCode ) + continue; - /* calcul de la Distance mini = Isol+ rayon ou demi largeur seg ref - + rayon ou demi largeur seg a comparer */ - w_dist = pt_segment->m_Width >> 1; - w_dist += pttrack->m_Width >> 1; - w_dist += g_DesignSettings.m_TrackClearence; + //pas de probleme si le segment a tester est sur une autre couche : + if( ( MaskLayer & pttrack->ReturnMaskLayer() ) == 0 ) + continue; - /* si le segment de reference est une via, le traitement est ici */ - if ( pt_segment->m_StructType == TYPEVIA ) - { - int orgx, orgy; // origine du repere d'axe X = segment a comparer - int angle = 0; // angle du segment a tester; - orgx = pttrack->m_Start.x; orgy = pttrack->m_Start.y; - dx = pttrack->m_End.x - orgx ; dy = pttrack->m_End.y - orgy; - x0 = pt_segment->m_Start.x - orgx ; y0 = pt_segment->m_Start.y - orgy ; + /* calcul de la Distance mini = Isol+ rayon ou demi largeur seg ref + + rayon ou demi largeur seg a comparer */ + w_dist = pt_segment->m_Width >> 1; + w_dist += pttrack->m_Width >> 1; + w_dist += g_DesignSettings.m_TrackClearence; - if( pttrack->m_StructType == TYPEVIA) /* Tst distance entre 2 vias */ - { - if( (int)hypot((float)x0,(float)y0) < w_dist ) - { - ErrorsDRC_Count++; - if( show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,21); - return(BAD_DRC) ; - } - } - else /* Tst distance de via a segment */ - { - /* calcul de l'angle */ - angle = ArcTangente(dy,dx); + /* si le segment de reference est une via, le traitement est ici */ + if( pt_segment->m_StructType == TYPEVIA ) + { + int orgx, orgy; // origine du repere d'axe X = segment a comparer + int angle = 0; // angle du segment a tester; + orgx = pttrack->m_Start.x; orgy = pttrack->m_Start.y; + dx = pttrack->m_End.x - orgx; dy = pttrack->m_End.y - orgy; + x0 = pt_segment->m_Start.x - orgx; y0 = pt_segment->m_Start.y - orgy; - /* Calcul des coord dans le nouveau repere */ - RotatePoint(&dx, &dy, angle); - RotatePoint(&x0, &y0, angle); + if( pttrack->m_StructType == TYPEVIA ) /* Tst distance entre 2 vias */ + { + if( (int) hypot( (float) x0, (float) y0 ) < w_dist ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 21 ); + return BAD_DRC; + } + } + else /* Tst distance de via a segment */ + { + /* calcul de l'angle */ + angle = ArcTangente( dy, dx ); - if( TestMarginToCircle(x0, y0, w_dist, dx) == BAD_DRC ) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,20); - return(BAD_DRC) ; - } - } - continue; - } + /* Calcul des coord dans le nouveau repere */ + RotatePoint( &dx, &dy, angle ); + RotatePoint( &x0, &y0, angle ); - /* calcule x0,y0, xf,yf = coord de debut et fin du segment de piste - a tester, dans le repere axe X = segment de reference */ - x0 = pttrack->m_Start.x - org_X ; y0 = pttrack->m_Start.y - org_Y ; - xf = pttrack->m_End.x - org_X ; yf = pttrack->m_End.y - org_Y ; + if( TestMarginToCircle( x0, y0, w_dist, dx ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 20 ); + return BAD_DRC; + } + } + continue; + } - RotatePoint(&x0, &y0, segm_angle); RotatePoint(&xf, &yf, segm_angle); + /* calcule x0,y0, xf,yf = coord de debut et fin du segment de piste + * a tester, dans le repere axe X = segment de reference */ + x0 = pttrack->m_Start.x - org_X; y0 = pttrack->m_Start.y - org_Y; + xf = pttrack->m_End.x - org_X; yf = pttrack->m_End.y - org_Y; - if ( pttrack->m_StructType == TYPEVIA ) - { - if( TestMarginToCircle(x0, y0,w_dist,segm_long) == OK_DRC) continue; - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,21); - return(BAD_DRC) ; - } + RotatePoint( &x0, &y0, segm_angle ); RotatePoint( &xf, &yf, segm_angle ); + + if( pttrack->m_StructType == TYPEVIA ) + { + if( TestMarginToCircle( x0, y0, w_dist, segm_long ) == OK_DRC ) + continue; + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 21 ); + return BAD_DRC; + } - /* - le segment de reference est Horizontal, par suite des modifs d'axe. - 3 cas : segment a comparer parallele, perp ou incline - */ - if ( y0 == yf ) // segments paralleles - { - if ( abs(y0) >= w_dist ) continue ; - if ( x0 > xf) EXCHG (x0,xf) ; /* pour que x0 <= xf */ + /* + * le segment de reference est Horizontal, par suite des modifs d'axe. + * 3 cas : segment a comparer parallele, perp ou incline + */ + if( y0 == yf ) // segments paralleles + { + if( abs( y0 ) >= w_dist ) + continue; + if( x0 > xf ) + EXCHG( x0, xf ); /* pour que x0 <= xf */ - if ( x0 > (-w_dist) && x0 < (segm_long + w_dist)) /* Risque de defaut */ - { - /* test fin tenant compte des formes arrondies des extremites */ - if ( x0 >= 0 && x0 <= segm_long ) - { - ErrorsDRC_Count++; - if ( show_err ) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,2); - return(BAD_DRC) ; - } - if( TestMarginToCircle(x0, y0, w_dist,segm_long) == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,2); - return(BAD_DRC) ; - } - } - if ( xf > (-w_dist) && xf < (segm_long + w_dist)) - { - /* test fin tenant compte des formes arrondies des extremites */ - if ( xf >= 0 && xf <= segm_long ) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,3); - return(BAD_DRC) ; - } - if( TestMarginToCircle(xf, yf, w_dist,segm_long) == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,3); - return(BAD_DRC) ; - } - } + if( x0 > (-w_dist) && x0 < (segm_long + w_dist) ) /* Risque de defaut */ + { + /* test fin tenant compte des formes arrondies des extremites */ + if( x0 >= 0 && x0 <= segm_long ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 2 ); + return BAD_DRC; + } + if( TestMarginToCircle( x0, y0, w_dist, segm_long ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 2 ); + return BAD_DRC; + } + } + if( xf > (-w_dist) && xf < (segm_long + w_dist) ) + { + /* test fin tenant compte des formes arrondies des extremites */ + if( xf >= 0 && xf <= segm_long ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 3 ); + return BAD_DRC; + } + if( TestMarginToCircle( xf, yf, w_dist, segm_long ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 3 ); + return BAD_DRC; + } + } - if ( x0 <=0 && xf >= 0 ) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,4); - return(BAD_DRC) ; - } - } + if( x0 <=0 && xf >= 0 ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 4 ); + return BAD_DRC; + } + } + else if( x0 == xf ) // segments perpendiculaires + { + if( ( x0 <= (-w_dist) ) || ( x0 >= (segm_long + w_dist) ) ) + continue; - else if ( x0 == xf ) // segments perpendiculaires - { - if ( (x0 <= (-w_dist)) || (x0 >= (segm_long + w_dist))) continue ; + /* test si les segments se croisent */ + if( y0 > yf ) + EXCHG( y0, yf ); + if( (y0 < 0) && (yf > 0) ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 6 ); + return BAD_DRC; + } - /* test si les segments se croisent */ - if( y0 > yf ) EXCHG(y0, yf); - if( (y0 < 0) && (yf > 0) ) - { - ErrorsDRC_Count++; - if( show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,6); - return(BAD_DRC); - } + /* ici l'erreur est due a une extremite pres d'une extremite du segm + * de reference */ + if( TestMarginToCircle( x0, y0, w_dist, segm_long ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 7 ); + return BAD_DRC; + } + if( TestMarginToCircle( xf, yf, w_dist, segm_long ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pt_segment, pttrack, 8 ); + return BAD_DRC; + } + } + else // segments quelconques entre eux */ + { + int bflag = OK_DRC; + /* calcul de la "surface de securite du segment de reference */ + /* premiere passe : la piste est assimilee a un rectangle */ - /* ici l'erreur est due a une extremite pres d'une extremite du segm - de reference */ - if(TestMarginToCircle(x0,y0,w_dist,segm_long) == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,7); - return(BAD_DRC) ; - } - if(TestMarginToCircle(xf,yf,w_dist,segm_long) == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,8); - return(BAD_DRC) ; - } - } - else // segments quelconques entre eux */ - { - int bflag = OK_DRC; - /* calcul de la "surface de securite du segment de reference */ - /* premiere passe : la piste est assimilee a un rectangle */ + xcliplo = ycliplo = -w_dist; + xcliphi = segm_long + w_dist; ycliphi = w_dist; - xcliplo = ycliplo = -w_dist; - xcliphi = segm_long + w_dist; ycliphi = w_dist; + bflag = Tst_Ligne( x0, y0, xf, yf ); + if( bflag == BAD_DRC ) + { + /* 2eme passe : la piste a des extremites arrondies. + * Si le defaut de drc est du a une extremite : le calcul + * est affine pour tenir compte de cet arrondi */ - bflag = Tst_Ligne(x0,y0,xf,yf); - if (bflag == BAD_DRC) - { - /* 2eme passe : la piste a des extremites arrondies. - Si le defaut de drc est du a une extremite : le calcul - est affine pour tenir compte de cet arrondi */ + xcliplo = 0; xcliphi = segm_long; + bflag = Tst_Ligne( x0, y0, xf, yf ); - xcliplo = 0 ; xcliphi = segm_long ; - bflag = Tst_Ligne(x0,y0,xf,yf) ; + if( bflag == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 9 ); + return BAD_DRC; + } + else // L'erreur est due a une extremite du segment de reference: + { + // il faut tester les extremites de ce segment + int angle, rx0, ry0, rxf, ryf; + x0 = pttrack->m_Start.x; y0 = pttrack->m_Start.y; + xf = pttrack->m_End.x; yf = pttrack->m_End.y; + dx = xf - x0; dy = yf - y0; + /* calcul de l'angle d'inclinaison en 0,1 degre */ + angle = ArcTangente( dy, dx ); + /* Calcul de la longueur du segment: dx = longueur */ + RotatePoint( &dx, &dy, angle ); - if(bflag == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,9); - return(BAD_DRC) ; - } + /* calcul des coord du segment de reference ds le repere + * d'axe X = segment courant en tst */ + rx0 = pt_segment->m_Start.x - x0; + ry0 = pt_segment->m_Start.y - y0; + rxf = pt_segment->m_End.x - x0; + ryf = pt_segment->m_End.y - y0; - else // L'erreur est due a une extremite du segment de reference: - { // il faut tester les extremites de ce segment - int angle, rx0,ry0,rxf,ryf; - x0 = pttrack->m_Start.x; y0 = pttrack->m_Start.y; - xf = pttrack->m_End.x; yf = pttrack->m_End.y; - dx = xf - x0; dy = yf - y0; - /* calcul de l'angle d'inclinaison en 0,1 degre */ - angle = ArcTangente(dy,dx); - /* Calcul de la longueur du segment: dx = longueur */ - RotatePoint(&dx, &dy, angle); + RotatePoint( &rx0, &ry0, angle ); + RotatePoint( &rxf, &ryf, angle ); + if( TestMarginToCircle( rx0, ry0, w_dist, dx ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 10 ); + return BAD_DRC; + } + if( TestMarginToCircle( rxf, ryf, w_dist, dx ) == BAD_DRC ) + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, + DC, + frame->m_Pcb, + pt_segment, + pttrack, + 11 ); + return BAD_DRC; + } + } + } + } + } - /* calcul des coord du segment de reference ds le repere - d'axe X = segment courant en tst */ - rx0 = pt_segment->m_Start.x - x0; - ry0 = pt_segment->m_Start.y - y0; - rxf = pt_segment->m_End.x - x0; - ryf = pt_segment->m_End.y - y0; - - RotatePoint(&rx0,&ry0, angle); - RotatePoint(&rxf,&ryf, angle); - if(TestMarginToCircle(rx0,ry0,w_dist,dx) == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,10); - return(BAD_DRC) ; - } - if(TestMarginToCircle(rxf,ryf,w_dist,dx) == BAD_DRC) - { - ErrorsDRC_Count++; - if(show_err) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pt_segment,pttrack,11); - return(BAD_DRC) ; - } - } - } - } - } - return(OK_DRC) ; + return OK_DRC; } + /*****************************************************************************/ -static bool Test_Pad_to_Pads_Drc(WinEDA_BasePcbFrame *frame, wxDC * DC, D_PAD * pad_ref, - LISTE_PAD * start_buffer, LISTE_PAD * end_buffer, int max_size, bool show_err) +static bool Test_Pad_to_Pads_Drc( WinEDA_BasePcbFrame* frame, + wxDC* DC, + D_PAD* pad_ref, + LISTE_PAD* start_buffer, + LISTE_PAD* end_buffer, + int max_size, + bool show_err ) /*****************************************************************************/ + /* Teste l'isolation de pad_ref avec les autres pads. - end_buffer = upper limit of the pad list. - max_size = size of the biggest pad (used to stop the test when the X distance is > max_size) -*/ + * end_buffer = upper limit of the pad list. + * max_size = size of the biggest pad (used to stop the test when the X distance is > max_size) + */ { -int MaskLayer; -D_PAD * pad; -LISTE_PAD * pad_list = start_buffer; - - MaskLayer = pad_ref->m_Masque_Layer & ALL_CU_LAYERS; - int x_limite = max_size + g_DesignSettings.m_TrackClearence + - pad_ref->m_Rayon + pad_ref->m_Pos.x; - for ( ; pad_list < end_buffer ; pad_list++) - { - pad = * pad_list; - if ( pad == pad_ref ) continue; - - /* We can stop the test when pad->m_Pos.x > x_limite - because the list is sorted by X values */ - if ( pad->m_Pos.x > x_limite ) break; + int MaskLayer; + D_PAD* pad; + LISTE_PAD* pad_list = start_buffer; - /* Pas de probleme si les pads ne sont pas sur les memes couches cuivre*/ - if( (pad->m_Masque_Layer & MaskLayer ) == 0 ) continue; + MaskLayer = pad_ref->m_Masque_Layer & ALL_CU_LAYERS; + int x_limite = max_size + g_DesignSettings.m_TrackClearence + + pad_ref->m_Rayon + pad_ref->m_Pos.x; + for( ; pad_list < end_buffer; pad_list++ ) + { + pad = *pad_list; + if( pad == pad_ref ) + continue; - /* Le pad doit faire partie d'un net, - mais pas de probleme si les pads sont du meme net */ - if( pad->m_NetCode && (pad_ref->m_NetCode == pad->m_NetCode) ) - continue ; + /* We can stop the test when pad->m_Pos.x > x_limite + * because the list is sorted by X values */ + if( pad->m_Pos.x > x_limite ) + break; - /* pas de pb si les pads sont du meme module et - de la meme reference ( pads multiples ) */ - if ( (pad->m_Parent == pad_ref->m_Parent) && (pad->m_NumPadName == pad_ref->m_NumPadName) ) - continue; + /* Pas de probleme si les pads ne sont pas sur les memes couches cuivre*/ + if( (pad->m_Masque_Layer & MaskLayer ) == 0 ) + continue; - if( Pad_to_Pad_Isol(pad_ref, pad, g_DesignSettings.m_TrackClearence) == OK_DRC ) continue ; - else /* defaut d'isolation trouve */ - { - ErrorsDRC_Count++; - if( show_err ) - Affiche_Erreur_DRC(frame->DrawPanel, DC, frame->m_Pcb, pad_ref, pad); - return(BAD_DRC); - } - } - return OK_DRC; + /* Le pad doit faire partie d'un net, + * mais pas de probleme si les pads sont du meme net */ + if( pad->m_NetCode && (pad_ref->m_NetCode == pad->m_NetCode) ) + continue; + + /* pas de pb si les pads sont du meme module et + * de la meme reference ( pads multiples ) */ + if( (pad->m_Parent == pad_ref->m_Parent) && (pad->m_NumPadName == pad_ref->m_NumPadName) ) + continue; + + if( Pad_to_Pad_Isol( pad_ref, pad, g_DesignSettings.m_TrackClearence ) == OK_DRC ) + continue; + else /* defaut d'isolation trouve */ + { + ErrorsDRC_Count++; + if( show_err ) + Affiche_Erreur_DRC( frame->DrawPanel, DC, frame->m_Pcb, pad_ref, pad ); + return BAD_DRC; + } + } + + return OK_DRC; } + /**************************************************************************************/ -static int Pad_to_Pad_Isol(D_PAD * pad_ref, D_PAD * pad, const int dist_min) +static int Pad_to_Pad_Isol( D_PAD* pad_ref, D_PAD* pad, const int dist_min ) /***************************************************************************************/ + /* Return OK_DRC si clearance between pad_ref and pad is >= dist_min - or BAD_DRC if not */ + * or BAD_DRC if not */ { -wxPoint rel_pos; -int dist, diag; -wxPoint shape_pos; -int pad_angle; - - rel_pos = pad->ReturnShapePos(); + wxPoint rel_pos; + int dist, diag; + wxPoint shape_pos; + int pad_angle; + + rel_pos = pad->ReturnShapePos(); shape_pos = pad_ref->ReturnShapePos(); - // rel_pos is pad position relative to the pad_ref position - rel_pos.x -= shape_pos.x; - rel_pos.y -= shape_pos.y; - dist = (int) hypot( (double) rel_pos.x, (double) rel_pos.y); - diag = OK_DRC; + // rel_pos is pad position relative to the pad_ref position + rel_pos.x -= shape_pos.x; + rel_pos.y -= shape_pos.y; + dist = (int) hypot( (double) rel_pos.x, (double) rel_pos.y ); - /* tst rapide: si les cercles exinscrits sont distants de dist_min au moins, - il n'y a pas de risque: */ - if ( (dist - pad_ref->m_Rayon - pad->m_Rayon) >= dist_min ) - return OK_DRC; + diag = OK_DRC; - /* Ici les pads sont proches et les cercles exinxcrits sont trop proches - Selon les formes relatives il peut y avoir ou non erreur */ - - bool swap_pads = false; - if ( (pad_ref->m_PadShape != CIRCLE) && (pad->m_PadShape == CIRCLE) ) - swap_pads = true; - else if ( (pad_ref->m_PadShape != OVALE) && (pad->m_PadShape == OVALE) ) - swap_pads = true; - - if ( swap_pads ) - { - EXCHG (pad_ref, pad); - rel_pos.x = - rel_pos.x; - rel_pos.y = - rel_pos.y; - } - - switch (pad_ref->m_PadShape) - { - case CIRCLE: // pad_ref is like a track segment with a null lenght - segm_long = 0; - segm_angle = 0; - finx = finy = 0; - spot_cX = rel_pos.x; - spot_cY = rel_pos.y; - diag = TestClearanceSegmToPad(pad, pad_ref->m_Rayon, dist_min ); - break; + /* tst rapide: si les cercles exinscrits sont distants de dist_min au moins, + * il n'y a pas de risque: */ + if( (dist - pad_ref->m_Rayon - pad->m_Rayon) >= dist_min ) + return OK_DRC; - case RECT: - RotatePoint(&rel_pos.x, &rel_pos.y, pad_ref->m_Orient); - pad_angle = pad_ref->m_Orient + pad->m_Orient; // pad_angle = pad orient relative to the pad_ref orient - NORMALIZE_ANGLE_POS(pad_angle); - if ( pad->m_PadShape == RECT ) - { - wxSize size = pad->m_Size; - if ( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) || (pad_angle == 2700)) - { - if ( (pad_angle == 900) || (pad_angle == 2700) ) - { - EXCHG(size.x, size.y ); - } - // Test DRC: - diag = BAD_DRC; - rel_pos.x = ABS(rel_pos.x); rel_pos.y = ABS(rel_pos.y); - if ( (rel_pos.x - ((size.x + pad_ref->m_Size.x)/2) ) >= dist_min ) - diag = OK_DRC; - if ( (rel_pos.y - ((size.y + pad_ref->m_Size.y)/2) ) >= dist_min ) - diag = OK_DRC; - } - - else // Any other orient - { /* TODO : any orient ... */ - } - } - break; + /* Ici les pads sont proches et les cercles exinxcrits sont trop proches + * Selon les formes relatives il peut y avoir ou non erreur */ - case OVALE: /* an oval pad is like a track segment */ - { - /* Create and test a track segment with same dimensions */ - int segm_width; - segm_angle = pad_ref->m_Orient; // Segment orient. - if ( pad_ref->m_Size.y < pad_ref->m_Size.x ) /* We suppose the pad is an horizontal oval */ - { - segm_width = pad_ref->m_Size.y; - segm_long = pad_ref->m_Size.x - pad_ref->m_Size.y; - } - else // it was a vertical oval, change to a rotated horizontal one - { - segm_width = pad_ref->m_Size.x; - segm_long = pad_ref->m_Size.y - pad_ref->m_Size.x; - segm_angle += 900; - } - /* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ - int sx = - segm_long /2, sy = 0; // Start point coordinate of the horizontal equivalent segment - RotatePoint(&sx, &sy, segm_angle); // True start point coordinate of the equivalent segment - spot_cX = rel_pos.x + sx; - spot_cY = rel_pos.y + sy; // pad position / segment origin - finx = - sx; - finy = - sy; // end of segment coordinate - diag = TestClearanceSegmToPad(pad, segm_width/2, dist_min); - break; - } + bool swap_pads = false; + if( (pad_ref->m_PadShape != CIRCLE) && (pad->m_PadShape == CIRCLE) ) + swap_pads = true; + else if( (pad_ref->m_PadShape != OVALE) && (pad->m_PadShape == OVALE) ) + swap_pads = true; - default: - /* TODO...*/ - break; - } - return diag; + if( swap_pads ) + { + EXCHG( pad_ref, pad ); + rel_pos.x = -rel_pos.x; + rel_pos.y = -rel_pos.y; + } + + switch( pad_ref->m_PadShape ) + { + case CIRCLE: // pad_ref is like a track segment with a null lenght + segm_long = 0; + segm_angle = 0; + finx = finy = 0; + spot_cX = rel_pos.x; + spot_cY = rel_pos.y; + diag = TestClearanceSegmToPad( pad, pad_ref->m_Rayon, dist_min ); + break; + + case RECT: + RotatePoint( &rel_pos.x, &rel_pos.y, pad_ref->m_Orient ); + pad_angle = pad_ref->m_Orient + pad->m_Orient; // pad_angle = pad orient relative to the pad_ref orient + NORMALIZE_ANGLE_POS( pad_angle ); + if( pad->m_PadShape == RECT ) + { + wxSize size = pad->m_Size; + if( (pad_angle == 0) || (pad_angle == 900) || (pad_angle == 1800) || + (pad_angle == 2700) ) + { + if( (pad_angle == 900) || (pad_angle == 2700) ) + { + EXCHG( size.x, size.y ); + } + + // Test DRC: + diag = BAD_DRC; + rel_pos.x = ABS( rel_pos.x ); rel_pos.y = ABS( rel_pos.y ); + if( ( rel_pos.x - ( (size.x + pad_ref->m_Size.x) / 2 ) ) >= dist_min ) + diag = OK_DRC; + if( ( rel_pos.y - ( (size.y + pad_ref->m_Size.y) / 2 ) ) >= dist_min ) + diag = OK_DRC; + } + else // Any other orient + { + /* TODO : any orient ... */ + } + } + break; + + case OVALE: /* an oval pad is like a track segment */ + { + /* Create and test a track segment with same dimensions */ + int segm_width; + segm_angle = pad_ref->m_Orient; // Segment orient. + if( pad_ref->m_Size.y < pad_ref->m_Size.x ) /* We suppose the pad is an horizontal oval */ + { + segm_width = pad_ref->m_Size.y; + segm_long = pad_ref->m_Size.x - pad_ref->m_Size.y; + } + else // it was a vertical oval, change to a rotated horizontal one + { + segm_width = pad_ref->m_Size.x; + segm_long = pad_ref->m_Size.y - pad_ref->m_Size.x; + segm_angle += 900; + } + /* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ + int sx = -segm_long / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment + RotatePoint( &sx, &sy, segm_angle ); // True start point coordinate of the equivalent segment + spot_cX = rel_pos.x + sx; + spot_cY = rel_pos.y + sy; // pad position / segment origin + finx = -sx; + finy = -sy; // end of segment coordinate + diag = TestClearanceSegmToPad( pad, segm_width / 2, dist_min ); + break; + } + + default: + /* TODO...*/ + break; + } + + return diag; } + /***************************************************************************/ -static int TestClearanceSegmToPad(const D_PAD* pad_to_test, int w_segm, int dist_min) +static int TestClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min ) /****************************************************************************/ + /* - Routine adaptee de la "distance()" (LOCATE.CPP) - teste la distance du pad au segment de droite en cours - - retourne: - 0 si distance >= dist_min - 1 si distance < dist_min - Parametres d'appel: - pad_to_test = pointeur sur le pad a tester - w_segm = demi largeur du segment a tester - dist_min = marge a respecter - - en variables globales - segm_long = longueur du segment en test - segm_angle = angle d'inclinaison du segment; - finx, finy = coord fin du segment / origine - spot_cX, spot_cY = position du pad / origine du segment -*/ + * Routine adaptee de la "distance()" (LOCATE.CPP) + * teste la distance du pad au segment de droite en cours + * + * retourne: + * 0 si distance >= dist_min + * 1 si distance < dist_min + * Parametres d'appel: + * pad_to_test = pointeur sur le pad a tester + * w_segm = demi largeur du segment a tester + * dist_min = marge a respecter + * + * en variables globales + * segm_long = longueur du segment en test + * segm_angle = angle d'inclinaison du segment; + * finx, finy = coord fin du segment / origine + * spot_cX, spot_cY = position du pad / origine du segment + */ { -int p_dimx, p_dimy ; /* demi - dimensions X et Y du pad a controler */ -int bflag; -int orient; -int x0, y0, xf, yf ; -int seuil; -int deltay; + int p_dimx, p_dimy; /* demi - dimensions X et Y du pad a controler */ + int bflag; + int orient; + int x0, y0, xf, yf; + int seuil; + int deltay; - seuil = w_segm + dist_min; - p_dimx = pad_to_test->m_Size.x >> 1 ; - p_dimy = pad_to_test->m_Size.y >> 1 ; + seuil = w_segm + dist_min; + p_dimx = pad_to_test->m_Size.x >> 1; + p_dimy = pad_to_test->m_Size.y >> 1; - if (pad_to_test->m_PadShape == CIRCLE ) - { - /* calcul des coord centre du pad dans le repere axe X confondu - avec le segment en tst */ - RotatePoint(&spot_cX, &spot_cY, segm_angle); - return (TestMarginToCircle(spot_cX, spot_cY, seuil+p_dimx, segm_long)); - } - else - { - /* calcul de la "surface de securite" du pad de reference */ - xcliplo = spot_cX - seuil - p_dimx ; - ycliplo = spot_cY - seuil - p_dimy; - xcliphi = spot_cX + seuil + p_dimx; - ycliphi = spot_cY + seuil + p_dimy; - x0 = y0 = 0 ; xf = finx; yf = finy ; - orient = pad_to_test->m_Orient; - RotatePoint(&x0,&y0,spot_cX, spot_cY, -orient); - RotatePoint(&xf,&yf,spot_cX, spot_cY, -orient); + if( pad_to_test->m_PadShape == CIRCLE ) + { + /* calcul des coord centre du pad dans le repere axe X confondu + * avec le segment en tst */ + RotatePoint( &spot_cX, &spot_cY, segm_angle ); + return TestMarginToCircle( spot_cX, spot_cY, seuil + p_dimx, segm_long ); + } + else + { + /* calcul de la "surface de securite" du pad de reference */ + xcliplo = spot_cX - seuil - p_dimx; + ycliplo = spot_cY - seuil - p_dimy; + xcliphi = spot_cX + seuil + p_dimx; + ycliphi = spot_cY + seuil + p_dimy; + + x0 = y0 = 0; + + xf = finx; + yf = finy; + + orient = pad_to_test->m_Orient; + + RotatePoint( &x0, &y0, spot_cX, spot_cY, -orient ); + RotatePoint( &xf, &yf, spot_cX, spot_cY, -orient ); - bflag = Tst_Ligne(x0,y0,xf,yf) ; + bflag = Tst_Ligne( x0, y0, xf, yf ); - if (bflag == OK_DRC) return (OK_DRC); - /* Erreur DRC : analyse fine de la forme de la pastille */ + if( bflag == OK_DRC ) + return OK_DRC; + /* Erreur DRC : analyse fine de la forme de la pastille */ - switch (pad_to_test->m_PadShape ) - { - default: return(BAD_DRC); + switch( pad_to_test->m_PadShape ) + { + default: + return BAD_DRC; - case OVALE : - /* test de la pastille ovale ramenee au type ovale vertical */ - if (p_dimx > p_dimy) - { - EXCHG(p_dimx,p_dimy); orient += 900; - if(orient >= 3600) orient -=3600; - } - deltay = p_dimy - p_dimx; - /* ici: p_dimx = rayon, - delta = dist centre cercles a centre pad */ + case OVALE: + /* test de la pastille ovale ramenee au type ovale vertical */ + if( p_dimx > p_dimy ) + { + EXCHG( p_dimx, p_dimy ); orient += 900; + if( orient >= 3600 ) + orient -= 3600; + } + deltay = p_dimy - p_dimx; - /* Test du rectangle separant les 2 demi cercles */ - xcliplo = spot_cX - seuil - p_dimx; - ycliplo = spot_cY - w_segm - deltay; - xcliphi = spot_cX + seuil + p_dimx; - ycliphi = spot_cY + w_segm + deltay; + /* ici: p_dimx = rayon, + * delta = dist centre cercles a centre pad */ - bflag = Tst_Ligne(x0,y0,xf,yf); - if (bflag == BAD_DRC) return(BAD_DRC); + /* Test du rectangle separant les 2 demi cercles */ + xcliplo = spot_cX - seuil - p_dimx; + ycliplo = spot_cY - w_segm - deltay; + xcliphi = spot_cX + seuil + p_dimx; + ycliphi = spot_cY + w_segm + deltay; - /* test des 2 cercles */ - x0 = spot_cX; /* x0,y0 = centre du cercle superieur du pad ovale */ - y0 = spot_cY + deltay; - RotatePoint(&x0,&y0, spot_cX, spot_cY, orient); - RotatePoint(&x0,&y0, segm_angle); - bflag = TestMarginToCircle(x0,y0,p_dimx + seuil, segm_long); - if( bflag == BAD_DRC) return(BAD_DRC); + bflag = Tst_Ligne( x0, y0, xf, yf ); + if( bflag == BAD_DRC ) + return BAD_DRC; - x0 = spot_cX; /* x0,y0 = centre du cercle inferieur du pad ovale */ - y0 = spot_cY - deltay; - RotatePoint(&x0,&y0, spot_cX, spot_cY, orient); - RotatePoint(&x0,&y0, segm_angle); - bflag = TestMarginToCircle(x0,y0,p_dimx + seuil, segm_long); - if( bflag == BAD_DRC) return(BAD_DRC); - break; + /* test des 2 cercles */ + x0 = spot_cX; /* x0,y0 = centre du cercle superieur du pad ovale */ + y0 = spot_cY + deltay; + RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); + RotatePoint( &x0, &y0, segm_angle ); + bflag = TestMarginToCircle( x0, y0, p_dimx + seuil, segm_long ); + if( bflag == BAD_DRC ) + return BAD_DRC; - case RECT: /* 2 rectangle + 4 1/4 cercles a tester */ - /* Test du rectangle dimx + seuil, dimy */ - xcliplo = spot_cX - p_dimx - seuil; - ycliplo = spot_cY - p_dimy; - xcliphi = spot_cX + p_dimx + seuil; - ycliphi = spot_cY + p_dimy; + x0 = spot_cX; /* x0,y0 = centre du cercle inferieur du pad ovale */ + y0 = spot_cY - deltay; + RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); + RotatePoint( &x0, &y0, segm_angle ); + bflag = TestMarginToCircle( x0, y0, p_dimx + seuil, segm_long ); + if( bflag == BAD_DRC ) + return BAD_DRC; + break; - bflag = Tst_Ligne(x0,y0,xf,yf); - if (bflag == BAD_DRC) - { - return(BAD_DRC); - } + case RECT: /* 2 rectangle + 4 1/4 cercles a tester */ + /* Test du rectangle dimx + seuil, dimy */ + xcliplo = spot_cX - p_dimx - seuil; + ycliplo = spot_cY - p_dimy; + xcliphi = spot_cX + p_dimx + seuil; + ycliphi = spot_cY + p_dimy; - /* Test du rectangle dimx , dimy + seuil */ - xcliplo = spot_cX - p_dimx; - ycliplo = spot_cY - p_dimy - seuil; - xcliphi = spot_cX + p_dimx; - ycliphi = spot_cY + p_dimy + seuil; + bflag = Tst_Ligne( x0, y0, xf, yf ); + if( bflag == BAD_DRC ) + { + return BAD_DRC; + } - bflag = Tst_Ligne(x0,y0,xf,yf); - if (bflag == BAD_DRC) - { - return(BAD_DRC); - } + /* Test du rectangle dimx , dimy + seuil */ + xcliplo = spot_cX - p_dimx; + ycliplo = spot_cY - p_dimy - seuil; + xcliphi = spot_cX + p_dimx; + ycliphi = spot_cY + p_dimy + seuil; - /* test des 4 cercles ( surface d'solation autour des sommets */ - /* test du coin sup. gauche du pad */ - x0 = spot_cX - p_dimx; - y0 = spot_cY - p_dimy; - RotatePoint(&x0,&y0, spot_cX, spot_cY, orient); - RotatePoint(&x0,&y0, segm_angle); - bflag = TestMarginToCircle(x0, y0, seuil, segm_long); - if( bflag == BAD_DRC) - { - return(BAD_DRC); - } + bflag = Tst_Ligne( x0, y0, xf, yf ); + if( bflag == BAD_DRC ) + { + return BAD_DRC; + } - /* test du coin sup. droit du pad */ - x0 = spot_cX + p_dimx; - y0 = spot_cY - p_dimy; - RotatePoint(&x0,&y0, spot_cX, spot_cY, orient); - RotatePoint(&x0,&y0, segm_angle); - bflag = TestMarginToCircle(x0, y0, seuil, segm_long); - if( bflag == BAD_DRC) - { - return(BAD_DRC); - } + /* test des 4 cercles ( surface d'solation autour des sommets */ + /* test du coin sup. gauche du pad */ + x0 = spot_cX - p_dimx; + y0 = spot_cY - p_dimy; + RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); + RotatePoint( &x0, &y0, segm_angle ); + bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); + if( bflag == BAD_DRC ) + { + return BAD_DRC; + } - /* test du coin inf. gauche du pad */ - x0 = spot_cX - p_dimx; - y0 = spot_cY + p_dimy; - RotatePoint(&x0,&y0, spot_cX, spot_cY, orient); - RotatePoint(&x0,&y0, segm_angle); - bflag = TestMarginToCircle(x0, y0, seuil, segm_long); - if( bflag == BAD_DRC) - { - return(BAD_DRC); - } + /* test du coin sup. droit du pad */ + x0 = spot_cX + p_dimx; + y0 = spot_cY - p_dimy; + RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); + RotatePoint( &x0, &y0, segm_angle ); + bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); + if( bflag == BAD_DRC ) + { + return BAD_DRC; + } - /* test du coin inf. droit du pad */ - x0 = spot_cX + p_dimx; - y0 = spot_cY + p_dimy; - RotatePoint(&x0,&y0, spot_cX, spot_cY, orient); - RotatePoint(&x0,&y0, segm_angle); - bflag = TestMarginToCircle(x0, y0, seuil, segm_long); - if( bflag == BAD_DRC) - { - return(BAD_DRC); - } + /* test du coin inf. gauche du pad */ + x0 = spot_cX - p_dimx; + y0 = spot_cY + p_dimy; + RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); + RotatePoint( &x0, &y0, segm_angle ); + bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); + if( bflag == BAD_DRC ) + { + return BAD_DRC; + } - break; + /* test du coin inf. droit du pad */ + x0 = spot_cX + p_dimx; + y0 = spot_cY + p_dimy; + RotatePoint( &x0, &y0, spot_cX, spot_cY, orient ); + RotatePoint( &x0, &y0, segm_angle ); + bflag = TestMarginToCircle( x0, y0, seuil, segm_long ); + if( bflag == BAD_DRC ) + { + return BAD_DRC; + } - } - } - return(OK_DRC) ; + break; + } + } + return OK_DRC; } + /*******************************************************************/ -static int TestMarginToCircle(int cx, int cy, int rayon, int longueur ) +static int TestMarginToCircle( int cx, int cy, int rayon, int longueur ) /*******************************************************************/ + /* - Routine analogue a TestClearanceSegmToPad. - Calcul de la distance d'un cercle (via ronde, extremite de piste) - au segment de droite en cours de controle (segment de reference dans - son repere ) - parametres: - cx, cy: centre du cercle (surface ronde) a tester, dans le repere - segment de reference - rayon = rayon du cercle - longueur = longueur du segment dans son repere (i.e. coord de fin) - retourne: - OK_DRC si distance >= rayon - BAD_DRC si distance < rayon -*/ + * Routine analogue a TestClearanceSegmToPad. + * Calcul de la distance d'un cercle (via ronde, extremite de piste) + * au segment de droite en cours de controle (segment de reference dans + * son repere ) + * parametres: + * cx, cy: centre du cercle (surface ronde) a tester, dans le repere + * segment de reference + * rayon = rayon du cercle + * longueur = longueur du segment dans son repere (i.e. coord de fin) + * retourne: + * OK_DRC si distance >= rayon + * BAD_DRC si distance < rayon + */ { - if ( abs(cy) > rayon) return(OK_DRC); + if( abs( cy ) > rayon ) + return OK_DRC; - if ( (cx >= -rayon ) && (cx <= (longueur+rayon) ) ) - { - if( (cx >= 0) && (cx <= longueur) ) return(BAD_DRC) ; - if( cx > longueur) cx -= longueur ; - if( hypot((double)cx, (double)cy) < rayon ) return(BAD_DRC); - } + if( (cx >= -rayon ) && ( cx <= (longueur + rayon) ) ) + { + if( (cx >= 0) && (cx <= longueur) ) + return BAD_DRC; + if( cx > longueur ) + cx -= longueur; + if( hypot( (double) cx, (double) cy ) < rayon ) + return BAD_DRC; + } - return(OK_DRC) ; + return OK_DRC; } /******************************************************************************/ -static void Affiche_Erreur_DRC(WinEDA_DrawPanel * panel, wxDC * DC, BOARD * Pcb, - TRACK * pt_ref, void * pt_item, int errnumber) +static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, + TRACK* pt_ref, void* pt_item, int errnumber ) /******************************************************************************/ /* affiche les erreurs de DRC : - Message d'erreur - + - Marqueur - number = numero d'identification -*/ + * Message d'erreur + + + * Marqueur + * number = numero d'identification + */ { -wxPoint erc_pos; -TRACK * pt_segm; -wxString msg; -wxString tracktype, netname1, netname2; -EQUIPOT * equipot = GetEquipot(Pcb, pt_ref->m_NetCode); - if ( equipot ) netname1 = equipot->m_Netname; - else netname1 = wxT(""); - netname2 = wxT(""); + wxPoint erc_pos; + TRACK* pt_segm; + wxString msg; + wxString tracktype, netname1, netname2; + EQUIPOT* equipot = GetEquipot( Pcb, pt_ref->m_NetCode ); - tracktype = wxT("Track"); - if ( pt_ref->m_StructType == TYPEVIA ) tracktype = wxT("Via"); - if ( pt_ref->m_StructType == TYPEZONE ) tracktype = wxT("Zone"); + if( equipot ) + netname1 = equipot->m_Netname; + else + netname1 = wxT( "" ); + netname2 = wxT( "" ); + + tracktype = wxT( "Track" ); + if( pt_ref->m_StructType == TYPEVIA ) + tracktype = wxT( "Via" ); + if( pt_ref->m_StructType == TYPEZONE ) + tracktype = wxT( "Zone" ); - if( ((EDA_BaseStruct*)pt_item)->m_StructType == TYPEPAD ) - { - D_PAD * pad = (D_PAD*) pt_item; - equipot = GetEquipot(Pcb, pad->m_NetCode); - if ( equipot ) netname2 = equipot->m_Netname; - erc_pos = pad->m_Pos; - wxString pad_name = pad->ReturnStringPadName(); - wxString module_name = ((MODULE*)(pad->m_Parent))->m_Reference->m_Text; - msg.Printf(_("%d Drc Err %d %s (net %s)and PAD %s (%s) net %s @ %d,%d\n"), - ErrorsDRC_Count, errnumber, tracktype.GetData(), - netname1.GetData(), - pad_name.GetData(), module_name.GetData(), - netname2.GetData(), - erc_pos.x, erc_pos.y); - } - else /* erreur sur segment de piste */ - { - pt_segm = (TRACK *) pt_item; - equipot = GetEquipot(Pcb, pt_segm->m_NetCode); - if ( equipot ) netname2 = equipot->m_Netname; - erc_pos = pt_segm->m_Start; - if(pt_segm->m_StructType == TYPEVIA) - { - msg.Printf(_("%d Err type %d: %s (net %s) and VIA (net %s) @ %d,%d\n"), - ErrorsDRC_Count, errnumber, tracktype.GetData(), - netname1.GetData(), netname2.GetData(), - erc_pos.x,erc_pos.y); - } - else - { - wxPoint erc_pos_f = pt_segm->m_End; - if(hypot( (double)(erc_pos_f.x - pt_ref->m_End.x),(double)(erc_pos_f.y - pt_ref->m_End.y) ) - < hypot( (double)(erc_pos.x - pt_ref->m_End.x),(double)(erc_pos.y - pt_ref->m_End.y) ) ) - { - EXCHG(erc_pos_f.x, erc_pos.x); EXCHG(erc_pos_f.y, erc_pos.y); - } - msg.Printf(_("%d Err type %d: %s (net %s) and track (net %s) @ %d,%d\n"), - ErrorsDRC_Count, errnumber, tracktype.GetData(), - netname1.GetData(), netname2.GetData(), - erc_pos.x,erc_pos.y); - } - } + if( ( (EDA_BaseStruct*) pt_item )->m_StructType == TYPEPAD ) + { + D_PAD* pad = (D_PAD*) pt_item; + equipot = GetEquipot( Pcb, pad->m_NetCode ); + if( equipot ) + netname2 = equipot->m_Netname; + erc_pos = pad->m_Pos; + wxString pad_name = pad->ReturnStringPadName(); + wxString module_name = ( (MODULE*) (pad->m_Parent) )->m_Reference->m_Text; + msg.Printf( _( "%d Drc Err %d %s (net %s)and PAD %s (%s) net %s @ %d,%d\n" ), + ErrorsDRC_Count, errnumber, tracktype.GetData(), + netname1.GetData(), + pad_name.GetData(), module_name.GetData(), + netname2.GetData(), + erc_pos.x, erc_pos.y ); + } + else /* erreur sur segment de piste */ + { + pt_segm = (TRACK*) pt_item; + equipot = GetEquipot( Pcb, pt_segm->m_NetCode ); + if( equipot ) + netname2 = equipot->m_Netname; + erc_pos = pt_segm->m_Start; + if( pt_segm->m_StructType == TYPEVIA ) + { + msg.Printf( _( "%d Err type %d: %s (net %s) and VIA (net %s) @ %d,%d\n" ), + ErrorsDRC_Count, errnumber, tracktype.GetData(), + netname1.GetData(), netname2.GetData(), + erc_pos.x, erc_pos.y ); + } + else + { + wxPoint erc_pos_f = pt_segm->m_End; + if( hypot( (double) (erc_pos_f.x - pt_ref->m_End.x), + (double) (erc_pos_f.y - pt_ref->m_End.y) ) + < hypot( (double) (erc_pos.x - pt_ref->m_End.x), + (double) (erc_pos.y - pt_ref->m_End.y) ) ) + { + EXCHG( erc_pos_f.x, erc_pos.x ); EXCHG( erc_pos_f.y, erc_pos.y ); + } + msg.Printf( _( "%d Err type %d: %s (net %s) and track (net %s) @ %d,%d\n" ), + ErrorsDRC_Count, errnumber, tracktype.GetData(), + netname1.GetData(), netname2.GetData(), + erc_pos.x, erc_pos.y ); + } + } - if ( DrcFrame ) DrcFrame->m_logWindow->AppendText(msg); - else panel->m_Parent->Affiche_Message(msg); - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); + if( DrcFrame ) + DrcFrame->m_logWindow->AppendText( msg ); + else + panel->m_Parent->Affiche_Message( msg ); + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); - if(current_marqueur == NULL) current_marqueur = new MARQUEUR(Pcb); - current_marqueur->m_Pos = wxPoint(erc_pos.x, erc_pos.y); - current_marqueur->m_Color = WHITE; - current_marqueur->m_Diag = msg; - current_marqueur->Draw(panel, DC, GR_OR); + if( current_marqueur == NULL ) + current_marqueur = new MARQUEUR( Pcb ); + current_marqueur->m_Pos = wxPoint( erc_pos.x, erc_pos.y ); + current_marqueur->m_Color = WHITE; + current_marqueur->m_Diag = msg; + current_marqueur->Draw( panel, DC, GR_OR ); } /******************************************************************************/ -static void Affiche_Erreur_DRC(WinEDA_DrawPanel * panel, wxDC * DC, BOARD * Pcb, - D_PAD * pad1, D_PAD * pad2) +static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, + D_PAD* pad1, D_PAD* pad2 ) /******************************************************************************/ /* affiche les erreurs de DRC : - Message d'erreur - + - Marqueur - number = numero d'identification -*/ + * Message d'erreur + + + * Marqueur + * number = numero d'identification + */ { -wxString msg; + wxString msg; - wxString pad_name1 = pad1->ReturnStringPadName(); - wxString module_name1 = ((MODULE*)(pad1->m_Parent))->m_Reference->m_Text; - wxString pad_name2 = pad2->ReturnStringPadName(); - wxString module_name2 = ((MODULE*)(pad2->m_Parent))->m_Reference->m_Text; - wxString netname1, netname2; - EQUIPOT * equipot = GetEquipot(Pcb, pad1->m_NetCode); - if ( equipot ) netname1 = equipot->m_Netname; - else netname1 = wxT(""); - equipot = GetEquipot(Pcb, pad2->m_NetCode); - if ( equipot ) netname2 = equipot->m_Netname; - else netname2 = wxT(""); + wxString pad_name1 = pad1->ReturnStringPadName(); + wxString module_name1 = ( (MODULE*) (pad1->m_Parent) )->m_Reference->m_Text; + wxString pad_name2 = pad2->ReturnStringPadName(); + wxString module_name2 = ( (MODULE*) (pad2->m_Parent) )->m_Reference->m_Text; + wxString netname1, netname2; + EQUIPOT* equipot = GetEquipot( Pcb, pad1->m_NetCode ); - msg.Printf( _("%d Drc Err: PAD %s (%s) net %s @ %d,%d and PAD %s (%s) net %s @ %d,%d\n"), - ErrorsDRC_Count, pad_name1.GetData(), module_name1.GetData(), - netname1.GetData(), pad1->m_Pos.x,pad1->m_Pos.y, - pad_name2.GetData(), module_name2.GetData(), - netname2.GetData(), pad2->m_Pos.x, pad2->m_Pos.y); - if ( DrcFrame ) DrcFrame->m_logWindow->AppendText(msg); - else panel->m_Parent->Affiche_Message(msg); - if ( s_RptFile ) fprintf(s_RptFile, "%s", CONV_TO_UTF8(msg) ); + if( equipot ) + netname1 = equipot->m_Netname; + else + netname1 = wxT( "" ); + equipot = GetEquipot( Pcb, pad2->m_NetCode ); + if( equipot ) + netname2 = equipot->m_Netname; + else + netname2 = wxT( "" ); - if(current_marqueur == NULL) current_marqueur = new MARQUEUR(Pcb); - current_marqueur->m_Pos = pad1->m_Pos; - current_marqueur->m_Color = WHITE; - current_marqueur->m_Diag = msg; - current_marqueur->Draw(panel, DC, GR_OR); + msg.Printf( _( "%d Drc Err: PAD %s (%s) net %s @ %d,%d and PAD %s (%s) net %s @ %d,%d\n" ), + ErrorsDRC_Count, pad_name1.GetData(), module_name1.GetData(), + netname1.GetData(), pad1->m_Pos.x, pad1->m_Pos.y, + pad_name2.GetData(), module_name2.GetData(), + netname2.GetData(), pad2->m_Pos.x, pad2->m_Pos.y ); + if( DrcFrame ) + DrcFrame->m_logWindow->AppendText( msg ); + else + panel->m_Parent->Affiche_Message( msg ); + if( s_RptFile ) + fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); + + if( current_marqueur == NULL ) + current_marqueur = new MARQUEUR( Pcb ); + current_marqueur->m_Pos = pad1->m_Pos; + current_marqueur->m_Color = WHITE; + current_marqueur->m_Diag = msg; + current_marqueur->Draw( panel, DC, GR_OR ); } - /**********************************************/ - /* int Tst_Ligne(int x1,int y1,int x2,int y2) */ - /**********************************************/ +/**********************************************/ +/* int Tst_Ligne(int x1,int y1,int x2,int y2) */ +/**********************************************/ /* Routine utilisee pour tester si une piste est en contact avec une autre piste. - - Cette routine controle si la ligne (x1,y1 x2,y2) a une partie s'inscrivant - dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales, - locales a ce fichier) - - Retourne OK_DRC si aucune partie commune - Retourne BAD_DRC si partie commune -*/ + * + * Cette routine controle si la ligne (x1,y1 x2,y2) a une partie s'inscrivant + * dans le cadre (xcliplo,ycliplo xcliphi,ycliphi) (variables globales, + * locales a ce fichier) + * + * Retourne OK_DRC si aucune partie commune + * Retourne BAD_DRC si partie commune + */ #define us unsigned int -static inline int USCALE(us arg, us num, us den) - { - int ii; - - ii = (int)( ((float) arg * num) / den); - return( ii ); - } - -#define WHEN_OUTSIDE return(OK_DRC) -#define WHEN_INSIDE - -static int Tst_Ligne(int x1,int y1,int x2,int y2) +static inline int USCALE( us arg, us num, us den ) { -int temp; + int ii; -do { - if(x1 > x2) { EXCHG(x1,x2); EXCHG(y1,y2); } - if((x2 < xcliplo) || (x1 > xcliphi)) { WHEN_OUTSIDE; } - if(y1 < y2) - { - if((y2 < ycliplo) || (y1 > ycliphi)) { WHEN_OUTSIDE;} - if(y1 < ycliplo) - { - temp = USCALE((x2 - x1),(ycliplo - y1),(y2 - y1)); - if((x1 += temp) > xcliphi) { WHEN_OUTSIDE; } - y1 = ycliplo; - WHEN_INSIDE; - } - if(y2 > ycliphi) - { - temp = USCALE((x2 - x1),(y2 - ycliphi),(y2 - y1)); - if((x2 -= temp) < xcliplo) { WHEN_OUTSIDE; } - y2 = ycliphi; - WHEN_INSIDE; - } - if(x1 < xcliplo) - { - temp = USCALE((y2 - y1),(xcliplo - x1),(x2 - x1)); - y1 += temp; x1 = xcliplo; - WHEN_INSIDE; - } - if(x2 > xcliphi) - { - temp = USCALE((y2 - y1),(x2 - xcliphi),(x2 - x1)); - y2 -= temp; x2 = xcliphi; - WHEN_INSIDE; - } - } - else - { - if((y1 < ycliplo) || (y2 > ycliphi)) { WHEN_OUTSIDE; } - if(y1 > ycliphi) - { - temp = USCALE((x2 - x1),(y1 - ycliphi),(y1 - y2)); - if((x1 += temp) > xcliphi) { WHEN_OUTSIDE; } - y1 = ycliphi; - WHEN_INSIDE; - } - if(y2 < ycliplo) - { - temp = USCALE((x2 - x1),(ycliplo - y2),(y1 - y2)); - if((x2 -= temp) < xcliplo) { WHEN_OUTSIDE; } - y2 = ycliplo; - WHEN_INSIDE; - } - if(x1 < xcliplo) - { - temp = USCALE((y1 - y2),(xcliplo - x1),(x2 - x1)); - y1 -= temp; x1 = xcliplo; - WHEN_INSIDE; - } - if(x2 > xcliphi) - { - temp = USCALE((y1 - y2),(x2 - xcliphi),(x2 - x1)); - y2 += temp; x2 = xcliphi; - WHEN_INSIDE; - } - } - } while(0); - - if ( ((x2 + x1)/2 <= xcliphi ) && ((x2+x1)/2 >= xcliplo) \ - && ((y2 + y1)/2 <= ycliphi ) && ((y2+y1)/2 >= ycliplo) ) - { - return(BAD_DRC) ; - } - - else return(OK_DRC); + ii = (int) ( ( (float) arg * num ) / den ); + return ii; } +#define WHEN_OUTSIDE return (OK_DRC) +#define WHEN_INSIDE + +static int Tst_Ligne( int x1, int y1, int x2, int y2 ) +{ + int temp; + + do { + if( x1 > x2 ) + { + EXCHG( x1, x2 ); EXCHG( y1, y2 ); + } + if( (x2 < xcliplo) || (x1 > xcliphi) ) + { + WHEN_OUTSIDE; + } + if( y1 < y2 ) + { + if( (y2 < ycliplo) || (y1 > ycliphi) ) + { + WHEN_OUTSIDE; + } + if( y1 < ycliplo ) + { + temp = USCALE( (x2 - x1), (ycliplo - y1), (y2 - y1) ); + if( (x1 += temp) > xcliphi ) + { + WHEN_OUTSIDE; + } + y1 = ycliplo; + WHEN_INSIDE; + } + if( y2 > ycliphi ) + { + temp = USCALE( (x2 - x1), (y2 - ycliphi), (y2 - y1) ); + if( (x2 -= temp) < xcliplo ) + { + WHEN_OUTSIDE; + } + y2 = ycliphi; + WHEN_INSIDE; + } + if( x1 < xcliplo ) + { + temp = USCALE( (y2 - y1), (xcliplo - x1), (x2 - x1) ); + y1 += temp; x1 = xcliplo; + WHEN_INSIDE; + } + if( x2 > xcliphi ) + { + temp = USCALE( (y2 - y1), (x2 - xcliphi), (x2 - x1) ); + y2 -= temp; x2 = xcliphi; + WHEN_INSIDE; + } + } + else + { + if( (y1 < ycliplo) || (y2 > ycliphi) ) + { + WHEN_OUTSIDE; + } + if( y1 > ycliphi ) + { + temp = USCALE( (x2 - x1), (y1 - ycliphi), (y1 - y2) ); + if( (x1 += temp) > xcliphi ) + { + WHEN_OUTSIDE; + } + y1 = ycliphi; + WHEN_INSIDE; + } + if( y2 < ycliplo ) + { + temp = USCALE( (x2 - x1), (ycliplo - y2), (y1 - y2) ); + if( (x2 -= temp) < xcliplo ) + { + WHEN_OUTSIDE; + } + y2 = ycliplo; + WHEN_INSIDE; + } + if( x1 < xcliplo ) + { + temp = USCALE( (y1 - y2), (xcliplo - x1), (x2 - x1) ); + y1 -= temp; x1 = xcliplo; + WHEN_INSIDE; + } + if( x2 > xcliphi ) + { + temp = USCALE( (y1 - y2), (x2 - xcliphi), (x2 - x1) ); + y2 += temp; x2 = xcliphi; + WHEN_INSIDE; + } + } + } while( 0 ); + + if( ( (x2 + x1) / 2 <= xcliphi ) && ( (x2 + x1) / 2 >= xcliplo ) \ + && ( (y2 + y1) / 2 <= ycliphi ) && ( (y2 + y1) / 2 >= ycliplo ) ) + { + return BAD_DRC; + } + else + return OK_DRC; +} diff --git a/pcbnew/edit.cpp b/pcbnew/edit.cpp index bc1a711092..c2b3f441c0 100644 --- a/pcbnew/edit.cpp +++ b/pcbnew/edit.cpp @@ -128,8 +128,7 @@ void WinEDA_PcbFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos ) #if defined(DEBUG) DrawStruct = m_Pcb->FindPadOrModule( GetScreen()->RefPos(true), - GetScreen()->m_Active_Layer, - VISIBLE_ONLY ); + GetScreen()->m_Active_Layer ); #else DrawStruct = PcbGeneralLocateAndDisplay(); #endif diff --git a/pcbnew/locate.cpp b/pcbnew/locate.cpp index 522c06f5e2..3436f24923 100644 --- a/pcbnew/locate.cpp +++ b/pcbnew/locate.cpp @@ -13,10 +13,7 @@ #include "protos.h" - -/* variables locales */ -int ux0, uy0, dx, dy, spot_cX, spot_cY; /* Variables utilisees pour - * la localisation des segments */ + /* fonctions locales */ EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc ); @@ -302,72 +299,21 @@ EDGE_MODULE* Locate_Edge_Module( MODULE* module, int typeloc ) * 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 ) return NULL; - ref_pos = RefPos( typeloc ); + /* coord du point de localisation */ + wxPoint ref_pos = RefPos( typeloc ); - PtStruct = module->m_Drawings; - for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) + EDA_BaseStruct* PtStruct = module->m_Drawings; + for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) { if( PtStruct->m_StructType != TYPEEDGEMODULE ) continue; - edge_mod = (EDGE_MODULE*) PtStruct; - type_trace = edge_mod->m_Shape; - ux0 = edge_mod->m_Start.x; uy0 = edge_mod->m_Start.y; - uxf = edge_mod->m_End.x; uyf = edge_mod->m_End.y; - - switch( type_trace ) - { - case S_SEGMENT: - /* recalcul des coordonnees avec ux0,uy0 = origine des coord. */ - spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0; - dx = uxf - ux0; dy = uyf - uy0; - /* detection : */ - if( distance( edge_mod->m_Width / 2 ) ) - return edge_mod; - break; - - case S_CIRCLE: - rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) ); - dist = (int) hypot( (double) (ref_pos.x - ux0), (double) (ref_pos.y - uy0) ); - - if( abs( rayon - dist ) <= edge_mod->m_Width ) - return edge_mod; - break; - - case S_ARC: - rayon = (int) hypot( (double) (uxf - ux0), (double) (uyf - uy0) ); - dist = (int) hypot( (double) (ref_pos.x - ux0), (double) (ref_pos.y - uy0) ); - - if( abs( rayon - dist ) > edge_mod->m_Width ) - break; - - /* pour un arc, controle complementaire */ - MouseAngle = (int) ArcTangente( ref_pos.y - uy0, ref_pos.x - ux0 ); - StAngle = (int) ArcTangente( uyf - uy0, uxf - ux0 ); - EndAngle = StAngle + edge_mod->m_Angle; - - if( EndAngle > 3600 ) - { - StAngle -= 3600; EndAngle -= 3600; - } - - if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) ) - return edge_mod; - - break; - } + // calls virtual EDGE_MODULE::HitTest() + if( PtStruct->HitTest( ref_pos ) ) + return (EDGE_MODULE*) PtStruct; } 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 */ { - EDA_BaseStruct* PtStruct; - COTATION* Cotation; - TEXTE_PCB* pt_txt; - wxPoint ref_pos; - int ux0, uy0; + wxPoint ref_pos = RefPos( typeloc ); - ref_pos = RefPos( typeloc ); - - PtStruct = Pcb->m_Drawings; + EDA_BaseStruct* PtStruct = Pcb->m_Drawings; for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) { if( PtStruct->m_StructType != TYPECOTATION ) continue; - - Cotation = (COTATION*) PtStruct; - if( (Cotation->m_Layer != LayerSearch) && (LayerSearch != -1) ) - continue; - /* Localisation du texte ? */ - pt_txt = Cotation->m_Text; - if( pt_txt ) - { - // 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(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; + // calls virtual COTATION::HitTest() + if( PtStruct->HitTest( ref_pos ) ) + return (COTATION*) PtStruct; } return NULL; @@ -499,73 +357,32 @@ DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int LayerSearch, int typeloc ) * Le segment sur la couche active est détecté en priorite */ { - EDA_BaseStruct* PtStruct; - DRAWSEGMENT* pts, * locate_segm = NULL; - wxPoint ref_pos; + + DRAWSEGMENT* locate_segm = NULL; PCB_SCREEN* screen = (PCB_SCREEN*) ActiveScreen; + + wxPoint ref_pos = RefPos( typeloc ); - ref_pos = RefPos( typeloc ); - - PtStruct = Pcb->m_Drawings; + EDA_BaseStruct* PtStruct = Pcb->m_Drawings; for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext ) { if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue; - pts = (DRAWSEGMENT*) PtStruct; + + DRAWSEGMENT* pts = (DRAWSEGMENT*) PtStruct; + if( (pts->m_Layer != LayerSearch) && (LayerSearch != -1) ) continue; - - ux0 = pts->m_Start.x; uy0 = pts->m_Start.y; - - /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ - dx = pts->m_End.x - ux0; dy = pts->m_End.y - uy0; - spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0; - /* detection : */ - if( (pts->m_Shape == S_CIRCLE) || (pts->m_Shape == S_ARC) ) + if( pts->HitTest( ref_pos ) ) { - int rayon, dist, StAngle, EndAngle, MouseAngle; + // return this hit if layer matches, else remember in + // case no layer match is found. + if( pts->m_Layer == screen->m_Active_Layer ) + return pts; - rayon = (int) hypot( (double) (dx), (double) (dy) ); - dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) ); - - if( abs( rayon - dist ) <= (pts->m_Width / 2) ) - { - if( pts->m_Shape == S_CIRCLE ) - { - if( pts->m_Layer == screen->m_Active_Layer ) - return pts; - else if( !locate_segm ) - locate_segm = pts; - } - - /* pour un arc, controle complementaire */ - MouseAngle = (int) ArcTangente( spot_cY, spot_cX ); - StAngle = (int) ArcTangente( dy, dx ); - EndAngle = StAngle + pts->m_Angle; - - if( EndAngle > 3600 ) - { - StAngle -= 3600; EndAngle -= 3600; - } - if( (MouseAngle >= StAngle) && (MouseAngle <= EndAngle) ) - { - if( pts->m_Layer == screen->m_Active_Layer ) - return pts; - else if( !locate_segm ) - locate_segm = pts; - } - } - } - else - { - if( distance( pts->m_Width / 2 ) ) - { - if( pts->m_Layer == screen->m_Active_Layer ) - return pts; - else if( !locate_segm ) - locate_segm = pts; - } + else if( !locate_segm ) + locate_segm = pts; } } @@ -651,14 +468,6 @@ D_PAD* Locate_Pads( MODULE* module, const wxPoint& ref_pos, int masque_layer ) D_PAD* pt_pad = module->m_Pads; 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 */ if( (pt_pad->m_Masque_Layer & masque_layer) == 0 ) continue; @@ -704,8 +513,6 @@ MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc ) if( (typeloc & IGNORE_LOCKED) && pt_module->IsLocked() ) continue; - /* Localisation: test des dimensions minimales, choix du meilleur candidat */ - /* calcul de priorite: la priorite est donnee a la couche * d'appartenance du module et a la couche cuivre si le module * est sur couche serigr,adhesive cuivre, a la couche cmp si le module @@ -718,6 +525,8 @@ MODULE* Locate_Prefered_Module( BOARD* Pcb, int typeloc ) else if( layer==ADHESIVE_N_CMP || layer==SILKSCREEN_N_CMP ) layer = CMP_N; + /* Localisation: test des dimensions minimales, choix du meilleur candidat */ + /* calcul des dimensions du cadre :*/ lx = pt_module->m_BoundaryBox.GetWidth(); ly = pt_module->m_BoundaryBox.GetHeight(); @@ -998,42 +807,30 @@ TRACK* Locate_Pistes( TRACK* start_adresse, int MasqueLayer, int typeloc ) TRACK* Locate_Pistes( TRACK* start_adresse, const wxPoint& ref_pos, int MasqueLayer ) { - TRACK* Track; /* pointeur sur les pistes */ - int l_piste; /* demi-largeur de la piste */ - - for( Track = start_adresse; Track != NULL; Track = (TRACK*) Track->Pnext ) + for( TRACK* Track = start_adresse; Track; Track = (TRACK*) Track->Pnext ) { if( Track->GetState( BUSY | DELETED ) ) continue; + if( (g_DesignSettings.m_LayerColor[Track->m_Layer] & ITEM_NOT_SHOW) ) continue; - /* calcul des coordonnees du segment teste */ - l_piste = Track->m_Width >> 1; /* l_piste = demi largeur piste */ - ux0 = Track->m_Start.x; uy0 = Track->m_Start.y; /* coord de depart */ - dx = Track->m_End.x; dy = Track->m_End.y; /* coord d'arrivee */ - - /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ - dx -= ux0; dy -= uy0; - spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0; - if( Track->m_StructType == TYPEVIA ) /* VIA rencontree */ { - if( (abs( spot_cX ) <= l_piste ) && (abs( spot_cY ) <=l_piste) ) - { + if( Track->HitTest( ref_pos ) ) + return Track; + } + else + { + if( MasqueLayer != -1 ) + if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0 ) + continue; /* Segments sur couches differentes */ + + if( Track->HitTest( ref_pos ) ) return Track; - } - continue; } - - if( MasqueLayer != -1 ) - if( (g_TabOneLayerMask[Track->m_Layer] & MasqueLayer) == 0 ) - continue; /* Segments sur couches differentes */ - - if( distance( l_piste ) ) - return Track; } - + return NULL; } @@ -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* Zone; /* pointeur sur les pistes */ - int l_segm; /* demi-largeur de la piste */ - - for( Zone = start_adresse; Zone != NULL; Zone = (TRACK*) Zone->Pnext ) + for( TRACK* Zone = start_adresse; Zone; Zone = (TRACK*) Zone->Pnext ) { - /* calcul des coordonnees du segment teste */ - l_segm = Zone->m_Width >> 1; /* l_piste = demi largeur piste */ - ux0 = Zone->m_Start.x; uy0 = Zone->m_Start.y; /* coord de depart */ - dx = Zone->m_End.x; dy = Zone->m_End.y; /* coord d'arrivee */ - - /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ - dx -= ux0; dy -= uy0; - spot_cX = ref_pos.x - ux0; spot_cY = ref_pos.y - uy0; - if( (layer != -1) && (Zone->m_Layer != layer) ) continue; - if( distance( l_segm ) ) + + if( Zone->HitTest( ref_pos ) ) 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 ) @@ -1396,11 +1029,10 @@ EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, int typeloc ) /***********************************************************************/ -/* Serach for a photo target +/* Search for a photo target */ { wxPoint ref_pos;/* coord du point de localisation */ - int dX, dY, rayon; if( PtStruct == NULL ) return NULL; @@ -1417,13 +1049,10 @@ EDA_BaseStruct* Locate_MirePcb( EDA_BaseStruct* PtStruct, int LayerSearch, if( LayerSearch != -1 && item->m_Layer != LayerSearch ) continue; - dX = ref_pos.x - item->m_Pos.x; - dY = ref_pos.y - item->m_Pos.y; - rayon = item->m_Size / 2; - - if( (abs( dX ) <= rayon ) && ( abs( dY ) <= rayon ) ) - break; /* Mire Localisee */ + if( item->HitTest( ref_pos ) ) + break; } return PtStruct; } + diff --git a/pcbnew/protos.h b/pcbnew/protos.h index 808e1996da..538c9ab535 100644 --- a/pcbnew/protos.h +++ b/pcbnew/protos.h @@ -198,24 +198,6 @@ D_PAD * Fast_Locate_Pad_Connecte(BOARD * Pcb, const wxPoint & ref_pos, int layer (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, const wxPoint & ref_pos,int layer); /* diff --git a/pcbnew/zones.h b/pcbnew/zones.h index 1f3d95e604..22d97041e7 100644 --- a/pcbnew/zones.h +++ b/pcbnew/zones.h @@ -122,5 +122,5 @@ public: WinEDA_PcbFrame * m_Parent; }; -#endif - // _ZONES_H_ +#endif // _ZONES_H_ +