diff --git a/change_log.txt b/change_log.txt index 025d17cb63..fbd7269419 100644 --- a/change_log.txt +++ b/change_log.txt @@ -4,10 +4,25 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. +2007-Nov-30 UPDATE Dick Hollenbeck +================================================================================ ++pcbnew + * added virtual GetPosition() to BOARD_ITEM and derivatives. + * added classes DRC, REPORT_ISSUE, DRC_ITEM and rearranged drc.cpp entirely + to comprize the DRC class. The result has finer granularity of functions + and each is fairly well documented in English, see drc_stuff.h. + Keeping old stuff commented out at bottom of drc.cpp until some more usage + and testing is done. + * Made the DRC dialog modeless, so it can sit off to the side while the MARKER + are inspected one by one. + Need another 4-8 hours or so to finish the actual dialog display, remove + debug statements and finish testing. + + 2007-Nov-29 UPDATE Jean-Pierre Charras ================================================================================ +pcbnew: - Removed a bug (function block() ) which crashes pcbnew when erasing a zone by block delete + Removed a bug (function block() ) which crashes pcbnew when erasing a zone by block delete 2007-Nov-27 UPDATE Dick Hollenbeck @@ -50,7 +65,7 @@ email address. 2007-Nov-15 UPDATE Jean-Pierre Charras ================================================================================ +pcbnew: - Removed a bug (function Delete_Zone() ) which crashes pcbnew when erasing a zone by popup menu + Removed a bug (function Delete_Zone() ) which crashes pcbnew when erasing a zone by popup menu 2007-Nov-13 UPDATE Geoff Harland diff --git a/include/base_struct.h b/include/base_struct.h index 36ff959e20..af10525393 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -456,6 +456,13 @@ public: BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; } BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; } + /** + * Function GetPosition + * returns the position of this object. + * @return wxPoint& - The position of this object, non-const so it + * can be changed + */ + virtual wxPoint& GetPosition() = 0; /** * Function GetLayer diff --git a/include/pcbstruct.h b/include/pcbstruct.h index 4a4bb3f000..2be35791b7 100644 --- a/include/pcbstruct.h +++ b/include/pcbstruct.h @@ -199,8 +199,11 @@ enum DisplayViaMode { class BOARD : public BOARD_ITEM { friend class WinEDA_PcbFrame; + private: - std::vector m_markers; ///< MARKERs which we own by pointer + std::vector m_markers; ///< MARKERs for clearance problems, owned by pointer +// std::vector m_markersUnconnected; ///< MARKERs for unconnected problems, owned by pointer + public: WinEDA_BasePcbFrame* m_PcbFrame; // Window de visualisation @@ -233,6 +236,14 @@ public: BOARD( EDA_BaseStruct* StructFather, WinEDA_BasePcbFrame* frame ); ~BOARD(); + /** + * Function GetPosition + * is here to satisfy BOARD_ITEM's requirements, but this implementation + * is a dummy. + * @return const wxPoint& of (0,0) + */ + wxPoint& GetPosition(); + /* supprime du chainage la structure Struct */ void UnLink(); @@ -275,7 +286,16 @@ public: int GetNumSegmTrack(); int GetNumSegmZone(); int GetNumNoconnect(); // retourne le nombre de connexions manquantes - int GetNumRatsnests(); // retourne le nombre de chevelus + + /** + * Function GetNumRatsnests + * @return int - The number of rats + */ + int GetNumRatsnests() + { + return m_NbLinks; + } + int GetNumNodes(); // retourne le nombre de pads a netcode > 0 // Calcul du rectangle d'encadrement: @@ -407,7 +427,18 @@ public: DRAWSEGMENT( BOARD_ITEM* StructFather, KICAD_T idtype = TYPEDRAWSEGMENT ); ~DRAWSEGMENT(); - // Read/write data + + /** + * Function GetPosition + * returns the position of this object. + * Required by pure virtual BOARD_ITEM::GetPosition() + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Start; + } + /** * Function Save diff --git a/include/wxstruct.h b/include/wxstruct.h index 1e80a5951f..99d9aeb283 100644 --- a/include/wxstruct.h +++ b/include/wxstruct.h @@ -101,6 +101,7 @@ class Ki_PageDescr; class Ki_HotkeyInfo; class GENERAL_COLLECTOR; class GENERAL_COLLECTORS_GUIDE; +class DRC; enum id_librarytype { @@ -574,6 +575,9 @@ private: bool m_SelViaSizeBox_Changed; wxMenu* m_FilesMenu; + DRC* m_drc; ///< the DRC controller, see drc.cpp + + // we'll use lower case function names for private member functions. void createPopUpMenuForFootprints( MODULE* aModule, wxMenu* aPopMenu ); void createPopUpMenuForFpTexts( TEXTE_MODULE* aText, wxMenu* aPopMenu ); @@ -655,7 +659,6 @@ public: MODULE* ListAndSelectModuleName(); void Liste_Equipot( wxCommandEvent& event ); void Swap_Layers( wxCommandEvent& event ); - int Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone ); void Install_Test_DRC_Frame( wxDC* DC ); void Trace_Pcb( wxDC* DC, int mode ); @@ -719,6 +722,8 @@ public: bool PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC ); void Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC ); void SwitchLayer( wxDC* DC, int layer ); + int Add_45_degrees_Segment( wxDC* DC, TRACK* pt_segm ); + bool Genere_Pad_Connexion( wxDC* DC, int layer ); // zone handling EDGE_ZONE* Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone ); diff --git a/pcbnew/autoplac.cpp b/pcbnew/autoplac.cpp index 6a26e6fe9f..271f64aa48 100644 --- a/pcbnew/autoplac.cpp +++ b/pcbnew/autoplac.cpp @@ -865,22 +865,25 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule( wxDC* DC ) CHEVELU* pt_local_chevelu; int ii; float cout, icout; - int ox, oy, fx, fy, dx, dy; + int ox, oy; + int fx, fy; + int dx, dy; if( (m_Pcb->m_Status_Pcb & CHEVELU_LOCAL_OK) == 0 ) return -1; pt_local_chevelu = local_liste_chevelu; - ii = nb_local_chevelu; cout = 0; + ii = nb_local_chevelu; + cout = 0; while( ii-- > 0 ) { if( !(pt_local_chevelu->status & LOCAL_CHEVELU) ) { - ox = pt_local_chevelu->pad_start->m_Pos.x - g_Offset_Module.x; - oy = pt_local_chevelu->pad_start->m_Pos.y - g_Offset_Module.y; - fx = pt_local_chevelu->pad_end->m_Pos.x; - fy = pt_local_chevelu->pad_end->m_Pos.y; + ox = pt_local_chevelu->pad_start->GetPosition().x - g_Offset_Module.x; + oy = pt_local_chevelu->pad_start->GetPosition().y - g_Offset_Module.y; + fx = pt_local_chevelu->pad_end->GetPosition().x; + fy = pt_local_chevelu->pad_end->GetPosition().y; if( AutoPlaceShowAll ) { @@ -889,12 +892,18 @@ float WinEDA_PcbFrame::Compute_Ratsnest_PlaceModule( wxDC* DC ) } /* Evaluation du cout du chevelu: */ - dx = fx - ox; dy = fy - oy; - dx = abs( dx ); dy = abs( dy ); + dx = fx - ox; + dy = fy - oy; + + dx = abs( dx ); + dy = abs( dy ); + if( dx < dy ) EXCHG( dx, dy );/* dx >= dy */ + /* cout de la distance: */ icout = (float) dx * dx; + /* cout de l'inclinaison */ icout += 3 * (float) dy * dy; icout = sqrt( icout ); diff --git a/pcbnew/autorout.h b/pcbnew/autorout.h index 538d1ab1bb..7ce8e8ee8c 100644 --- a/pcbnew/autorout.h +++ b/pcbnew/autorout.h @@ -55,9 +55,10 @@ public: void SetNet( int aNetCode ) { m_NetCode = aNetCode; - }; + } }; + /****************************************************************/ /* description d'un point de piste pour le suivi des connexions */ /****************************************************************/ @@ -81,9 +82,6 @@ enum StatusPcbFlags { DO_NOT_SHOW_GENERAL_RASTNEST = 0x20 /* Do not display the general rastnest (used in module moves) */ }; -#define OK_DRC 0 -#define BAD_DRC 1 - /* Commandes d'autoplacement / autorouage possibles */ enum CommandOpt { @@ -170,4 +168,5 @@ eda_global BOARDHEAD Board; /* 2-sided board */ #include "ar_protos.h" -#endif /* AUTOROUT_H */ +#endif // AUTOROUT_H + diff --git a/pcbnew/block_module_editor.cpp b/pcbnew/block_module_editor.cpp index bdbee47278..11fa1aed03 100644 --- a/pcbnew/block_module_editor.cpp +++ b/pcbnew/block_module_editor.cpp @@ -471,8 +471,8 @@ void MoveMarkedItems( MODULE* module, wxPoint offset ) { if( pad->m_Selected == 0 ) continue; - pad->m_Pos.x += offset.x; - pad->m_Pos.y += offset.y; + pad->GetPosition().x += offset.x; + pad->GetPosition().y += offset.y; pad->m_Pos0.x += offset.x; pad->m_Pos0.y += offset.y; } @@ -486,8 +486,8 @@ void MoveMarkedItems( MODULE* module, wxPoint offset ) switch( item->Type() ) { case TYPETEXTEMODULE: - ( (TEXTE_MODULE*) item )->m_Pos.x += offset.x; - ( (TEXTE_MODULE*) item )->m_Pos.y += offset.y; + ( (TEXTE_MODULE*) item )->GetPosition().x += offset.x; + ( (TEXTE_MODULE*) item )->GetPosition().y += offset.y; ( (TEXTE_MODULE*) item )->m_Pos0.x += offset.x; ( (TEXTE_MODULE*) item )->m_Pos0.y += offset.y; break; @@ -495,10 +495,13 @@ void MoveMarkedItems( MODULE* module, wxPoint offset ) case TYPEEDGEMODULE: ( (EDGE_MODULE*) item )->m_Start.x += offset.x; ( (EDGE_MODULE*) item )->m_Start.y += offset.y; + ( (EDGE_MODULE*) item )->m_End.x += offset.x; ( (EDGE_MODULE*) item )->m_End.y += offset.y; + ( (EDGE_MODULE*) item )->m_Start0.x += offset.x; ( (EDGE_MODULE*) item )->m_Start0.y += offset.y; + ( (EDGE_MODULE*) item )->m_End0.x += offset.x; ( (EDGE_MODULE*) item )->m_End0.y += offset.y; break; @@ -565,8 +568,8 @@ void MirrorMarkedItems( MODULE* module, wxPoint offset ) { if( pad->m_Selected == 0 ) continue; - SETMIRROR( pad->m_Pos.x ); - pad->m_Pos0.x = pad->m_Pos.x; + SETMIRROR( pad->GetPosition().x ); + pad->m_Pos0.x = pad->GetPosition().x; pad->m_Offset.x = -pad->m_Offset.x; pad->m_DeltaSize.x = -pad->m_DeltaSize.x; pad->m_Orient = 1800 - pad->m_Orient; @@ -590,8 +593,8 @@ void MirrorMarkedItems( MODULE* module, wxPoint offset ) break; case TYPETEXTEMODULE: - SETMIRROR( ( (TEXTE_MODULE*) item )->m_Pos.x ); - ( (TEXTE_MODULE*) item )->m_Pos0.x = ( (TEXTE_MODULE*) item )->m_Pos.x; + SETMIRROR( ( (TEXTE_MODULE*) item )->GetPosition().x ); + ( (TEXTE_MODULE*) item )->m_Pos0.x = ( (TEXTE_MODULE*) item )->GetPosition().x; break; default: @@ -621,8 +624,8 @@ void RotateMarkedItems( MODULE* module, wxPoint offset ) { if( pad->m_Selected == 0 ) continue; - ROTATE( pad->m_Pos ); - pad->m_Pos0 = pad->m_Pos; + ROTATE( pad->GetPosition() ); + pad->m_Pos0 = pad->GetPosition(); pad->m_Orient += 900; NORMALIZE_ANGLE( pad->m_Orient ); } @@ -643,8 +646,8 @@ void RotateMarkedItems( MODULE* module, wxPoint offset ) break; case TYPETEXTEMODULE: - ROTATE( ( (TEXTE_MODULE*) item )->m_Pos ); - ( (TEXTE_MODULE*) item )->m_Pos0 = ( (TEXTE_MODULE*) item )->m_Pos; + ROTATE( ( (TEXTE_MODULE*) item )->GetPosition() ); + ( (TEXTE_MODULE*) item )->m_Pos0 = ( (TEXTE_MODULE*) item )->GetPosition(); ( (TEXTE_MODULE*) item )->m_Orient += 900; break; @@ -696,7 +699,7 @@ int MarkItemsInBloc( MODULE* module, EDA_Rect& Rect ) for( ; pad != NULL; pad = pad->Next() ) { pad->m_Selected = 0; - pos = pad->m_Pos; + pos = pad->GetPosition(); if( Rect.Inside( pos ) ) { pad->m_Selected = IS_SELECTED; @@ -727,7 +730,7 @@ int MarkItemsInBloc( MODULE* module, EDA_Rect& Rect ) break; case TYPETEXTEMODULE: - pos = ( (TEXTE_MODULE*) item )->m_Pos; + pos = ( (TEXTE_MODULE*) item )->GetPosition(); if( Rect.Inside( pos ) ) { item->m_Selected = IS_SELECTED; diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index bc8435838d..5bc4cc3f1c 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -360,38 +360,38 @@ int Build_Work( BOARD* Pcb, CHEVELU* pt_base_chevelu ) current_net_code = pt_pad->GetNet(); pt_ch = pt_rats; - r1 = (pt_pad->m_Pos.y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize; + r1 = (pt_pad->GetPosition().y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize; if( r1 < 0 || r1 >= Nrows ) { msg.Printf( wxT( "erreur : row = %d ( padY %d pcbY %d) " ), r1, - pt_pad->m_Pos.y, Pcb->m_BoundaryBox.m_Pos.y ); + pt_pad->GetPosition().y, Pcb->m_BoundaryBox.m_Pos.y ); DisplayError( NULL, msg ); return 0; } - c1 = (pt_pad->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize; + c1 = (pt_pad->GetPosition().x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize; if( c1 < 0 || c1 >= Ncols ) { msg.Printf( wxT( "erreur : col = %d ( padX %d pcbX %d) " ), c1, - pt_pad->m_Pos.x, Pcb->m_BoundaryBox.m_Pos.x ); + pt_pad->GetPosition().x, Pcb->m_BoundaryBox.m_Pos.x ); DisplayError( NULL, msg ); return 0; } pt_pad = pt_rats->pad_end; - r2 = (pt_pad->m_Pos.y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize; + r2 = (pt_pad->GetPosition().y - Pcb->m_BoundaryBox.m_Pos.y + demi_pas ) / g_GridRoutingSize; if( r2 < 0 || r2 >= Nrows ) { msg.Printf( wxT( "erreur : row = %d ( padY %d pcbY %d) " ), r2, - pt_pad->m_Pos.y, Pcb->m_BoundaryBox.m_Pos.y ); + pt_pad->GetPosition().y, Pcb->m_BoundaryBox.m_Pos.y ); DisplayError( NULL, msg ); return 0; } - c2 = (pt_pad->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize; + c2 = (pt_pad->GetPosition().x - Pcb->m_BoundaryBox.m_Pos.x + demi_pas ) / g_GridRoutingSize; if( c2 < 0 || c2 >= Ncols ) { msg.Printf( wxT( "erreur : col = %d ( padX %d pcbX %d) " ), c2, - pt_pad->m_Pos.x, Pcb->m_BoundaryBox.m_Pos.x ); + pt_pad->GetPosition().x, Pcb->m_BoundaryBox.m_Pos.x ); DisplayError( NULL, msg ); return 0; } diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index efadf18ed8..132b6202b3 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -79,6 +79,13 @@ BOARD::~BOARD() } +wxPoint& BOARD::GetPosition() +{ + static wxPoint dummy(0,0); + return dummy; // a reference +} + + void BOARD::UnLink() { /* Modification du chainage arriere */ @@ -108,6 +115,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) { // this one uses a vector case TYPEMARKER: + aBoardItem->m_Parent = this; m_markers.push_back( (MARKER*) aBoardItem ); break; @@ -188,13 +196,6 @@ int BOARD::GetNumNoconnect() } -// retourne le nombre de chevelus -int BOARD::GetNumRatsnests() -{ - return m_NbLinks; -} - - // retourne le nombre de pads a netcode > 0 int BOARD::GetNumNodes() { @@ -273,11 +274,13 @@ bool BOARD::ComputeBoundaryBox() D_PAD* pt_pad = module->m_Pads; for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext ) { + const wxPoint& pos = pt_pad->GetPosition(); + d = pt_pad->m_Rayon; - xmin = MIN( xmin, pt_pad->m_Pos.x - d ); - ymin = MIN( ymin, pt_pad->m_Pos.y - d ); - xmax = MAX( xmax, pt_pad->m_Pos.x + d ); - ymax = MAX( ymax, pt_pad->m_Pos.y + d ); + xmin = MIN( xmin, pos.x - d ); + ymin = MIN( ymin, pos.y - d ); + xmax = MAX( xmax, pos.x + d ); + ymax = MAX( ymax, pos.y + d ); } } diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index e1559b22c4..f5f23eab61 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -195,7 +195,8 @@ wxString BOARD_ITEM::MenuText( const BOARD* aPcb ) const break; case TYPEMARKER: - text << _( "Marker" ) << wxT( " @(" ) << ((MARKER*)item)->m_Pos.x << wxT(",") << ((MARKER*)item)->m_Pos.y << wxT(")"); + text << _( "Marker" ) << wxT( " @(" ) << ((MARKER*)item)->GetPos().x + << wxT(",") << ((MARKER*)item)->GetPos().y << wxT(")"); break; case TYPECOTATION: diff --git a/pcbnew/class_cotation.h b/pcbnew/class_cotation.h index bd818ee3a7..2af1ae90b9 100644 --- a/pcbnew/class_cotation.h +++ b/pcbnew/class_cotation.h @@ -28,6 +28,12 @@ public: COTATION( BOARD_ITEM* StructFather ); ~COTATION(); + wxPoint& GetPosition() + { + return m_Pos; + } + + bool ReadCotationDescr( FILE* File, int* LineNum ); /** diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 817acf170d..e39e1493bb 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -29,6 +29,18 @@ public: EDGE_MODULE( EDGE_MODULE* edge ); ~EDGE_MODULE(); + + /** + * Function GetPosition + * returns the position of this object. + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Start; + } + + /* supprime du chainage la structure Struct */ void UnLink(); diff --git a/pcbnew/class_equipot.cpp b/pcbnew/class_equipot.cpp index 59f432c679..423269e0af 100644 --- a/pcbnew/class_equipot.cpp +++ b/pcbnew/class_equipot.cpp @@ -44,6 +44,13 @@ EQUIPOT::~EQUIPOT() } +wxPoint& EQUIPOT::GetPosition() +{ + static wxPoint dummy; + return dummy; +} + + void EQUIPOT::UnLink() { /* Modification du chainage arriere */ diff --git a/pcbnew/class_equipot.h b/pcbnew/class_equipot.h index cb885068a7..b15e43c9e4 100644 --- a/pcbnew/class_equipot.h +++ b/pcbnew/class_equipot.h @@ -29,6 +29,16 @@ public: ~EQUIPOT(); EQUIPOT* Next() { return (EQUIPOT*) Pnext; } + + /** + * Function GetPosition + * returns the position of this object. + * @return wxPoint& - The position of this object, non-const so it + * can be changed + * A dummy to satisfy pure virtual BOARD::GetPosition() + */ + wxPoint& GetPosition(); + /* Effacement memoire de la structure */ void UnLink(); diff --git a/pcbnew/class_marker.cpp b/pcbnew/class_marker.cpp index 906addac5d..5dff99162a 100644 --- a/pcbnew/class_marker.cpp +++ b/pcbnew/class_marker.cpp @@ -38,8 +38,7 @@ static char Default_MarkerBitmap[] = /* Classe MARKER */ /*******************/ -MARKER::MARKER( BOARD_ITEM* StructFather ) : - BOARD_ITEM( StructFather, TYPEMARKER ) +void MARKER::init() { m_Bitmap = NULL; m_Type = 0; @@ -49,6 +48,26 @@ MARKER::MARKER( BOARD_ITEM* StructFather ) : m_Size.y = Default_MarkerBitmap[1]; } +MARKER::MARKER( BOARD_ITEM* StructFather ) : + BOARD_ITEM( StructFather, TYPEMARKER ), + m_drc() +{ + init(); +} + + +MARKER::MARKER( int aErrorCode, const wxPoint& aMarkerPos, + const wxString& aText, const wxPoint& aPos, + const wxString& bText, const wxPoint& bPos ) : + BOARD_ITEM( NULL, TYPEMARKER ) // parent set during BOARD::Add() +{ + init(); + + SetData( aErrorCode, aMarkerPos, + aText, aPos, + bText, bPos ); +} + /* Effacement memoire de la structure */ MARKER::~MARKER() @@ -59,6 +78,19 @@ MARKER::~MARKER() } +void MARKER::SetData( int aErrorCode, const wxPoint& aMarkerPos, + const wxString& aText, const wxPoint& aPos, + const wxString& bText, const wxPoint& bPos ) +{ + m_drc.SetData( aErrorCode, aMarkerPos, + aText, bText, + aPos, bPos ); + + // @todo: switch on error code to set error code specific color, and possibly bitmap. + m_Color = WHITE; +} + + /* supprime du chainage la structure Struct * les structures arrieres et avant sont chainees directement */ @@ -78,7 +110,7 @@ void MARKER::Display_Infos( WinEDA_DrawFrame* frame ) Affiche_1_Parametre( frame, text_pos, _( "Type" ), _("Marker"), DARKCYAN ); text_pos = 12; - Affiche_1_Parametre( frame, text_pos, _( "Marker Error Text" ), m_Diag, RED ); + Affiche_1_Parametre( frame, text_pos, _( "Marker Error Text" ), GetOneLineMessage(), RED ); } @@ -95,9 +127,11 @@ bool MARKER::HitTest( const wxPoint& refPos ) TrueSize.x *= ActiveScreen->GetZoom(); TrueSize.y *= ActiveScreen->GetZoom(); } + + wxPoint pos = GetPosition(); - int dx = refPos.x - m_Pos.x; - int dy = refPos.y - m_Pos.y; + int dx = refPos.x - pos.x; + int dy = refPos.y - pos.y; /* is refPos in the box: Marker size to right an bottom, or size/2 to left or top */ @@ -130,8 +164,8 @@ void MARKER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int DrawMode ) GRSetDrawMode( DC, DrawMode ); - px = GRMapX( m_Pos.x ); - py = GRMapY( m_Pos.y ); + px = GRMapX( GetPosition().x ); + py = GRMapY( GetPosition().y ); /* Get the bitmap size */ m_Size.x = *(pt_bitmap++); diff --git a/pcbnew/class_marker.h b/pcbnew/class_marker.h index 1317be70d5..632b136565 100644 --- a/pcbnew/class_marker.h +++ b/pcbnew/class_marker.h @@ -7,39 +7,106 @@ #include "base_struct.h" +#include "drc_stuff.h" class MARKER : public BOARD_ITEM { -private: - wxString m_Diag; /* Associated text (comment) */ +protected: + char* m_Bitmap; ///< Shape (bitmap) + int m_Type; + int m_Color; ///< color + wxSize m_Size; ///< Size of the graphic symbol + + DRC_ITEM m_drc; + + void init(); public: - wxPoint m_Pos; - char* m_Bitmap; /* Shape (bitmap) */ - int m_Type; - int m_Color; /* color */ - wxSize m_Size; /* Size of the graphic symbol */ -public: MARKER( BOARD_ITEM* StructFather ); + + /** + * Constructor + * @param aErrorCode The categorizing identifier for an error + * @param aMarkerPos The position of the MARKER on the BOARD + * @param aText Text describing the first of two objects + * @param aPos The position of the first of two objects + * @param bText Text describing the second of the two conflicting objects + * @param bPos The position of the second of two objects + */ + MARKER( int aErrorCode, const wxPoint& aMarkerPos, + const wxString& aText, const wxPoint& aPos, + const wxString& bText, const wxPoint& bPos ); + ~MARKER(); void UnLink(); void Draw( WinEDA_DrawPanel* panel, wxDC* DC, int DrawMode ); + + /** + * Function GetPosition + * returns the position of this MARKER. + */ + wxPoint& GetPosition() + { + return (wxPoint&) m_drc.GetPosition(); + } + + + /** + * Function GetPos + * returns the position of this MARKER, const. + */ + const wxPoint& GetPos() const + { + return m_drc.GetPosition(); + } + + + /** + * Function SetData + * fills in all the reportable data associated with a MARKER. + * @param aErrorCode The categorizing identifier for an error + * @param aMarkerPos The position of the MARKER on the BOARD + * @param aText Text describing the first of two objects + * @param aPos The position of the first of two objects + * @param bText Text describing the second of the two conflicting objects + * @param bPos The position of the second of two objects + */ + void SetData( int aErrorCode, const wxPoint& aMarkerPos, + const wxString& aText, const wxPoint& aPos, + const wxString& bText, const wxPoint& bPos ); /** * Function GetMessage * @return const wxString& - the diagnostic message */ - const wxString& GetMessage() + const wxString GetOneLineMessage() { - return m_Diag; + return m_drc.ShowText(); } + + + /** + * Function GetReporter + * returns the REPORT_ISSUE held within this MARKER so that its + * interface may be used. + * @return const& REPORT_ISSUE + */ + const REPORT_ISSUE& GetReporter() const + { + return m_drc; + } + + + /* void SetMessage( const wxString& aMsg ) { m_Diag = aMsg; } + */ + /** @@ -75,4 +142,4 @@ public: }; -#endif // end #ifndef CLASS_MARKER_H +#endif // CLASS_MARKER_H diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index ef1d53822c..1103d1cbbd 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -19,6 +19,12 @@ public: MIREPCB( BOARD_ITEM* StructFather ); ~MIREPCB(); + wxPoint& GetPosition() + { + return m_Pos; + } + + /** * Function Save * writes the data structures for this object out to a FILE in "*.brd" format. diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 841a715234..1e5c4e8c5d 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -37,6 +37,7 @@ enum Mod_Attribut /* Attributs d'un module */ class MODULE : public BOARD_ITEM { + public: wxPoint m_Pos; // Real coord on board D_PAD* m_Pads; /* Pad list (linked list) */ @@ -82,6 +83,18 @@ public: void SetRectangleExinscrit();/* mise a jour du rect d'encadrement * et de la surface en coord reelles */ + /** + * Function GetPosition + * returns the position of this object. + * Required by pure virtual BOARD_ITEM::GetPosition() + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Pos; + } + + // deplacements void SetPosition( const wxPoint& newpos ); void SetOrientation( int newangle ); diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 2e81a49104..bec6af7aa6 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -38,7 +38,7 @@ D_PAD::D_PAD( MODULE* parent ) : if( m_Parent && (m_Parent->Type() == TYPEMODULE) ) { - m_Pos = ( (MODULE*) m_Parent )->m_Pos; + m_Pos = ( (MODULE*) m_Parent )->GetPosition(); } m_PadShape = CIRCLE; // forme CERCLE, RECT OVALE TRAPEZE ou libre @@ -75,8 +75,8 @@ void D_PAD::ComputeRayon() case RECT: case TRAPEZE: - m_Rayon = (int) (sqrt( (float) m_Size.y * m_Size.y - + (float) m_Size.x * m_Size.x ) / 2); + m_Rayon = (int) (sqrt( (double) m_Size.y * m_Size.y + + (double) m_Size.x * m_Size.x ) / 2); break; } } @@ -88,7 +88,7 @@ const wxPoint D_PAD::ReturnShapePos() // retourne la position de la forme (pastilles excentrees) { - if( (m_Offset.x == 0) && (m_Offset.y == 0) ) + if( m_Offset.x == 0 && m_Offset.y == 0 ) return m_Pos; wxPoint shape_pos; diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 21721d95d0..93accf7f61 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -23,8 +23,11 @@ class D_PAD : public BOARD_ITEM { private: int m_NetCode; // Net number for fast comparisons + public: + wxPoint m_Pos; // pad Position on board + union { unsigned long m_NumPadName; @@ -42,7 +45,6 @@ public: int m_PadShape; // Shape: CIRCLE, RECT, OVAL, TRAPEZOID int m_DrillShape; // Shape CIRCLE, OVAL - wxPoint m_Pos; // pad Position on board wxSize m_Drill; // Drill diam (drill shape = CIRCLE) or drill size(shape = OVAL) // for drill shape = CIRCLE, drill diam = m_Drill.x @@ -72,6 +74,21 @@ public: D_PAD* Next() { return (D_PAD*) Pnext; } + /** + * Function GetPosition + * returns the position of this object. + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Pos; + } + void SetPosition( const wxPoint& aPos ) + { + m_Pos = aPos; + } + + /* remove from linked list */ void UnLink(); @@ -86,6 +103,7 @@ public: */ bool Save( FILE* aFile ) const; + /* drawing functions */ void Draw( WinEDA_DrawPanel* panel, wxDC* DC, const wxPoint& offset, int draw_mode ); diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h index b182bc6369..66a4ba0b4d 100644 --- a/pcbnew/class_pcb_text.h +++ b/pcbnew/class_pcb_text.h @@ -13,6 +13,19 @@ public: TEXTE_PCB( TEXTE_PCB* textepcb ); ~TEXTE_PCB(); + + /** + * Function GetPosition + * returns the position of this object. + * @return wxPoint& - The position of this object, non-const so it + * can be changed + */ + wxPoint& GetPosition() + { + return m_Pos; // within EDA_TextStruct + } + + /* supprime du chainage la structure Struct */ void UnLink(); diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index dd1a82fcbb..25495da323 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -16,8 +16,8 @@ class TEXTE_MODULE : public BOARD_ITEM { public: - int m_Width; wxPoint m_Pos; // Real coord + int m_Width; wxPoint m_Pos0; // coord du debut du texte /ancre, orient 0 char m_Unused; // unused (reserved for future extensions) char m_Miroir; // vue normale / miroir @@ -31,6 +31,18 @@ public: TEXTE_MODULE( MODULE* parent, int text_type = TEXT_is_DIVERS ); ~TEXTE_MODULE(); + /** + * Function GetPosition + * returns the position of this object. + * Required by pure virtual BOARD_ITEM::GetPosition() + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Pos; + } + + /* supprime du chainage la structure Struct */ void UnLink(); diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 30846636b5..080d07620d 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -144,21 +144,6 @@ bool TRACK::IsNull() } -/*************************************************************/ -double TRACK::GetLength() const -/*************************************************************/ -{ - int dx = m_Start.x - m_End.x; - int dy = m_Start.y - m_End.y; - - double dist = ( (double) dx * dx ) + ( (double) dy * dy ); - - dist = sqrt( dist ); - - return dist; -} - - /*************************************************************/ int TRACK::IsPointOnEnds( const wxPoint& point, int min_dist ) /*************************************************************/ diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index a1113c5317..e5b681f254 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -55,6 +55,16 @@ public: TRACK* Back() const { return (TRACK*) Pback; } + /** + * Function GetPosition + * returns the position of this object. + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Start; // it had to be start or end. + } + /* supprime du chainage la structure Struct */ void UnLink(); @@ -122,7 +132,12 @@ public: * returns the length of the track using the hypotenuse calculation. * @return double - the length of the track */ - double GetLength() const; + double GetLength() const + { + int dx = m_Start.x - m_End.x; + int dy = m_Start.y - m_End.y; + return hypot( dx, dy ); + } /* Display on screen: */ @@ -255,8 +270,16 @@ public: void SetLayerPair( int top_layer, int bottom_layer ); void ReturnLayerPair( int* top_layer, int* bottom_layer ) const; - const wxPoint& GetPos() const { return m_Start; } - void SetPos( const wxPoint& aPoint ) { m_Start=aPoint; m_End=aPoint; } + /** + * Function GetPosition + * returns the position of this object. + * @return const wxPoint& - The position of this object. + */ + wxPoint& GetPosition() + { + return m_Start; + } + void SetPosition( const wxPoint& aPoint ) { m_Start=aPoint; m_End=aPoint; } /** * Function GetClass diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 5016a95707..8cbadd0fea 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -985,12 +985,12 @@ static void ConnectDanglingEndToVia( BOARD* pcb ) // if the other track's m_End does not match the via position, and the track's m_Start is // within the bounds of the via, and the other track has no start - if( other->m_End!=via->GetPos() && via->HitTest( other->m_Start ) && !other->start ) + if( other->m_End!=via->GetPosition() && via->HitTest( other->m_Start ) && !other->start ) { TRACK* newTrack = other->Copy(); newTrack->Insert( pcb, other ); - newTrack->m_End = via->GetPos(); + newTrack->m_End = via->GetPosition(); newTrack->start = other; newTrack->end = via; @@ -1007,12 +1007,12 @@ static void ConnectDanglingEndToVia( BOARD* pcb ) // if the other track's m_Start does not match the via position, and the track's m_End is // within the bounds of the via, and the other track has no end - else if( other->m_Start!=via->GetPos() && via->HitTest( other->m_End ) && !other->end ) + else if( other->m_Start!=via->GetPosition() && via->HitTest( other->m_End ) && !other->end ) { TRACK* newTrack = other->Copy(); newTrack->Insert( pcb, other ); - newTrack->m_Start = via->GetPos(); + newTrack->m_Start = via->GetPosition(); newTrack->start = via; newTrack->end = other; diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 54fe970287..b3dccd8271 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -58,7 +58,7 @@ void RemoteCommand( const char* cmdline ) frame->DrawPanel->PrepareGraphicContext( &dc ); frame->DrawPanel->CursorOff( &dc ); - frame->GetScreen()->m_Curseur = module->m_Pos; + frame->GetScreen()->m_Curseur = module->GetPosition(); frame->DrawPanel->CursorOn( &dc ); } } @@ -96,7 +96,7 @@ void RemoteCommand( const char* cmdline ) frame->Hight_Light( &dc ); /* hightlighted the new one */ frame->DrawPanel->CursorOff( &dc ); - frame->GetScreen()->m_Curseur = pad->m_Pos; + frame->GetScreen()->m_Curseur = pad->GetPosition(); frame->DrawPanel->CursorOn( &dc ); } diff --git a/pcbnew/dialog_drc.cpp b/pcbnew/dialog_drc.cpp index 10f9b4eb30..09e448f330 100644 --- a/pcbnew/dialog_drc.cpp +++ b/pcbnew/dialog_drc.cpp @@ -123,63 +123,62 @@ public: /*! - * WinEDA_DrcFrame type definition + * DrcDialog type definition */ -IMPLEMENT_DYNAMIC_CLASS( WinEDA_DrcFrame, wxDialog ) +IMPLEMENT_DYNAMIC_CLASS( DrcDialog, wxDialog ) /*! - * WinEDA_DrcFrame event table definition + * DrcDialog event table definition */ -BEGIN_EVENT_TABLE( WinEDA_DrcFrame, wxDialog ) +BEGIN_EVENT_TABLE( DrcDialog, wxDialog ) -////@begin WinEDA_DrcFrame event table entries - EVT_INIT_DIALOG( WinEDA_DrcFrame::OnInitDialog ) +////@begin DrcDialog event table entries + EVT_INIT_DIALOG( DrcDialog::OnInitDialog ) + EVT_WINDOW_DESTROY( DrcDialog::OnDestroy ) - EVT_CHECKBOX( ID_CHECKBOX, WinEDA_DrcFrame::OnReportCheckBoxClicked ) + EVT_CHECKBOX( ID_CHECKBOX, DrcDialog::OnReportCheckBoxClicked ) - EVT_BUTTON( ID_BUTTON_BROWSE_RPT_FILE, WinEDA_DrcFrame::OnButtonBrowseRptFileClick ) + EVT_BUTTON( ID_BUTTON_BROWSE_RPT_FILE, DrcDialog::OnButtonBrowseRptFileClick ) - EVT_BUTTON( ID_STARTDRC, WinEDA_DrcFrame::OnStartdrcClick ) + EVT_BUTTON( ID_STARTDRC, DrcDialog::OnStartdrcClick ) - EVT_BUTTON( ID_LIST_UNCONNECTED, WinEDA_DrcFrame::OnListUnconnectedClick ) + EVT_BUTTON( ID_LIST_UNCONNECTED, DrcDialog::OnListUnconnectedClick ) - EVT_BUTTON( ID_DELETE_ALL, WinEDA_DrcFrame::OnDeleteAllClick ) + EVT_BUTTON( ID_DELETE_ALL, DrcDialog::OnDeleteAllClick ) - EVT_BUTTON( wxID_CANCEL, WinEDA_DrcFrame::OnCancelClick ) + EVT_BUTTON( wxID_CANCEL, DrcDialog::OnCancelClick ) - EVT_BUTTON( wxID_OK, WinEDA_DrcFrame::OnOkClick ) + EVT_BUTTON( wxID_OK, DrcDialog::OnOkClick ) -////@end WinEDA_DrcFrame event table entries +////@end DrcDialog event table entries // outside bracket: DialogBlocks does not know about the listbox events on a custom list box. - EVT_LISTBOX( ID_CLEARANCE_LIST, WinEDA_DrcFrame::OnMarkerSelectionEvent) - EVT_LISTBOX( ID_UNCONNECTED_LIST, WinEDA_DrcFrame::OnUnconnectedSelectionEvent) + EVT_LISTBOX( ID_CLEARANCE_LIST, DrcDialog::OnMarkerSelectionEvent) + EVT_LISTBOX( ID_UNCONNECTED_LIST, DrcDialog::OnUnconnectedSelectionEvent) END_EVENT_TABLE() /*! - * WinEDA_DrcFrame constructors + * DrcDialog constructors */ -WinEDA_DrcFrame::WinEDA_DrcFrame( ) +DrcDialog::DrcDialog( ) { } -WinEDA_DrcFrame::WinEDA_DrcFrame( DRC_TESTER* aDrc_tester, WinEDA_PcbFrame* parent, wxDC * panelDC, +DrcDialog::DrcDialog( DRC* aTester, WinEDA_PcbFrame* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { - m_Tester = aDrc_tester; + m_tester = aTester; m_Parent = parent; - m_DC = panelDC; - AbortDrc = FALSE; Create(parent, id, caption, pos, size, style); @@ -191,9 +190,9 @@ WinEDA_DrcFrame::WinEDA_DrcFrame( DRC_TESTER* aDrc_tester, WinEDA_PcbFrame* pare * WinEDA_DrcFrame creator */ -bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) +bool DrcDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) { -////@begin WinEDA_DrcFrame member initialisation +////@begin DrcDialog member initialisation m_MainSizer = NULL; m_CommandSizer = NULL; m_ClearenceTitle = NULL; @@ -202,16 +201,17 @@ bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& c m_RptFilenameCtrl = NULL; m_BrowseButton = NULL; m_Pad2PadTestCtrl = NULL; - m_UnconnectedTestCtrl = NULL; m_ZonesTestCtrl = NULL; + m_UnconnectedTestCtrl = NULL; + m_DeleteAllButton = NULL; m_DeleteCurrentMarkerButton = NULL; m_ClearanceListBox = NULL; m_UnconnectedListBox = NULL; StdDialogButtonSizer = NULL; -////@end WinEDA_DrcFrame member initialisation +////@end DrcDialog member initialisation -////@begin WinEDA_DrcFrame creation +////@begin DrcDialog creation SetExtraStyle(wxWS_EX_BLOCK_EVENTS); wxDialog::Create( parent, id, caption, pos, size, style ); @@ -221,7 +221,7 @@ bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& c GetSizer()->SetSizeHints(this); } Centre(); -////@end WinEDA_DrcFrame creation +////@end DrcDialog creation // m_ClearanceListBox->SetList( &gList ); @@ -234,14 +234,14 @@ bool WinEDA_DrcFrame::Create( wxWindow* parent, wxWindowID id, const wxString& c * Control creation for WinEDA_DrcFrame */ -void WinEDA_DrcFrame::CreateControls() +void DrcDialog::CreateControls() { SetFont( *g_DialogFont ); -////@begin WinEDA_DrcFrame content construction - // Generated by DialogBlocks, Tue 27 Nov 2007 00:10:16 CST (unregistered) +////@begin DrcDialog content construction + // Generated by DialogBlocks, Fri 30 Nov 2007 18:52:20 CST (unregistered) - WinEDA_DrcFrame* itemDialog1 = this; + DrcDialog* itemDialog1 = this; m_MainSizer = new wxBoxSizer(wxVERTICAL); itemDialog1->SetSizer(m_MainSizer); @@ -251,7 +251,7 @@ void WinEDA_DrcFrame::CreateControls() wxStaticBox* itemStaticBoxSizer4Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Options")); wxStaticBoxSizer* itemStaticBoxSizer4 = new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxHORIZONTAL); - m_CommandSizer->Add(itemStaticBoxSizer4, 20, wxGROW|wxTOP|wxBOTTOM, 8); + m_CommandSizer->Add(itemStaticBoxSizer4, 3, wxGROW|wxTOP|wxBOTTOM, 8); wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxVERTICAL); itemStaticBoxSizer4->Add(itemBoxSizer5, 2, wxGROW|wxALL, 5); @@ -262,139 +262,138 @@ void WinEDA_DrcFrame::CreateControls() m_ClearenceTitle = new wxStaticText( itemDialog1, wxID_STATIC, _("Clearance"), wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE ); itemBoxSizer6->Add(m_ClearenceTitle, 0, wxALIGN_TOP|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); - itemBoxSizer6->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10); - m_SetClearance = new wxTextCtrl( itemDialog1, ID_TEXTCTRL1, _T(""), wxDefaultPosition, wxSize(144, -1), 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) + if (DrcDialog::ShowToolTips()) m_SetClearance->SetToolTip(_("In the clearance units, enter the clearance distance")); itemBoxSizer6->Add(m_SetClearance, 1, wxALIGN_TOP|wxLEFT|wxRIGHT|wxBOTTOM|wxADJUST_MINSIZE, 5); - wxStaticBox* itemStaticBoxSizer10Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Create Report File")); - wxStaticBoxSizer* itemStaticBoxSizer10 = new wxStaticBoxSizer(itemStaticBoxSizer10Static, wxHORIZONTAL); - itemBoxSizer5->Add(itemStaticBoxSizer10, 1, wxGROW|wxALL, 5); + wxStaticBox* itemStaticBoxSizer9Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Create Report File")); + wxStaticBoxSizer* itemStaticBoxSizer9 = new wxStaticBoxSizer(itemStaticBoxSizer9Static, wxHORIZONTAL); + itemBoxSizer5->Add(itemStaticBoxSizer9, 1, wxGROW|wxALL, 5); m_CreateRptCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX, _T(""), wxDefaultPosition, wxDefaultSize, 0 ); m_CreateRptCtrl->SetValue(false); - if (WinEDA_DrcFrame::ShowToolTips()) + if (DrcDialog::ShowToolTips()) m_CreateRptCtrl->SetToolTip(_("Enable writing report to this file")); - itemStaticBoxSizer10->Add(m_CreateRptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); + itemStaticBoxSizer9->Add(m_CreateRptCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxTOP|wxBOTTOM, 5); m_RptFilenameCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL3, _T(""), wxDefaultPosition, wxSize(250, -1), 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) + if (DrcDialog::ShowToolTips()) m_RptFilenameCtrl->SetToolTip(_("Enter the report filename")); - itemStaticBoxSizer10->Add(m_RptFilenameCtrl, 2, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5); + itemStaticBoxSizer9->Add(m_RptFilenameCtrl, 2, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM, 5); m_BrowseButton = new wxButton( itemDialog1, ID_BUTTON_BROWSE_RPT_FILE, _("..."), wxDefaultPosition, wxSize(35, -1), 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) + if (DrcDialog::ShowToolTips()) m_BrowseButton->SetToolTip(_("Pick a filename interactively")); - itemStaticBoxSizer10->Add(m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM|wxADJUST_MINSIZE, 5); + itemStaticBoxSizer9->Add(m_BrowseButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxTOP|wxBOTTOM|wxADJUST_MINSIZE, 5); - wxStaticBox* itemStaticBoxSizer14Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Include Tests For:")); - wxStaticBoxSizer* itemStaticBoxSizer14 = new wxStaticBoxSizer(itemStaticBoxSizer14Static, wxVERTICAL); - itemStaticBoxSizer4->Add(itemStaticBoxSizer14, 0, wxGROW|wxALL, 5); + wxStaticBox* itemStaticBoxSizer13Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Include Tests For:")); + wxStaticBoxSizer* itemStaticBoxSizer13 = new wxStaticBoxSizer(itemStaticBoxSizer13Static, wxVERTICAL); + itemStaticBoxSizer4->Add(itemStaticBoxSizer13, 0, wxGROW|wxALL, 5); - m_Pad2PadTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX2, _("Clearances"), wxDefaultPosition, wxDefaultSize, 0 ); + m_Pad2PadTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX2, _("Pad to pad"), wxDefaultPosition, wxDefaultSize, 0 ); m_Pad2PadTestCtrl->SetValue(false); - if (WinEDA_DrcFrame::ShowToolTips()) - m_Pad2PadTestCtrl->SetToolTip(_("Test pad to pad, pad to track, and track to track clearances")); - itemStaticBoxSizer14->Add(m_Pad2PadTestCtrl, 0, wxGROW|wxALL, 5); - - m_UnconnectedTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX3, _("Unconnected"), wxDefaultPosition, wxDefaultSize, 0 ); - m_UnconnectedTestCtrl->SetValue(false); - if (WinEDA_DrcFrame::ShowToolTips()) - m_UnconnectedTestCtrl->SetToolTip(_("Find unconnected pads and tracks")); - itemStaticBoxSizer14->Add(m_UnconnectedTestCtrl, 0, wxGROW|wxALL, 5); + if (DrcDialog::ShowToolTips()) + m_Pad2PadTestCtrl->SetToolTip(_("Include tests for clearances between pad to pads")); + itemStaticBoxSizer13->Add(m_Pad2PadTestCtrl, 0, wxGROW|wxALL, 5); m_ZonesTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX7, _("Zones"), wxDefaultPosition, wxDefaultSize, 0 ); m_ZonesTestCtrl->SetValue(false); - if (WinEDA_DrcFrame::ShowToolTips()) + if (DrcDialog::ShowToolTips()) m_ZonesTestCtrl->SetToolTip(_("Include zones in clearance or unconnected tests")); - itemStaticBoxSizer14->Add(m_ZonesTestCtrl, 0, wxGROW|wxALL, 5); + itemStaticBoxSizer13->Add(m_ZonesTestCtrl, 0, wxGROW|wxALL, 5); - wxBoxSizer* itemBoxSizer18 = new wxBoxSizer(wxVERTICAL); - m_CommandSizer->Add(itemBoxSizer18, 0, wxALIGN_TOP|wxALL, 5); + m_UnconnectedTestCtrl = new wxCheckBox( itemDialog1, ID_CHECKBOX3, _("Unconnected pads"), wxDefaultPosition, wxDefaultSize, 0 ); + m_UnconnectedTestCtrl->SetValue(false); + if (DrcDialog::ShowToolTips()) + m_UnconnectedTestCtrl->SetToolTip(_("Find unconnected pads")); + itemStaticBoxSizer13->Add(m_UnconnectedTestCtrl, 0, wxGROW|wxALL, 5); - wxButton* itemButton19 = new wxButton( itemDialog1, ID_STARTDRC, _("Start DRC"), wxDefaultPosition, wxDefaultSize, 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) - itemButton19->SetToolTip(_("Start the Design Rule Checker")); - itemButton19->SetForegroundColour(wxColour(202, 0, 0)); - itemBoxSizer18->Add(itemButton19, 0, wxGROW|wxALL, 5); + wxBoxSizer* itemBoxSizer17 = new wxBoxSizer(wxVERTICAL); + m_CommandSizer->Add(itemBoxSizer17, 0, wxALIGN_TOP|wxALL, 5); - wxButton* itemButton20 = new wxButton( itemDialog1, ID_LIST_UNCONNECTED, _("List Unconnected"), wxDefaultPosition, wxDefaultSize, 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) - itemButton20->SetToolTip(_("List unconnected pads or tracks")); - itemButton20->SetForegroundColour(wxColour(0, 0, 255)); - itemBoxSizer18->Add(itemButton20, 0, wxGROW|wxALL, 5); + wxButton* itemButton18 = new wxButton( itemDialog1, ID_STARTDRC, _("Start DRC"), wxDefaultPosition, wxDefaultSize, 0 ); + if (DrcDialog::ShowToolTips()) + itemButton18->SetToolTip(_("Start the Design Rule Checker")); + itemButton18->SetForegroundColour(wxColour(202, 0, 0)); + itemBoxSizer17->Add(itemButton18, 0, wxGROW|wxALL, 5); - wxButton* itemButton21 = new wxButton( itemDialog1, ID_DELETE_ALL, _("Delete All Markers"), wxDefaultPosition, wxDefaultSize, 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) - itemButton21->SetToolTip(_("Delete every marker")); - itemButton21->SetForegroundColour(wxColour(0, 128, 0)); - itemBoxSizer18->Add(itemButton21, 0, wxGROW|wxALL, 5); + wxButton* itemButton19 = new wxButton( itemDialog1, ID_LIST_UNCONNECTED, _("List Unconnected"), wxDefaultPosition, wxDefaultSize, 0 ); + if (DrcDialog::ShowToolTips()) + itemButton19->SetToolTip(_("List unconnected pads or tracks")); + itemButton19->SetForegroundColour(wxColour(0, 0, 255)); + itemBoxSizer17->Add(itemButton19, 0, wxGROW|wxALL, 5); + + m_DeleteAllButton = new wxButton( itemDialog1, ID_DELETE_ALL, _("Delete All Markers"), wxDefaultPosition, wxDefaultSize, 0 ); + if (DrcDialog::ShowToolTips()) + m_DeleteAllButton->SetToolTip(_("Delete every marker")); + m_DeleteAllButton->SetForegroundColour(wxColour(0, 128, 0)); + itemBoxSizer17->Add(m_DeleteAllButton, 0, wxGROW|wxALL, 5); m_DeleteCurrentMarkerButton = new wxButton( itemDialog1, ID_DELETE_ONE, _("Delete Current Marker"), wxDefaultPosition, wxDefaultSize, 0 ); - if (WinEDA_DrcFrame::ShowToolTips()) + if (DrcDialog::ShowToolTips()) m_DeleteCurrentMarkerButton->SetToolTip(_("Delete the marker selected in the listBox below")); m_DeleteCurrentMarkerButton->Enable(false); - itemBoxSizer18->Add(m_DeleteCurrentMarkerButton, 0, wxGROW|wxALL, 5); + itemBoxSizer17->Add(m_DeleteCurrentMarkerButton, 0, wxGROW|wxALL, 5); - wxStaticText* itemStaticText23 = new wxStaticText( itemDialog1, wxID_STATIC, _("Error Messages:"), wxDefaultPosition, wxDefaultSize, 0 ); - m_MainSizer->Add(itemStaticText23, 0, wxGROW|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 10); + wxStaticText* itemStaticText22 = new wxStaticText( itemDialog1, wxID_STATIC, _("Error Messages:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_MainSizer->Add(itemStaticText22, 0, wxGROW|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 10); - wxNotebook* itemNotebook24 = new wxNotebook( itemDialog1, ID_NOTEBOOK1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT|wxRAISED_BORDER ); + wxNotebook* itemNotebook23 = new wxNotebook( itemDialog1, ID_NOTEBOOK1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT|wxRAISED_BORDER ); #if !wxCHECK_VERSION(2,5,2) - wxNotebookSizer* itemNotebook24Sizer = new wxNotebookSizer(itemNotebook24); + wxNotebookSizer* itemNotebook23Sizer = new wxNotebookSizer(itemNotebook23); #endif - m_ClearanceListBox = new DRCLISTBOX( itemNotebook24, ID_CLEARANCE_LIST, wxDefaultPosition, wxSize(100, 300), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL ); - if (WinEDA_DrcFrame::ShowToolTips()) + m_ClearanceListBox = new DRCLISTBOX( itemNotebook23, ID_CLEARANCE_LIST, wxDefaultPosition, wxSize(100, 300), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL ); + if (DrcDialog::ShowToolTips()) m_ClearanceListBox->SetToolTip(_("MARKERs on the PCB, double click on any MARKER to go there in PCB")); - itemNotebook24->AddPage(m_ClearanceListBox, _("Distance Problem Markers")); + itemNotebook23->AddPage(m_ClearanceListBox, _("Distance Problem Markers")); - m_UnconnectedListBox = new DRCLISTBOX( itemNotebook24, ID_UNCONNECTED_LIST, wxDefaultPosition, wxSize(100, 100), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL ); - if (WinEDA_DrcFrame::ShowToolTips()) + m_UnconnectedListBox = new DRCLISTBOX( itemNotebook23, ID_UNCONNECTED_LIST, wxDefaultPosition, wxSize(100, 100), wxSUNKEN_BORDER|wxHSCROLL|wxVSCROLL ); + if (DrcDialog::ShowToolTips()) m_UnconnectedListBox->SetToolTip(_("Pad to pad, pad to track, and track to track clearance problems")); - itemNotebook24->AddPage(m_UnconnectedListBox, _("Unconnected")); + itemNotebook23->AddPage(m_UnconnectedListBox, _("Unconnected")); #if !wxCHECK_VERSION(2,5,2) - m_MainSizer->Add(itemNotebook24Sizer, 5, wxGROW|wxALL, 5); + m_MainSizer->Add(itemNotebook23Sizer, 5, wxGROW|wxALL, 5); #else - m_MainSizer->Add(itemNotebook24, 5, wxGROW|wxALL, 5); + m_MainSizer->Add(itemNotebook23, 5, wxGROW|wxALL, 5); #endif StdDialogButtonSizer = new wxStdDialogButtonSizer; m_MainSizer->Add(StdDialogButtonSizer, 0, wxGROW|wxALL, 10); - wxButton* itemButton28 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton28->SetForegroundColour(wxColour(0, 0, 255)); - StdDialogButtonSizer->AddButton(itemButton28); + wxButton* itemButton27 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton27->SetForegroundColour(wxColour(0, 0, 255)); + StdDialogButtonSizer->AddButton(itemButton27); - wxButton* itemButton29 = new wxButton( itemDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton29->SetDefault(); - StdDialogButtonSizer->AddButton(itemButton29); + wxButton* itemButton28 = new wxButton( itemDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton28->SetDefault(); + StdDialogButtonSizer->AddButton(itemButton28); StdDialogButtonSizer->Realize(); - // Set validators - m_CreateRptCtrl->SetValidator( wxGenericValidator(& s_CreateRptFileOpt) ); - m_Pad2PadTestCtrl->SetValidator( wxGenericValidator(& s_Pad2PadTestOpt) ); - m_UnconnectedTestCtrl->SetValidator( wxGenericValidator(& s_UnconnectedTestOpt) ); - m_ZonesTestCtrl->SetValidator( wxGenericValidator(& s_ZonesTestOpt) ); // Connect events and objects - m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(WinEDA_DrcFrame::OnLeftDClickClearance), NULL, this); - m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(WinEDA_DrcFrame::OnRightUpClearance), NULL, this); - m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(WinEDA_DrcFrame::OnLeftDClickUnconnected), NULL, this); - m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(WinEDA_DrcFrame::OnRightUpUnconnected), NULL, this); -////@end WinEDA_DrcFrame content construction + itemDialog1->Connect(ID_DIALOG, wxEVT_DESTROY, wxWindowDestroyEventHandler(DrcDialog::OnDestroy), NULL, this); + m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(DrcDialog::OnLeftDClickClearance), NULL, this); + m_ClearanceListBox->Connect(ID_CLEARANCE_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(DrcDialog::OnRightUpClearance), NULL, this); + m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_LEFT_DCLICK, wxMouseEventHandler(DrcDialog::OnLeftDClickUnconnected), NULL, this); + m_UnconnectedListBox->Connect(ID_UNCONNECTED_LIST, wxEVT_RIGHT_UP, wxMouseEventHandler(DrcDialog::OnRightUpUnconnected), NULL, this); +////@end DrcDialog content construction + + // @todo this is expanding the Clearance text, so we need to recalc sizers. + AddUnitSymbol(*m_ClearenceTitle); + + Layout(); // adding the units above expanded Clearance text, now resize. } /*! * Should we show tooltips? */ -bool WinEDA_DrcFrame::ShowToolTips() +bool DrcDialog::ShowToolTips() { return true; } @@ -403,34 +402,34 @@ bool WinEDA_DrcFrame::ShowToolTips() * Get bitmap resources */ -wxBitmap WinEDA_DrcFrame::GetBitmapResource( const wxString& name ) +wxBitmap DrcDialog::GetBitmapResource( const wxString& name ) { // Bitmap retrieval -////@begin WinEDA_DrcFrame bitmap retrieval +////@begin DrcDialog bitmap retrieval wxUnusedVar(name); return wxNullBitmap; -////@end WinEDA_DrcFrame bitmap retrieval +////@end DrcDialog bitmap retrieval } /*! * Get icon resources */ -wxIcon WinEDA_DrcFrame::GetIconResource( const wxString& name ) +wxIcon DrcDialog::GetIconResource( const wxString& name ) { // Icon retrieval -////@begin WinEDA_DrcFrame icon retrieval +////@begin DrcDialog icon retrieval wxUnusedVar(name); return wxNullIcon; -////@end WinEDA_DrcFrame icon retrieval +////@end DrcDialog icon retrieval } /*! * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DRC_RUN */ -void WinEDA_DrcFrame::OnStartdrcClick( wxCommandEvent& event ) +void DrcDialog::OnStartdrcClick( wxCommandEvent& event ) { - TestDrc(event); + CmdDrc(); } /*! @@ -438,7 +437,7 @@ void WinEDA_DrcFrame::OnStartdrcClick( wxCommandEvent& event ) */ /* -void WinEDA_DrcFrame::OnStopControlDrcClick( wxCommandEvent& event ) +void DrcDialog::OnStopControlDrcClick( wxCommandEvent& event ) { if( DrcInProgress ) AbortDrc = TRUE; @@ -451,7 +450,7 @@ void WinEDA_DrcFrame::OnStopControlDrcClick( wxCommandEvent& event ) * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_ERASE_DRC_MARKERS */ -void WinEDA_DrcFrame::OnDeleteAllClick( wxCommandEvent& event ) +void DrcDialog::OnDeleteAllClick( wxCommandEvent& event ) { DelDRCMarkers(event); } @@ -460,7 +459,7 @@ void WinEDA_DrcFrame::OnDeleteAllClick( wxCommandEvent& event ) * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIST_UNCONNECTED_PADS */ -void WinEDA_DrcFrame::OnListUnconnectedClick( wxCommandEvent& event ) +void DrcDialog::OnListUnconnectedClick( wxCommandEvent& event ) { ListUnconnectedPads(event); } @@ -469,7 +468,7 @@ void WinEDA_DrcFrame::OnListUnconnectedClick( wxCommandEvent& event ) * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON_BROWSE_RPT_FILE */ -void WinEDA_DrcFrame::OnButtonBrowseRptFileClick( wxCommandEvent& event ) +void DrcDialog::OnButtonBrowseRptFileClick( wxCommandEvent& event ) { wxString FileName; wxString Mask(wxT("*")); @@ -492,7 +491,6 @@ void WinEDA_DrcFrame::OnButtonBrowseRptFileClick( wxCommandEvent& event ) return; m_RptFilenameCtrl->SetValue(FileName); - s_RptFilename = FileName; } @@ -500,12 +498,8 @@ void WinEDA_DrcFrame::OnButtonBrowseRptFileClick( wxCommandEvent& event ) * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK */ -void WinEDA_DrcFrame::OnOkClick( wxCommandEvent& event ) +void DrcDialog::OnOkClick( wxCommandEvent& event ) { - s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked(); - s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked(); - s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked(); - s_CreateRptFileOpt = m_CreateRptCtrl->IsChecked(); event.Skip(); } @@ -514,7 +508,7 @@ void WinEDA_DrcFrame::OnOkClick( wxCommandEvent& event ) * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL */ -void WinEDA_DrcFrame::OnCancelClick( wxCommandEvent& event ) +void DrcDialog::OnCancelClick( wxCommandEvent& event ) { ////@begin wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_DrcFrame. // Before editing this code, remove the block markers. @@ -527,10 +521,8 @@ void WinEDA_DrcFrame::OnCancelClick( wxCommandEvent& event ) * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_CHECKBOX1 */ -void WinEDA_DrcFrame::OnReportCheckBoxClicked( wxCommandEvent& event ) +void DrcDialog::OnReportCheckBoxClicked( wxCommandEvent& event ) { - // @todo: see if the checkbox is selected, if so, enable the report name field - // and browse button, else disable them. if( m_CreateRptCtrl->IsChecked() ) { m_RptFilenameCtrl->Enable(true); @@ -549,21 +541,18 @@ void WinEDA_DrcFrame::OnReportCheckBoxClicked( wxCommandEvent& event ) * wxEVT_INIT_DIALOG event handler for ID_DIALOG */ -void WinEDA_DrcFrame::OnInitDialog( wxInitDialogEvent& event ) +void DrcDialog::OnInitDialog( wxInitDialogEvent& event ) { wxCommandEvent junk; - // Set the initial status of the browse button and the text + // Set the initial "enabled" status of the browse button and the text // field for report name OnReportCheckBoxClicked( junk ); - AddUnitSymbol(*m_ClearenceTitle); - m_RptFilenameCtrl->SetValue(s_RptFilename); - m_SetClearance->SetFocus(); // deselect the existing text, seems SetFocus() wants to emulate - // Microsoft, which is not desireable here. + // Microsoft and select all text, which is not desireable here. m_SetClearance->SetSelection(0,0); event.Skip(); @@ -574,7 +563,7 @@ void WinEDA_DrcFrame::OnInitDialog( wxInitDialogEvent& event ) * wxEVT_LEFT_DCLICK event handler for ID_CLEARANCE_LIST */ -void WinEDA_DrcFrame::OnLeftDClickClearance( wxMouseEvent& event ) +void DrcDialog::OnLeftDClickClearance( wxMouseEvent& event ) { int selection = m_ClearanceListBox->GetSelection(); @@ -595,7 +584,7 @@ void WinEDA_DrcFrame::OnLeftDClickClearance( wxMouseEvent& event ) * wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST */ -void WinEDA_DrcFrame::OnRightUpUnconnected( wxMouseEvent& event ) +void DrcDialog::OnRightUpUnconnected( wxMouseEvent& event ) { event.Skip(); } @@ -605,7 +594,7 @@ void WinEDA_DrcFrame::OnRightUpUnconnected( wxMouseEvent& event ) * wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST */ -void WinEDA_DrcFrame::OnRightUpClearance( wxMouseEvent& event ) +void DrcDialog::OnRightUpClearance( wxMouseEvent& event ) { ////@begin wxEVT_RIGHT_UP event handler for ID_CLEARANCE_LIST in WinEDA_DrcFrame. // Before editing this code, remove the block markers. @@ -618,7 +607,7 @@ void WinEDA_DrcFrame::OnRightUpClearance( wxMouseEvent& event ) * wxEVT_LEFT_DCLICK event handler for ID_UNCONNECTED_LIST */ -void WinEDA_DrcFrame::OnLeftDClickUnconnected( wxMouseEvent& event ) +void DrcDialog::OnLeftDClickUnconnected( wxMouseEvent& event ) { int selection = m_UnconnectedListBox->GetSelection(); @@ -631,7 +620,7 @@ void WinEDA_DrcFrame::OnLeftDClickUnconnected( wxMouseEvent& event ) } -void WinEDA_DrcFrame::OnMarkerSelectionEvent( wxCommandEvent& event ) +void DrcDialog::OnMarkerSelectionEvent( wxCommandEvent& event ) { int selection = event.GetSelection(); @@ -645,7 +634,7 @@ void WinEDA_DrcFrame::OnMarkerSelectionEvent( wxCommandEvent& event ) event.Skip(); } -void WinEDA_DrcFrame::OnUnconnectedSelectionEvent( wxCommandEvent& event ) +void DrcDialog::OnUnconnectedSelectionEvent( wxCommandEvent& event ) { int selection = event.GetSelection(); @@ -657,3 +646,16 @@ void WinEDA_DrcFrame::OnUnconnectedSelectionEvent( wxCommandEvent& event ) event.Skip(); } + +/*! + * wxEVT_DESTROY event handler for ID_DIALOG + */ + +void DrcDialog::OnDestroy( wxWindowDestroyEvent& event ) +{ +////@begin wxEVT_DESTROY event handler for ID_DIALOG in WinEDA_DrcFrame. + // Before editing this code, remove the block markers. + event.Skip(); +////@end wxEVT_DESTROY event handler for ID_DIALOG in WinEDA_DrcFrame. +} + diff --git a/pcbnew/dialog_drc.h b/pcbnew/dialog_drc.h index 2206354fa3..b109e9dfd0 100644 --- a/pcbnew/dialog_drc.h +++ b/pcbnew/dialog_drc.h @@ -23,7 +23,6 @@ */ ////@begin includes -#include "wx/valgen.h" #include "wx/notebook.h" ////@end includes @@ -50,8 +49,8 @@ class wxStdDialogButtonSizer; #define ID_TEXTCTRL3 10014 #define ID_BUTTON_BROWSE_RPT_FILE 10018 #define ID_CHECKBOX2 10019 -#define ID_CHECKBOX3 10020 #define ID_CHECKBOX7 10021 +#define ID_CHECKBOX3 10011 #define ID_STARTDRC 10006 #define ID_LIST_UNCONNECTED 10003 #define ID_DELETE_ALL 10005 @@ -59,14 +58,14 @@ class wxStdDialogButtonSizer; #define ID_NOTEBOOK1 10008 #define ID_CLEARANCE_LIST 10001 #define ID_UNCONNECTED_LIST 10009 -#define SYMBOL_WINEDA_DRCFRAME_STYLE wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER -#define SYMBOL_WINEDA_DRCFRAME_TITLE _("DRC Control") -#define SYMBOL_WINEDA_DRCFRAME_IDNAME ID_DIALOG -#define SYMBOL_WINEDA_DRCFRAME_SIZE wxSize(400, 300) -#define SYMBOL_WINEDA_DRCFRAME_POSITION wxDefaultPosition +#define SYMBOL_DRCDIALOG_STYLE wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX +#define SYMBOL_DRCDIALOG_TITLE _("DRC Control") +#define SYMBOL_DRCDIALOG_IDNAME ID_DIALOG +#define SYMBOL_DRCDIALOG_SIZE wxSize(400, 300) +#define SYMBOL_DRCDIALOG_POSITION wxDefaultPosition ////@end control identifiers -#define ID_DRCLISTCTRL 10001 // outside @end control identifiers since DialogBlocks knows not DRCLISTBOX +#define ID_DRCLISTCTRL 14000 // outside @end control identifiers since DialogBlocks knows not DRCLISTBOX /*! * Compatibility @@ -77,35 +76,38 @@ class wxStdDialogButtonSizer; #endif /*! - * WinEDA_DrcFrame class declaration + * DrcDialog class declaration */ -class WinEDA_DrcFrame: public wxDialog +class DrcDialog: public wxDialog { - DECLARE_DYNAMIC_CLASS( WinEDA_DrcFrame ) + DECLARE_DYNAMIC_CLASS( DrcDialog ) DECLARE_EVENT_TABLE() public: /// Constructors - WinEDA_DrcFrame( ); - WinEDA_DrcFrame( DRC_TESTER* aDrc_tester, WinEDA_PcbFrame* parent, wxDC * panelDC, - wxWindowID id = SYMBOL_WINEDA_DRCFRAME_IDNAME, - const wxString& caption = SYMBOL_WINEDA_DRCFRAME_TITLE, - const wxPoint& pos = SYMBOL_WINEDA_DRCFRAME_POSITION, - const wxSize& size = SYMBOL_WINEDA_DRCFRAME_SIZE, - long style = SYMBOL_WINEDA_DRCFRAME_STYLE ); + DrcDialog( ); + DrcDialog( DRC* aTester, WinEDA_PcbFrame* parent, + wxWindowID id = SYMBOL_DRCDIALOG_IDNAME, + const wxString& caption = SYMBOL_DRCDIALOG_TITLE, + const wxPoint& pos = SYMBOL_DRCDIALOG_POSITION, + const wxSize& size = SYMBOL_DRCDIALOG_SIZE, + long style = SYMBOL_DRCDIALOG_STYLE ); /// Creation - bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WINEDA_DRCFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_DRCFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_DRCFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_DRCFRAME_SIZE, long style = SYMBOL_WINEDA_DRCFRAME_STYLE ); + bool Create( wxWindow* parent, wxWindowID id = SYMBOL_DRCDIALOG_IDNAME, const wxString& caption = SYMBOL_DRCDIALOG_TITLE, const wxPoint& pos = SYMBOL_DRCDIALOG_POSITION, const wxSize& size = SYMBOL_DRCDIALOG_SIZE, long style = SYMBOL_DRCDIALOG_STYLE ); /// Creates the controls and sizers void CreateControls(); -////@begin WinEDA_DrcFrame event handler declarations +////@begin DrcDialog event handler declarations /// wxEVT_INIT_DIALOG event handler for ID_DIALOG void OnInitDialog( wxInitDialogEvent& event ); + /// wxEVT_DESTROY event handler for ID_DIALOG + void OnDestroy( wxWindowDestroyEvent& event ); + /// wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_CHECKBOX void OnReportCheckBoxClicked( wxCommandEvent& event ); @@ -139,16 +141,16 @@ public: /// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_OK void OnOkClick( wxCommandEvent& event ); -////@end WinEDA_DrcFrame event handler declarations +////@end DrcDialog event handler declarations -////@begin WinEDA_DrcFrame member function declarations +////@begin DrcDialog member function declarations /// Retrieves bitmap resources wxBitmap GetBitmapResource( const wxString& name ); /// Retrieves icon resources wxIcon GetIconResource( const wxString& name ); -////@end WinEDA_DrcFrame member function declarations +////@end DrcDialog member function declarations void OnMarkerSelectionEvent( wxCommandEvent& event ); void OnUnconnectedSelectionEvent( wxCommandEvent& event ); @@ -156,11 +158,11 @@ public: /// Should we show tooltips? static bool ShowToolTips(); - void TestDrc(wxCommandEvent & event); + void CmdDrc(); void DelDRCMarkers(wxCommandEvent & event); void ListUnconnectedPads(wxCommandEvent & event); -////@begin WinEDA_DrcFrame member variables +////@begin DrcDialog member variables wxBoxSizer* m_MainSizer; wxBoxSizer* m_CommandSizer; wxStaticText* m_ClearenceTitle; @@ -169,18 +171,18 @@ public: wxTextCtrl* m_RptFilenameCtrl; wxButton* m_BrowseButton; wxCheckBox* m_Pad2PadTestCtrl; - wxCheckBox* m_UnconnectedTestCtrl; wxCheckBox* m_ZonesTestCtrl; + wxCheckBox* m_UnconnectedTestCtrl; + wxButton* m_DeleteAllButton; wxButton* m_DeleteCurrentMarkerButton; DRCLISTBOX* m_ClearanceListBox; DRCLISTBOX* m_UnconnectedListBox; wxStdDialogButtonSizer* StdDialogButtonSizer; -////@end WinEDA_DrcFrame member variables +////@end DrcDialog member variables - DRC_TESTER* m_Tester; + DRC* m_tester; WinEDA_PcbFrame* m_Parent; - wxDC* m_DC; int m_UnconnectedCount; }; diff --git a/pcbnew/dialog_drc.pjd b/pcbnew/dialog_drc.pjd index 79ca7daf91..42d499bca8 100644 --- a/pcbnew/dialog_drc.pjd +++ b/pcbnew/dialog_drc.pjd @@ -218,10 +218,11 @@ "" 0 0 - "wxEVT_INIT_DIALOG|OnInitDialog|NONE||WinEDA_DrcFrame" + "wxEVT_INIT_DIALOG|OnInitDialog|NONE||DrcDialog" + "wxEVT_DESTROY|OnDestroy|NONE||DrcDialog" "ID_DIALOG" 10000 - "WinEDA_DrcFrame" + "DrcDialog" "wxDialog" "wxDialog" "dialog_drc.cpp" @@ -253,8 +254,8 @@ 0 0 0 - 0 - 0 + 1 + 1 0 0 0 @@ -344,7 +345,7 @@ "Horizontal" "Expand" "Expand" - 20 + 3 8 0 0 @@ -474,32 +475,6 @@ "" "" - - "Spacer" - "dialog-control-document" - "" - "spacer" - 0 - 1 - 0 - 0 - "26/11/2007" - "wbSpacerProxy" - 5 - 5 - "Centre" - "Centre" - 0 - 10 - 1 - 1 - 0 - 0 - 0 - 0 - 0 - "<Any platform>" - "wxTextCtrl: ID_TEXTCTRL1" "dialog-control-document" @@ -628,13 +603,13 @@ 0 "25/11/2007" "wbCheckBoxProxy" - "wxEVT_COMMAND_CHECKBOX_CLICKED|OnReportCheckBoxClicked|NONE||WinEDA_DrcFrame" + "wxEVT_COMMAND_CHECKBOX_CLICKED|OnReportCheckBoxClicked|NONE||DrcDialog" "ID_CHECKBOX" 10004 "" "wxCheckBox" "wxCheckBox" - 1 + 0 0 "" "" @@ -643,8 +618,8 @@ 0 "" "Enable writing report to this file" - "s_CreateRptFileOpt" - "wxGenericValidator(& %VARIABLE%)" + "" + "" "" "" "" @@ -775,7 +750,7 @@ 0 "25/11/2007" "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnButtonBrowseRptFileClick|NONE||WinEDA_DrcFrame" + "wxEVT_COMMAND_BUTTON_CLICKED|OnButtonBrowseRptFileClick|NONE||DrcDialog" "ID_BUTTON_BROWSE_RPT_FILE" 10018 "" @@ -888,76 +863,12 @@ "" "" "m_Pad2PadTestCtrl" - "Clearances" + "Pad to pad" 0 "" - "Test pad to pad, pad to track, and track to track clearances" - "s_Pad2PadTestOpt" - "wxGenericValidator(& %VARIABLE%)" - "" - "" - "" - "" - "" - "" - "" - "" - 0 - 1 - "<Any platform>" - 0 - 0 - 0 - 0 - 0 - 0 - 0 - "" - -1 - -1 - -1 - -1 - "Expand" - "Centre" - 0 - 5 - 1 - 1 - 1 - 1 - 0 - 0 - 0 - "" - "" - - - "wxCheckBox: ID_CHECKBOX3" - "dialog-control-document" - "" - "checkbox" - 0 - 1 - 0 - 0 - "25/11/2007" - "wbCheckBoxProxy" - "ID_CHECKBOX3" - 10020 - "" - "wxCheckBox" - "wxCheckBox" - 1 - 0 - "" - "" - "m_UnconnectedTestCtrl" - "Unconnected" - 0 - "" - "Find unconnected pads and tracks" - "s_UnconnectedTestOpt" - "wxGenericValidator(& %VARIABLE%)" + "Include tests for clearances between pad to pads" + "" + "" "" "" "" @@ -1020,8 +931,72 @@ 0 "" "Include zones in clearance or unconnected tests" - "s_ZonesTestOpt" - "wxGenericValidator(& %VARIABLE%)" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + 0 + 1 + "<Any platform>" + 0 + 0 + 0 + 0 + 0 + 0 + 0 + "" + -1 + -1 + -1 + -1 + "Expand" + "Centre" + 0 + 5 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + "" + "" + + + "wxCheckBox: ID_CHECKBOX3" + "dialog-control-document" + "" + "checkbox" + 0 + 1 + 0 + 0 + "30/11/2007" + "wbCheckBoxProxy" + "ID_CHECKBOX3" + 10011 + "" + "wxCheckBox" + "wxCheckBox" + 1 + 0 + "" + "" + "m_UnconnectedTestCtrl" + "Unconnected pads" + 0 + "" + "Find unconnected pads" + "" + "" "" "" "" @@ -1097,7 +1072,7 @@ 0 "25/11/2007" "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnStartdrcClick|||WinEDA_DrcFrame" + "wxEVT_COMMAND_BUTTON_CLICKED|OnStartdrcClick|||DrcDialog" "ID_STARTDRC" 10006 "" @@ -1164,7 +1139,7 @@ 0 "25/11/2007" "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnListUnconnectedClick|||WinEDA_DrcFrame" + "wxEVT_COMMAND_BUTTON_CLICKED|OnListUnconnectedClick|||DrcDialog" "ID_LIST_UNCONNECTED" 10003 "" @@ -1231,7 +1206,7 @@ 0 "25/11/2007" "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnDeleteAllClick|||WinEDA_DrcFrame" + "wxEVT_COMMAND_BUTTON_CLICKED|OnDeleteAllClick|||DrcDialog" "ID_DELETE_ALL" 10005 "" @@ -1241,7 +1216,7 @@ 0 "" "" - "" + "m_DeleteAllButton" "Delete All Markers" 0 "" @@ -1511,8 +1486,8 @@ 0 "25/11/2007" "wbForeignCtrlProxy" - "wxEVT_LEFT_DCLICK|OnLeftDClickClearance|NONE||WinEDA_DrcFrame" - "wxEVT_RIGHT_UP|OnRightUpClearance|NONE||WinEDA_DrcFrame" + "wxEVT_LEFT_DCLICK|OnLeftDClickClearance|NONE||DrcDialog" + "wxEVT_RIGHT_UP|OnRightUpClearance|NONE||DrcDialog" "ID_CLEARANCE_LIST" 10001 "" @@ -1585,8 +1560,8 @@ 0 "25/11/2007" "wbForeignCtrlProxy" - "wxEVT_LEFT_DCLICK|OnLeftDClickUnconnected|NONE||WinEDA_DrcFrame" - "wxEVT_RIGHT_UP|OnRightUpUnconnected|NONE||WinEDA_DrcFrame" + "wxEVT_LEFT_DCLICK|OnLeftDClickUnconnected|NONE||DrcDialog" + "wxEVT_RIGHT_UP|OnRightUpUnconnected|NONE||DrcDialog" "ID_UNCONNECTED_LIST" 10009 "" @@ -1692,7 +1667,7 @@ 1 "13/11/2007" "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnCancelClick|NONE||WinEDA_DrcFrame" + "wxEVT_COMMAND_BUTTON_CLICKED|OnCancelClick|NONE||DrcDialog" "wxID_CANCEL" 5101 "" @@ -1759,7 +1734,7 @@ 1 "26/11/2007" "wbButtonProxy" - "wxEVT_COMMAND_BUTTON_CLICKED|OnOkClick|NONE||WinEDA_DrcFrame" + "wxEVT_COMMAND_BUTTON_CLICKED|OnOkClick|NONE||DrcDialog" "wxID_OK" 5100 "" diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 8d9cd3b16a..49be37258e 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -1,3 +1,30 @@ + +/* + * This program source code file is part of KICAD, a free EDA CAD application. + * + * Copyright (C) 2004-2007 Jean-Pierre Charras, jean-pierre.charras@inpg.fr + * Copyright (C) 2007 Dick Hollenbeck, dick@softplc.com + * Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + /****************************/ /* DRC control */ /****************************/ @@ -17,58 +44,156 @@ /* variables locales */ -class WinEDA_DrcFrame; -WinEDA_DrcFrame* DrcFrame; +class DrcDialog; -//#define WXYIELD() wxYield() -#define WXYIELD() do { } while(0) // nothing - - -/* 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 int ErrorsDRC_Count; -static MARKER* 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 */ - -/* 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, BOARD_ITEM* pt_item, int errnumber ); - -static void Affiche_Erreur_DRC( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, - D_PAD* pad1, D_PAD* pad2 ); - - -/*******************************************/ -/* DRC functions */ -/*******************************************/ #include "dialog_drc.cpp" +/******************************************************/ +void WinEDA_PcbFrame::Install_Test_DRC_Frame( wxDC* DC ) +/******************************************************/ + +/* install a dialog box to handle the general DRC control + */ +{ + m_drc->ShowDialog(); +} + + +void DRC::ShowDialog() +{ + updatePointers(); + + if( !m_ui ) + { +printf("creating new DrcFrame\n"); + m_ui = new DrcDialog( this, m_mainWindow ); + } + + + // @todo enter retentitive data into the panel. +// m_RptFilenameCtrl->SetValue(s_RptFilename); + + m_ui->Show(true); +// int rval = m_ui->ShowModal(); + + +#if defined(DEBUG) +// printf("dialog rval=%d wxID_OK=%d\n", rval, wxID_OK ); +#endif + + +// if( rval == wxID_OK ) + { + + // @todo capture the UI entered data into the DRC_TESTER here + /* + + s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked(); + s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked(); + s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked(); + s_CreateRptFileOpt = m_CreateRptCtrl->IsChecked(); + + wxBoxSizer* m_MainSizer; + wxBoxSizer* m_CommandSizer; + wxStaticText* m_ClearenceTitle; + wxTextCtrl* m_SetClearance; + wxCheckBox* m_CreateRptCtrl; + wxTextCtrl* m_RptFilenameCtrl; + wxButton* m_BrowseButton; + wxCheckBox* m_Pad2PadTestCtrl; + wxCheckBox* m_UnconnectedTestCtrl; + wxCheckBox* m_ZonesTestCtrl; + wxButton* m_DeleteCurrentMarkerButton; + DRCLISTBOX* m_ClearanceListBox; + DRCLISTBOX* m_UnconnectedListBox; + wxStdDialogButtonSizer* StdDialogButtonSizer; + */ + } + +// m_ui->Destroy(); +// m_ui = 0; +} + + +/*********************************************************/ +void DrcDialog::DelDRCMarkers( wxCommandEvent& event ) +/*********************************************************/ +{ + m_Parent->Erase_Marqueurs(); + m_Parent->ReDrawPanel(); +} + + +/****************************************************/ +void DrcDialog::CmdDrc() +/****************************************************/ +{ + wxString reportName; + + if( m_CreateRptCtrl->IsChecked() ) // Create a file rpt + { + reportName = m_RptFilenameCtrl->GetValue(); + + if( reportName.IsEmpty() ) + { + wxCommandEvent junk; + OnButtonBrowseRptFileClick( junk ); + } + + reportName = m_RptFilenameCtrl->GetValue(); + } + + g_DesignSettings.m_TrackClearence = + ReturnValueFromTextCtrl( *m_SetClearance, m_Parent->m_InternalUnits ); + + m_tester->SetSettings( m_Pad2PadTestCtrl->IsChecked(), + m_UnconnectedTestCtrl->IsChecked(), + m_ZonesTestCtrl->IsChecked(), + reportName, m_CreateRptCtrl->IsChecked() ); + + + m_Parent->Erase_Marqueurs(); + m_Parent->ReDrawPanel(); + + SetCursor( wxCursor( wxCURSOR_WATCH ) ); + + // run all the tests, with no UI at this time. + m_tester->RunTests(); + + // Generate the report + if( !reportName.IsEmpty() ) + { + FILE* fp = wxFopen( reportName, wxT( "w" ) ); + + m_tester->WriteReport( fp ); + + fclose(fp); + + // @todo put up message box saying we created the report + //msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() ); + } + + SetCursor( wxCursor( wxCURSOR_WATCH ) ); + + // @todo set the list counts in the DRCLISTITEMS here. + + + printf("done with tests\n"); +} + + +/***************************************************************/ +void DrcDialog::ListUnconnectedPads( wxCommandEvent& event ) +/***************************************************************/ +{ + m_tester->testUnconnected(); + + // @todo do report here +} + + const wxString& DRC_ITEM::GetErrorText() const { static const wxString error1( wxT("Items Too Close:") ); @@ -94,9 +219,1433 @@ wxString DRC_ITEM::ShowCoord( const wxPoint& aPos ) } +DRC::DRC( WinEDA_PcbFrame* aPcbWindow ) +{ + m_mainWindow = aPcbWindow; + m_drawPanel = aPcbWindow->DrawPanel; + m_pcb = aPcbWindow->m_Pcb; + + // establish initial values for everything: + m_doPad2PadTest = true; + m_doUnconnectedTest = true; + m_doZonesTest = false; + + m_doCreateRptFile = false; + + // m_rptFilename set to empty by its constructor + + m_errorCount = 0; + m_currentMarker = 0; + + m_spotcx = 0; + m_spotcy = 0; + m_finx = 0; + m_finy = 0; + + m_segmAngle = 0; + m_segmLength = 0; + + m_xcliplo = 0; + m_ycliplo = 0; + m_xcliphi = 0; + m_ycliphi = 0; + + m_unconnectedCount = 0; + m_drawPanel = 0; +} + + +/***********************************************************************/ +int DRC::Drc( TRACK* aRefSegm, TRACK* aList ) +/***********************************************************************/ +{ + updatePointers(); + + if( !doTrackDrc( aRefSegm, aList ) ) + { + wxString msg = m_currentMarker->GetReporter().ShowText(); + + m_mainWindow->Affiche_Message( msg ); + return BAD_DRC; + } + + return OK_DRC; +} + + +void DRC::WriteReport( FILE* fp ) +{ + fprintf( fp, "Drc report for %s\n", + CONV_TO_UTF8( m_mainWindow->GetScreen()->m_FileName ) ); + + char line[256]; + fprintf( fp, "Created on %s\n", DateAndTime( line ) ); + + + // write report here + int errors = 0; + + if( errors ) + fprintf( fp, "** End DRC: %d errors **\n", errors ); + else if( m_unconnectedCount == 0 ) + fprintf( fp, "** End Drc: No Error **\n" ); +} + + +void DRC::RunTests() +{ + // erase the MARKERs here. + m_pcb->DeleteMARKERs(); + + + // test pad to pad clearances, nothing to do with tracks, vias or zones. + if( m_doPad2PadTest ) + testPad2Pad(); + + // test track and via clearnces to other tracks, pads, and vias + testTracks(); + + // test zone clearances to other zones, pads, tracks, and vias + if( m_doZonesTest ) + testZones(); + + // find and gather unconnected pads. + if( m_doUnconnectedTest ) + testUnconnected(); +} + + +void DRC::testTracks() +{ + for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm=segm->Next() ) + { + if( !doTrackDrc( segm, segm->Next() ) ) + { + wxASSERT( m_currentMarker ); + m_pcb->Add( m_currentMarker ); + m_currentMarker = 0; + } + } +} + + +void DRC::testPad2Pad() +{ + LISTE_PAD* pad_list_start = CreateSortedPadListByXCoord( m_pcb ); + LISTE_PAD* pad_list_limit = &pad_list_start[m_pcb->m_NbPads]; + LISTE_PAD* ppad; + + // find the max size of the pads (used to stop the test) + int max_size = 0; + for( ppad = pad_list_start; ppadm_Rayon > max_size ) + max_size = pad->m_Rayon; + } + + // Test the pads + for( ppad = pad_list_start; ppadAdd( m_currentMarker ); + m_currentMarker = 0; + } + } + + free( pad_list_start ); +} + + +void DRC::testUnconnected() +{ + if( (m_pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 ) + { + wxClientDC dc( m_mainWindow->DrawPanel ); + m_mainWindow->Compile_Ratsnest( &dc, TRUE ); + } + + if( m_pcb->m_Ratsnest == NULL ) + return; + + m_unconnectedCount = 0; + + CHEVELU* rat = m_pcb->m_Ratsnest; + for( int i=0; iGetNumRatsnests(); ++i, ++rat ) + { + if( (rat->status & CH_ACTIF) == 0 ) + continue; + + m_unconnectedCount++; + + D_PAD* padStart = rat->pad_start; + D_PAD* padEnd = rat->pad_end; + + MARKER* marker = fillMarker( padStart, padEnd, DRCE_UNCONNECTED_PADS, NULL ); + + m_pcb->Add( marker ); + } +} + + +void DRC::testZones() +{ + TRACK* zoneSeg; + + /* this was for display purposes, don't know that we need it anymore + m_pcb->m_NbSegmZone = 0; + for( zoneSeg = m_pcb->m_Zone; zoneSeg; zoneSeg = zoneSeg->Next() ) + ++m_pcb->m_NbSegmZone; + */ + + for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() ) + { + // Test zoneSeg with other zone segments and with all pads + if( !doTrackDrc( zoneSeg, zoneSeg->Next() ) ) + { + wxASSERT( m_currentMarker ); + m_pcb->Add( m_currentMarker ); + m_currentMarker = 0; + } + + // Test zoneSeg with all track segments + int tmp = m_pcb->m_NbPads; + + m_pcb->m_NbPads = 0; // Pads already tested: disable pad test + bool rc = doTrackDrc( zoneSeg, m_pcb->m_Track ); + m_pcb->m_NbPads = tmp; + + if( !rc ) + { + wxASSERT( m_currentMarker ); + m_pcb->Add( m_currentMarker ); + m_currentMarker = 0; + } + } +} + + +MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe ) +{ + wxString textA = aTrack->MenuText( m_pcb ); + wxString textB = aItem->MenuText( m_pcb ); + + wxPoint position; + + if( aItem->Type() == TYPEPAD ) + position = aItem->GetPosition(); + + else if( aItem->Type() == TYPEVIA ) + position = aItem->GetPosition(); + + else if( aItem->Type() == TYPETRACK ) + { + TRACK* track = (TRACK*) aItem; + wxPoint endPos = track->m_End; + + // either of aItem's start or end will be used for the marker position + // first assume start, then swith to end if needed. decision made on + // distance from end of aTrack. + position = track->m_Start; + + double dToEnd = hypot( endPos.x - aTrack->m_End.x, + endPos.y - aTrack->m_End.y ); + double dToStart = hypot( position.x - aTrack->m_End.x, + position.y - aTrack->m_End.y ); + + if( dToEnd < dToStart ) + position = endPos; + } + + if( fillMe ) + fillMe->SetData( aErrorCode, position, + textA, aTrack->GetPosition(), + textB, aItem->GetPosition() ); + else + fillMe = new MARKER( aErrorCode, position, + textA, aTrack->GetPosition(), + textB, aItem->GetPosition() ); + + return fillMe; +} + + +MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe ) +{ + wxString textA = aPad->MenuText( m_pcb ); + wxString textB = bPad->MenuText( m_pcb ); + + wxPoint posA = aPad->GetPosition(); + wxPoint posB = bPad->GetPosition(); + + if( fillMe ) + fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); + else + fillMe = new MARKER( aErrorCode, posA, textA, posA, textB, posB ); + + return fillMe; +} + + +/***********************************************************************/ +bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) +/***********************************************************************/ +{ + TRACK* track; + int dx, dy; // utilise pour calcul des dim x et dim y des segments + int w_dist; + int layerMask; + 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 = aRefSeg->m_Start.x; + org_Y = aRefSeg->m_Start.y; + + m_finx = dx = aRefSeg->m_End.x - org_X; + m_finy = dy = aRefSeg->m_End.y - org_Y; + + layerMask = aRefSeg->ReturnMaskLayer(); + net_code_ref = aRefSeg->GetNet(); + + m_segmAngle = 0; + + // for a non horizontal or vertical segment Compute the segment angle + // in tenths of degrees and its length + if( dx || dy ) + { + // Compute the segment angle in 0,1 degrees + m_segmAngle = ArcTangente( dy, dx ); + + // Compute the segment length: we build an equivalent rotated segment, + // this segment is horizontal, therefore dx = length + RotatePoint( &dx, &dy, m_segmAngle ); // dx = length, dy = 0 + } + + m_segmLength = dx; + + /******************************************/ + /* Phase 1 : test DRC track to pads : */ + /******************************************/ + + D_PAD pseudo_pad( (MODULE*) NULL ); + + // Compute the min distance to pads + w_dist = aRefSeg->m_Width >> 1; + for( int ii=0; iim_NbPads; ++ii ) + { + D_PAD* pad = m_pcb->m_Pads[ii]; + + /* No problem if pads are on an other layer, + * But if a drill hole exists (a pad on a single layer can have a hole!) + * we must test the hole + */ + if( (pad->m_Masque_Layer & layerMask ) == 0 ) + { + /* We must test the pad hole. In order to use the function "checkClearanceSegmToPad", + * a pseudo pad is used, with a shape and a size like the hole + */ + if( pad->m_Drill.x == 0 ) + continue; + + pseudo_pad.m_Size = pad->m_Drill; + pseudo_pad.SetPosition( pad->GetPosition() ); + pseudo_pad.m_PadShape = pad->m_DrillShape; + pseudo_pad.m_Orient = pad->m_Orient; + pseudo_pad.ComputeRayon(); // compute the ray length + + m_spotcx = pseudo_pad.GetPosition().x - org_X; + m_spotcy = pseudo_pad.GetPosition().y - org_Y; + + if( !checkClearanceSegmToPad( &pseudo_pad, w_dist, + g_DesignSettings.m_TrackClearence ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, pad, + DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker ); + return false; + } + continue; + } + + /* The pad must be in a net (i.e pt_pad->GetNet() != 0 ) + * but no problem if the pad netcode is the current netcode (same net) + */ + if( pad->GetNet() && // the pad must be connected + net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok + continue; + + // DRC for the pad + shape_pos = pad->ReturnShapePos(); + m_spotcx = shape_pos.x - org_X; + m_spotcy = shape_pos.y - org_Y; + if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, pad, + DRCE_TRACK_NEAR_PAD, m_currentMarker ); + return false; + } + } + + /***********************************************/ + /* Phase 2: test DRC with other track segments */ + /***********************************************/ + + // At this point the reference segment is the X axis + + // Test the reference segment with other track segments + for( track=aStart; track; track=track->Next() ) + { + // coord des extremites du segment teste dans le repere modifie + int x0; + int y0; + int xf; + int yf; + + // No problem if segments have the same net code: + if( net_code_ref == track->GetNet() ) + continue; + + // No problem if segment are on different layers : + if( ( layerMask & track->ReturnMaskLayer() ) == 0 ) + continue; + + // the minimum distance = clearance plus half the reference track + // width plus half the other track's width + w_dist = aRefSeg->m_Width >> 1; + w_dist += track->m_Width >> 1; + w_dist += g_DesignSettings.m_TrackClearence; + + // If the reference segment is a via, we test it here + if( aRefSeg->Type() == TYPEVIA ) + { + int orgx, orgy; // origine du repere d'axe X = segment a comparer + int angle = 0; // angle du segment a tester; + + orgx = track->m_Start.x; + orgy = track->m_Start.y; + + dx = track->m_End.x - orgx; + dy = track->m_End.y - orgy; + + x0 = aRefSeg->m_Start.x - orgx; + y0 = aRefSeg->m_Start.y - orgy; + + if( track->Type() == TYPEVIA ) + { + // Test distance between two vias + if( (int) hypot( x0, y0 ) < w_dist ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_VIA_NEAR_VIA, m_currentMarker ); + return false; + } + } + else // test via to segment + { + // Compute l'angle + angle = ArcTangente( dy, dx ); + + // Compute new coordinates ( the segment become horizontal) + RotatePoint( &dx, &dy, angle ); + RotatePoint( &x0, &y0, angle ); + + if( !checkMarginToCircle( x0, y0, w_dist, dx ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_VIA_NEAR_TRACK, m_currentMarker ); + return false; + } + } + continue; + } + + /* We compute x0,y0, xf,yf = starting and ending point coordinates for the segment to test + * in the new axis : the new X axis is the reference segment + * We must translate and rotate the segment to test + */ + x0 = track->m_Start.x - org_X; + y0 = track->m_Start.y - org_Y; + + xf = track->m_End.x - org_X; + yf = track->m_End.y - org_Y; + + RotatePoint( &x0, &y0, m_segmAngle ); + RotatePoint( &xf, &yf, m_segmAngle ); + + if( track->Type() == TYPEVIA ) + { + if( checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) + continue; + + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACK_NEAR_VIA, m_currentMarker ); + return false; + } + + + /* We have changed axis: + * the reference segment is Horizontal. + * 3 cases : the segment to test can be parallel, perpendicular or have an other direction + */ + if( y0 == yf ) // parallel segments + { + if( abs( y0 ) >= w_dist ) + continue; + + if( x0 > xf ) + EXCHG( x0, xf ); /* pour que x0 <= xf */ + + if( x0 > (-w_dist) && x0 < (m_segmLength + w_dist) ) /* possible error drc */ + { + /* Fine test : we consider the rounded shape of the ends */ + if( x0 >= 0 && x0 <= m_segmLength ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACK_ENDS1, m_currentMarker ); + return false; + } + if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACK_ENDS2, m_currentMarker ); + return false; + } + } + if( xf > (-w_dist) && xf < (m_segmLength + w_dist) ) + { + /* Fine test : we consider the rounded shape of the ends */ + if( xf >= 0 && xf <= m_segmLength ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACK_ENDS3, m_currentMarker ); + return false; + } + if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACK_ENDS4, m_currentMarker ); + return false; + } + } + + if( x0 <=0 && xf >= 0 ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACK_UNKNOWN1, m_currentMarker ); + return false; + } + } + else if( x0 == xf ) // perpendicular segments + { + if( ( x0 <= (-w_dist) ) || ( x0 >= (m_segmLength + w_dist) ) ) + continue; + + // Test if segments are crossing + if( y0 > yf ) + EXCHG( y0, yf ); + if( (y0 < 0) && (yf > 0) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_TRACKS_CROSSING, m_currentMarker ); + return false; + } + + // At this point the drc error is due to an end near a reference segm end + if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_ENDS_PROBLEM1, m_currentMarker ); + return false; + } + if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_ENDS_PROBLEM2, m_currentMarker ); + return false; + } + } + else // segments quelconques entre eux */ + { + // calcul de la "surface de securite du segment de reference + // First rought 'and fast) test : the track segment is like a rectangle + + m_xcliplo = m_ycliplo = -w_dist; + m_xcliphi = m_segmLength + w_dist; + m_ycliphi = w_dist; + + // A fine test is needed because a serment is not exactly a + // rectangle, it has rounded ends + if( !checkLine( x0, y0, xf, yf ) ) + { + /* 2eme passe : the track has rounded ends. + * we must a fine test for each rounded end and the + * rectangular zone + */ + + m_xcliplo = 0; + m_xcliphi = m_segmLength; + + if( !checkLine( x0, y0, xf, yf ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_ENDS_PROBLEM3, m_currentMarker ); + return false; + } + else // The drc error is due to the starting or the ending point of the reference segment + { + // Test the starting and the ending point + int angle, rx0, ry0, rxf, ryf; + x0 = track->m_Start.x; + y0 = track->m_Start.y; + + xf = track->m_End.x; + yf = track->m_End.y; + + dx = xf - x0; + dy = yf - y0; + + /* Compute the segment orientation (angle) en 0,1 degre */ + angle = ArcTangente( dy, dx ); + + /* Compute the segment lenght: dx = longueur */ + RotatePoint( &dx, &dy, angle ); + + /* Comute the reference segment coordinates relatives to a + * X axis = current tested segment + */ + rx0 = aRefSeg->m_Start.x - x0; + ry0 = aRefSeg->m_Start.y - y0; + rxf = aRefSeg->m_End.x - x0; + ryf = aRefSeg->m_End.y - y0; + + RotatePoint( &rx0, &ry0, angle ); + RotatePoint( &rxf, &ryf, angle ); + if( !checkMarginToCircle( rx0, ry0, w_dist, dx ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_ENDS_PROBLEM4, m_currentMarker ); + return false; + } + if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) ) + { + ++m_errorCount; + m_currentMarker = fillMarker( aRefSeg, track, + DRCE_ENDS_PROBLEM5, m_currentMarker ); + return false; + } + } + } + } + } + + return true; +} + + +/*****************************************************************************/ +bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, + int max_size ) +/*****************************************************************************/ +{ + int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS; + + int x_limite = max_size + g_DesignSettings.m_TrackClearence + + aRefPad->m_Rayon + aRefPad->GetPosition().x; + + for( LISTE_PAD* pad_list=aStart; pad_listm_Pos.x > x_limite + * because the list is sorted by X values */ + if( pad->m_Pos.x > x_limite ) + break; + + /* No probleme if pads are on different copper layers */ + if( (pad->m_Masque_Layer & layerMask ) == 0 ) + continue; + + /* The pad must be in a net (i.e pt_pad->GetNet() != 0 ), + * But no problem if pads have the same netcode (same net)*/ + if( pad->GetNet() && (aRefPad->GetNet() == pad->GetNet()) ) + continue; + + /* No problem if pads are from the same footprint + * and have the same pad number ( equivalent pads ) */ + if( (pad->m_Parent == aRefPad->m_Parent) && (pad->m_NumPadName == aRefPad->m_NumPadName) ) + continue; + + if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) ) + { + // here we have a drc error! + ++m_errorCount; + m_currentMarker = fillMarker( aRefPad, pad, + DRCE_PAD_NEAR_PAD1, m_currentMarker ); + return false; + } + } + + return true; +} + + +/**************************************************************************************/ +bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_min ) +/***************************************************************************************/ +{ + wxPoint rel_pos; + int dist;; + wxPoint shape_pos; + int pad_angle; + + rel_pos = aPad->ReturnShapePos(); + shape_pos = aRefPad->ReturnShapePos(); + + // rel_pos is pad position relative to the aRefPad position + rel_pos.x -= shape_pos.x; + rel_pos.y -= shape_pos.y; + + dist = (int) hypot( rel_pos.x, rel_pos.y ); + + bool diag = true; + + + /* tst rapide: si les cercles exinscrits sont distants de dist_min au moins, + * il n'y a pas de risque: */ + if( (dist - aRefPad->m_Rayon - aPad->m_Rayon) >= dist_min ) + return 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( (aRefPad->m_PadShape != CIRCLE) && (aPad->m_PadShape == CIRCLE) ) + swap_pads = true; + else if( (aRefPad->m_PadShape != OVALE) && (aPad->m_PadShape == OVALE) ) + swap_pads = true; + + if( swap_pads ) + { + EXCHG( aRefPad, aPad ); + rel_pos.x = -rel_pos.x; + rel_pos.y = -rel_pos.y; + } + + switch( aRefPad->m_PadShape ) + { + case CIRCLE: // aRefPad is like a track segment with a null lenght + m_segmLength = 0; + m_segmAngle = 0; + + m_finx = m_finy = 0; + + m_spotcx = rel_pos.x; + m_spotcy = rel_pos.y; + + diag = checkClearanceSegmToPad( aPad, aRefPad->m_Rayon, dist_min ); + break; + + case RECT: + RotatePoint( &rel_pos.x, &rel_pos.y, aRefPad->m_Orient ); + pad_angle = aRefPad->m_Orient + aPad->m_Orient; // pad_angle = pad orient relative to the aRefPad orient + NORMALIZE_ANGLE_POS( pad_angle ); + if( aPad->m_PadShape == RECT ) + { + wxSize size = aPad->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 = false; + + rel_pos.x = ABS( rel_pos.x ); + rel_pos.y = ABS( rel_pos.y ); + + if( ( rel_pos.x - ( (size.x + aRefPad->m_Size.x) / 2 ) ) >= dist_min ) + diag = true; + + if( ( rel_pos.y - ( (size.y + aRefPad->m_Size.y) / 2 ) ) >= dist_min ) + diag = true; + } + 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; + m_segmAngle = aRefPad->m_Orient; // Segment orient. + if( aRefPad->m_Size.y < aRefPad->m_Size.x ) /* We suppose the pad is an horizontal oval */ + { + segm_width = aRefPad->m_Size.y; + m_segmLength = aRefPad->m_Size.x - aRefPad->m_Size.y; + } + else // it was a vertical oval, change to a rotated horizontal one + { + segm_width = aRefPad->m_Size.x; + m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x; + m_segmAngle += 900; + } + + /* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ + int sx = -m_segmLength / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment + + RotatePoint( &sx, &sy, m_segmAngle ); // True start point coordinate of the equivalent segment + + m_spotcx = rel_pos.x + sx; + m_spotcy = rel_pos.y + sy; // pad position / segment origin + + m_finx = -sx; + m_finy = -sy; // end of segment coordinate + + diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min ); + break; + } + + default: + /* TODO...*/ + break; + } + + return diag; +} + + +bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min ) +{ + int p_dimx; + int p_dimy; // half the dimension of the pad + 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; + + 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( &m_spotcx, &m_spotcy, m_segmAngle ); + return checkMarginToCircle( m_spotcx, m_spotcy, seuil + p_dimx, m_segmLength ); + } + else + { + /* calcul de la "surface de securite" du pad de reference */ + m_xcliplo = m_spotcx - seuil - p_dimx; + m_ycliplo = m_spotcy - seuil - p_dimy; + m_xcliphi = m_spotcx + seuil + p_dimx; + m_ycliphi = m_spotcy + seuil + p_dimy; + + x0 = y0 = 0; + + xf = m_finx; + yf = m_finy; + + orient = pad_to_test->m_Orient; + + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, -orient ); + RotatePoint( &xf, &yf, m_spotcx, m_spotcy, -orient ); + + if( checkLine( x0, y0, xf, yf ) ) + return true; + + /* Erreur DRC : analyse fine de la forme de la pastille */ + + switch( pad_to_test->m_PadShape ) + { + default: + return false; + + 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 */ + + /* Test du rectangle separant les 2 demi cercles */ + m_xcliplo = m_spotcx - seuil - p_dimx; + m_ycliplo = m_spotcy - w_segm - deltay; + m_xcliphi = m_spotcx + seuil + p_dimx; + m_ycliphi = m_spotcy + w_segm + deltay; + + if( !checkLine( x0, y0, xf, yf ) ) + return false; + + /* test des 2 cercles */ + x0 = m_spotcx; /* x0,y0 = centre du cercle superieur du pad ovale */ + y0 = m_spotcy + deltay; + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient ); + RotatePoint( &x0, &y0, m_segmAngle ); + + if( !checkMarginToCircle( x0, y0, p_dimx + seuil, m_segmLength ) ) + return false; + + x0 = m_spotcx; /* x0,y0 = centre du cercle inferieur du pad ovale */ + y0 = m_spotcy - deltay; + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient ); + RotatePoint( &x0, &y0, m_segmAngle ); + + if( !checkMarginToCircle( x0, y0, p_dimx + seuil, m_segmLength ) ) + return false; + break; + + case RECT: /* 2 rectangle + 4 1/4 cercles a tester */ + /* Test du rectangle dimx + seuil, dimy */ + m_xcliplo = m_spotcx - p_dimx - seuil; + m_ycliplo = m_spotcy - p_dimy; + m_xcliphi = m_spotcx + p_dimx + seuil; + m_ycliphi = m_spotcy + p_dimy; + + if( !checkLine( x0, y0, xf, yf ) ) + { + return false; + } + + /* Test du rectangle dimx , dimy + seuil */ + m_xcliplo = m_spotcx - p_dimx; + m_ycliplo = m_spotcy - p_dimy - seuil; + m_xcliphi = m_spotcx + p_dimx; + m_ycliphi = m_spotcy + p_dimy + seuil; + + if( !checkLine( x0, y0, xf, yf ) ) + { + return false; + } + + /* test des 4 cercles ( surface d'solation autour des sommets */ + /* test du coin sup. gauche du pad */ + x0 = m_spotcx - p_dimx; + y0 = m_spotcy - p_dimy; + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient ); + RotatePoint( &x0, &y0, m_segmAngle ); + if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) + { + return false; + } + + /* test du coin sup. droit du pad */ + x0 = m_spotcx + p_dimx; + y0 = m_spotcy - p_dimy; + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient ); + RotatePoint( &x0, &y0, m_segmAngle ); + if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) + { + return false; + } + + /* test du coin inf. gauche du pad */ + x0 = m_spotcx - p_dimx; + y0 = m_spotcy + p_dimy; + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient ); + RotatePoint( &x0, &y0, m_segmAngle ); + if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) + { + return false; + } + + /* test du coin inf. droit du pad */ + x0 = m_spotcx + p_dimx; + y0 = m_spotcy + p_dimy; + RotatePoint( &x0, &y0, m_spotcx, m_spotcy, orient ); + RotatePoint( &x0, &y0, m_segmAngle ); + if( !checkMarginToCircle( x0, y0, seuil, m_segmLength ) ) + { + return false; + } + + break; + } + } + return true; +} + +/**********************************************************************/ +bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) +/**********************************************************************/ +{ + if( abs( cy ) > radius ) + return true; + + if( (cx >= -radius ) && ( cx <= (longueur + radius) ) ) + { + if( (cx >= 0) && (cx <= longueur) ) + return false; + + if( cx > longueur ) + cx -= longueur; + + if( hypot( cx, cy ) < radius ) + return false; + } + + return true; +} + + + +/**********************************************/ +/* int Tst_Ligne(int x1,int y1,int x2,int y2) */ +/**********************************************/ + +static inline int USCALE( unsigned arg, unsigned num, unsigned den ) +{ + int ii; + + ii = (int) ( ( (double) arg * num ) / den ); + return ii; +} + + +#define WHEN_OUTSIDE return true +#define WHEN_INSIDE + +bool DRC::checkLine( int x1, int y1, int x2, int y2 ) +{ + int temp; + + if( x1 > x2 ) + { + EXCHG( x1, x2 ); + EXCHG( y1, y2 ); + } + if( (x2 < m_xcliplo) || (x1 > m_xcliphi) ) + { + WHEN_OUTSIDE; + } + if( y1 < y2 ) + { + if( (y2 < m_ycliplo) || (y1 > m_ycliphi) ) + { + WHEN_OUTSIDE; + } + if( y1 < m_ycliplo ) + { + temp = USCALE( (x2 - x1), (m_ycliplo - y1), (y2 - y1) ); + if( (x1 += temp) > m_xcliphi ) + { + WHEN_OUTSIDE; + } + y1 = m_ycliplo; + WHEN_INSIDE; + } + if( y2 > m_ycliphi ) + { + temp = USCALE( (x2 - x1), (y2 - m_ycliphi), (y2 - y1) ); + if( (x2 -= temp) < m_xcliplo ) + { + WHEN_OUTSIDE; + } + y2 = m_ycliphi; + WHEN_INSIDE; + } + if( x1 < m_xcliplo ) + { + temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) ); + y1 += temp; + x1 = m_xcliplo; + WHEN_INSIDE; + } + if( x2 > m_xcliphi ) + { + temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) ); + y2 -= temp; + x2 = m_xcliphi; + WHEN_INSIDE; + } + } + else + { + if( (y1 < m_ycliplo) || (y2 > m_ycliphi) ) + { + WHEN_OUTSIDE; + } + if( y1 > m_ycliphi ) + { + temp = USCALE( (x2 - x1), (y1 - m_ycliphi), (y1 - y2) ); + if( (x1 += temp) > m_xcliphi ) + { + WHEN_OUTSIDE; + } + y1 = m_ycliphi; + WHEN_INSIDE; + } + if( y2 < m_ycliplo ) + { + temp = USCALE( (x2 - x1), (m_ycliplo - y2), (y1 - y2) ); + if( (x2 -= temp) < m_xcliplo ) + { + WHEN_OUTSIDE; + } + y2 = m_ycliplo; + WHEN_INSIDE; + } + if( x1 < m_xcliplo ) + { + temp = USCALE( (y1 - y2), (m_xcliplo - x1), (x2 - x1) ); + y1 -= temp; + x1 = m_xcliplo; + WHEN_INSIDE; + } + if( x2 > m_xcliphi ) + { + temp = USCALE( (y1 - y2), (x2 - m_xcliphi), (x2 - x1) ); + y2 += temp; + x2 = m_xcliphi; + WHEN_INSIDE; + } + } + + if( ( (x2 + x1)/2 <= m_xcliphi ) && ( (x2 + x1)/2 >= m_xcliplo ) \ + && ( (y2 + y1)/2 <= m_ycliphi ) && ( (y2 + y1)/2 >= m_ycliplo ) ) + { + return false; + } + else + return true; +} + + + +#if 0 + +//----< new stuff above this line, old stuff below >------------------------ + + +/* 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 int ErrorsDRC_Count; +static MARKER* 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 */ + + +/************************************************************************/ +int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone ) +/************************************************************************/ + +/* Test DRC : + * Run a drc control for each pad and track segment + * Put a marker on pad or track end which have a drc problem + */ +{ + 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 + + DrcInProgress = TRUE; + ErrorsDRC_Count = 0; + Compile_Ratsnest( DC, TRUE ); + + MsgPanel->EraseMsgBox(); + + m_CurrentScreen->SetRefreshReq(); + + /* Delete previous markers */ + Erase_Marqueurs(); + + if( TestPad2Pad ) /* First test: Test DRC between pads (no track)*/ + { + 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; + + 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; + + 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 ); + } + + if( old_net != pt_segm->GetNet() ) + { + wxString msg; + jj = 1; + EQUIPOT* equipot = m_Pcb->FindNet( pt_segm->GetNet() ); + if( equipot ) + msg = equipot->m_Netname + wxT( " " ); + else + msg = wxT( "" ); + Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); + old_net = pt_segm->GetNet(); + } + + g_HightLigth_NetCode = pt_segm->GetNet(); + 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_TRACK_ERR_POS, wxEmptyString, Line, LIGHTRED ); + } + } + + /* Test zone 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 ); + + 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 ); + } + + if( old_net != pt_segm->GetNet() ) + { + jj = 1; + wxString msg; + EQUIPOT* equipot = m_Pcb->FindNet( pt_segm->GetNet() ); + + if( equipot ) + msg = equipot->m_Netname + wxT( " " ); + else + msg = wxT( "" ); + + Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); + old_net = pt_segm->GetNet(); + } + g_HightLigth_NetCode = pt_segm->GetNet(); + + /* 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; +} + /***************************************************************/ -void WinEDA_DrcFrame::ListUnconnectedPads( wxCommandEvent& event ) +void DrcDialog::ListUnconnectedPads( wxCommandEvent& event ) /***************************************************************/ { if( (m_Parent->m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 ) @@ -171,7 +1720,7 @@ void WinEDA_DrcFrame::ListUnconnectedPads( wxCommandEvent& event ) /****************************************************/ -void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event ) +void DrcDialog::TestDrc( wxCommandEvent& event ) /****************************************************/ { int errors; @@ -182,10 +1731,10 @@ void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event ) 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 @@ -202,30 +1751,30 @@ void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event ) s_Pad2PadTestOpt = m_Pad2PadTestCtrl->IsChecked(); s_UnconnectedTestOpt = m_UnconnectedTestCtrl->IsChecked(); - + s_ZonesTestOpt = m_ZonesTestCtrl->IsChecked(); - + AbortDrc = FALSE; -// m_logWindow->Clear(); + 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() ); - + 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 ); + + m_logWindow->AppendText( msg ); if( s_RptFile ) fprintf( s_RptFile, "%s", CONV_TO_UTF8( msg ) ); @@ -233,7 +1782,7 @@ void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event ) if( s_RptFile ) { msg.Printf( _( "Report file <%s> created\n" ), s_RptFilename.GetData() ); -// m_logWindow->AppendText( msg ); + m_logWindow->AppendText( msg ); fclose( s_RptFile ); s_RptFile = NULL; } @@ -244,281 +1793,11 @@ void WinEDA_DrcFrame::TestDrc( wxCommandEvent& event ) /*********************************************************/ -void WinEDA_DrcFrame::DelDRCMarkers( wxCommandEvent& event ) +void DrcDialog::DelDRCMarkers( wxCommandEvent& event ) /*********************************************************/ { - if( !DrcInProgress ) - { - m_Parent->Erase_Marqueurs(); - m_Parent->DrawPanel->ReDraw( m_DC, TRUE ); - } - else - wxBell(); -} - - -/******************************************************/ -void WinEDA_PcbFrame::Install_Test_DRC_Frame( wxDC* DC ) -/******************************************************/ - -/* install a dialog box to handle the general DRC control - */ -{ - AbortDrc = FALSE; - DrcFrame = new WinEDA_DrcFrame( NULL, this, DC ); // @todo - DrcFrame->ShowModal(); - DrcFrame->Destroy(); - DrcFrame = NULL; -} - - -/************************************************************************/ -int WinEDA_PcbFrame::Test_DRC( wxDC* DC, bool TestPad2Pad, bool TestZone ) -/************************************************************************/ - -/* Test DRC : - * Run a drc control for each pad and track segment - * Put a marker on pad or track end which have a drc problem - */ -{ - int ii, jj, old_net; - int flag_err_Drc; - TRACK* pt_segm; - D_PAD* pad; - MARKER* Marqueur; - 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 - - DrcInProgress = TRUE; - ErrorsDRC_Count = 0; - Compile_Ratsnest( DC, TRUE ); - - MsgPanel->EraseMsgBox(); - - m_CurrentScreen->SetRefreshReq(); - - /* Delete previous markers */ - Erase_Marqueurs(); - - if( TestPad2Pad ) /* First test: Test DRC between pads (no track)*/ - { - 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 ); - - m_Pcb->Add( 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; - -// 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 ); - } - - if( old_net != pt_segm->GetNet() ) - { - wxString msg; - jj = 1; - EQUIPOT* equipot = m_Pcb->FindNet( pt_segm->GetNet() ); - if( equipot ) - msg = equipot->m_Netname + wxT( " " ); - else - msg = wxT( "" ); - Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); - old_net = pt_segm->GetNet(); - } - - g_HightLigth_NetCode = pt_segm->GetNet(); - 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; - } - - m_Pcb->Add( Marqueur ); - - 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 ); - } - } - - /* Test zone 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 ); - -// 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 ); - } - - if( old_net != pt_segm->GetNet() ) - { - jj = 1; - wxString msg; - EQUIPOT* equipot = m_Pcb->FindNet( pt_segm->GetNet() ); - - if( equipot ) - msg = equipot->m_Netname + wxT( " " ); - else - msg = wxT( "" ); - - Affiche_1_Parametre( this, 0, _( "Netname" ), msg, YELLOW ); - old_net = pt_segm->GetNet(); - } - g_HightLigth_NetCode = pt_segm->GetNet(); - - /* 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; - } - - m_Pcb->Add( 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; - } - - m_Pcb->Add( 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; + m_Parent->Erase_Marqueurs(); + m_Parent->DrawPanel->ReDraw( m_DC, TRUE ); } @@ -1535,7 +2814,7 @@ static inline int USCALE( unsigned arg, unsigned num, unsigned den ) { int ii; - ii = (int) ( ( (float) arg * num ) / den ); + ii = (int) ( ( (double) arg * num ) / den ); return ii; } @@ -1646,3 +2925,4 @@ static int Tst_Ligne( int x1, int y1, int x2, int y2 ) return OK_DRC; } +#endif diff --git a/pcbnew/drc_stuff.h b/pcbnew/drc_stuff.h index 3fc83fae5e..469e1eca2f 100644 --- a/pcbnew/drc_stuff.h +++ b/pcbnew/drc_stuff.h @@ -29,10 +29,31 @@ #include "fctsys.h" -/// DRC error codes: -#define DRCE_ 1 +#define OK_DRC 0 +#define BAD_DRC 1 +/// DRC error codes: +#define DRCE_ 1 +#define DRCE_UNCONNECTED_PADS 2 +#define DRCE_TRACK_NEAR_THROUGH_HOLE 3 ///< thru hole is too close to track +#define DRCE_TRACK_NEAR_PAD 4 ///< pad too close to track +#define DRCE_TRACK_NEAR_VIA 5 ///< track too close to via +#define DRCE_VIA_NEAR_VIA 6 ///< via too close to via +#define DRCE_VIA_NEAR_TRACK 7 ///< via too close to track +#define DRCE_TRACK_ENDS1 8 ///< @todo say what this problem is +#define DRCE_TRACK_ENDS2 9 ///< @todo say what this problem is +#define DRCE_TRACK_ENDS3 10 ///< @todo say what this problem is +#define DRCE_TRACK_ENDS4 11 ///< @todo say what this problem is +#define DRCE_TRACK_UNKNOWN1 12 ///< @todo check source code and change this comment +#define DRCE_TRACKS_CROSSING 13 ///< tracks are crossing +#define DRCE_ENDS_PROBLEM1 14 ///< track ends are too close +#define DRCE_ENDS_PROBLEM2 15 ///< track ends are too close +#define DRCE_ENDS_PROBLEM3 16 ///< track ends are too close +#define DRCE_ENDS_PROBLEM4 17 ///< track ends are too close +#define DRCE_ENDS_PROBLEM5 18 ///< track ends are too close +#define DRCE_PAD_NEAR_PAD1 19 ///< pad too close to pad + /** * Class REPORT_ISSUE @@ -55,19 +76,27 @@ public: /** * Function ShowText - * translates this object into a text string suitable for saving - * to disk in a report. + * translates this object into a text string suitable for showing + * in the status panel. * @return wxString - the simple non-html text. */ virtual wxString ShowText() const = 0; + /** + * Function ShowText + * translates this object into a text string suitable for saving + * to disk in a report. + * @return wxString - the simple non-html text. + */ + virtual wxString ShowReport() const = 0; + /** * Function GetPosition * @return const wxPoint& - the position of this report item within * the drawing. */ - virtual const wxPoint& GetPosition() const = 0; + virtual const wxPoint& GetPosition() const = 0; }; @@ -94,9 +123,23 @@ protected: public: + DRC_ITEM() : + m_ErrorCode(0) + { + } + DRC_ITEM( int aErrorCode, const wxPoint& aIssuePos, const wxString& aText, const wxString& bText, const wxPoint& aPos, const wxPoint& bPos ) + { + SetData( aErrorCode, aIssuePos, + aText, bText, + aPos, bPos ); + } + + void SetData( int aErrorCode, const wxPoint& aIssuePos, + const wxString& aText, const wxString& bText, + const wxPoint& aPos, const wxPoint& bPos ) { m_ErrorCode = aErrorCode; m_Pos = aIssuePos; @@ -105,7 +148,8 @@ public: m_APos = aPos; m_BPos = bPos; } - + + //-------------------------------------------- /** @@ -136,7 +180,7 @@ public: { wxString ret; - ret.Printf( wxT("%s\n %s: %s\n %s: %s\n"), + ret.Printf( wxT("%s %s: %s AND %s: %s"), GetErrorText().GetData(), ShowCoord( m_APos ).GetData(), m_AText.GetData(), ShowCoord( m_BPos ).GetData(), m_BText.GetData() ); @@ -144,9 +188,29 @@ public: return ret; } + + /** + * Function ShowText + * translates this object into a text string suitable for saving + * to disk in a report. + * @return wxString - the simple non-html text. + */ + wxString ShowReport() const + { + wxString ret; + + ret.Printf( wxT("%s\n %s: %s\n %s: %s\n"), + GetErrorText().GetData(), + ShowCoord( m_APos ).GetData(), m_AText.GetData(), + ShowCoord( m_BPos ).GetData(), m_BText.GetData() ); + + return ret; + } + + /** * Function GetPosition - * @return const wxPoint& - the position of this report item within + * @return wxPoint& - the position of this report item within * the drawing. */ const wxPoint& GetPosition() const @@ -176,35 +240,37 @@ public: class WinEDA_DrawPanel; class MARKER; +class DrcDialog; -/// A smart pointer to a DRC_ITEM -//typedef OWNER DRC_ITEM_OWNER; - -/// A list of DRC_ITEM_PTRs typedef std::vector DRC_LIST; /** - * Class DRC_TESTER - * performs all the DRC tests, and can optionally generate a DRC test report - * to a disk file. This class is given access to the windows and the BOARD - * that it needs via its constructor or access functions. + * Class DRC + * is the Design Rule Checker, and performs all the DRC tests. The output of + * the checking goes to the BOARD file in the form of two MARKER lists. Those + * two lists are displayable in the drc dialog box. And they can optionally + * be sent to a text file on disk. + * This class is given access to the windows and the BOARD + * that it needs via its constructor or public access functions. */ -class DRC_TESTER +class DRC { -protected: + friend class DrcDialog; + +private: + // protected or private functions() are lowercase first character. + bool m_doPad2PadTest; bool m_doUnconnectedTest; bool m_doZonesTest; bool m_doCreateRptFile; - FILE* m_rptFile; - wxString m_rptFilename; int m_errorCount; - MARKER* m_currentMarker; + MARKER* m_currentMarker; bool m_aboartDRC; bool m_drcInProgress; @@ -214,7 +280,7 @@ protected: int m_finy; // coord relatives de l'extremite du segm de reference int m_segmAngle; // angle d'inclinaison du segment de reference en 0,1 degre - int m_segmLong; // longueur du segment de reference + int m_segmLength; // length of the reference segment int m_xcliplo; int m_ycliplo; @@ -223,77 +289,203 @@ protected: int m_unconnectedCount; - DRC_LIST* m_drcList; - + WinEDA_PcbFrame* m_mainWindow; WinEDA_DrawPanel* m_drawPanel; - -public: - DRC_TESTER() + BOARD* m_pcb; + DrcDialog* m_ui; + + /** + * Function updatePointers + * is a private helper function used to update needed pointers from the + * one pointer which is known not to change, m_mainWindow. + */ + void updatePointers() { - m_doPad2PadTest = true; - m_doUnconnectedTest = true; - m_doZonesTest = false; - m_doCreateRptFile = false; - - m_rptFile = 0; - - m_errorCount = 0; - - m_currentMarker = 0; - - m_aboartDRC = false; - m_drcInProgress = false; - m_spotcx = 0; - m_spotcy = 0; - m_finx = 0; - m_finy = 0; // coord relatives de l'extremite du segm de reference - - m_segmAngle = 0; // angle d'inclinaison du segment de reference en 0,1 degre - m_segmLong = 0; // longueur du segment de reference - - m_xcliplo = 0; - m_ycliplo = 0; - m_xcliphi = 0; - m_ycliphi = 0; // coord de la surface de securite du segment a comparer - - m_unconnectedCount = 0; - - m_drcList = new DRC_LIST(); - - m_drawPanel = 0; - - for( int i=0; i<12; ++i ) - { - DRC_ITEM* ditem = new DRC_ITEM( 2, wxPoint(12000,3000), - wxString( wxT("A item") ), wxString( wxT("B item") ), - wxPoint(12000,3000), wxPoint(13000,3000)); - - m_drcList->push_back( ditem ); - } + // update my pointers, m_mainWindow is the only unchangable one + m_drawPanel = m_mainWindow->DrawPanel; + m_pcb = m_mainWindow->m_Pcb; } + + + /** + * Function fillMarker + * optionally creates a marker and fills it in with information, + * but does not add it to the BOARD. Use this to report any kind of + * DRC problem, or unconnected pad problem. + * + * @param aTrack The reference track + * @param aItem Another item on the BOARD, such as a SEGVIA, SEGZONE, + * or TRACK. + * @param aErrorCode A categorizing identifier for the particular type + * of error that is being reported. + * @param fillMe A MARKER* which is to be filled in, or NULL if one is to + * first be allocated, then filled. + */ + MARKER* fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKER* fillMe ); + + MARKER* fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillMe ); + + + //---------------------------------------------- + + void testTracks(); + + void testPad2Pad(); + + void testUnconnected(); + + void testZones(); + + + //---------------------------------------------- + + /** + * Function doPadToPadsDrc + * tests the clearance between aRefPad and other pads. + * The pad list must be sorted by x coordinate. + * @param aRefPad The pad to test + * @param aStart The start of the pad list to test against + * @param aEnd Marks the end of the list and is not included + * @param max_size The size of the biggest pad (used to stop the test when the X distance is > max_size) + */ + bool doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, + LISTE_PAD* aEnd, int max_size ); + + /** + * Function DoTrackDrc + * tests the current segment. + * @param aRefSeg The segment to test + * @param aStart The head of a list of tracks to test against (usually BOARD::m_Track) + * @return bool - true if no poblems, else false and m_currentMarker is + * filled in with the problem information. + */ + bool doTrackDrc( TRACK* aRefSeg, TRACK* aStart ); + + + //--------------------------------------------------- + + /** + * Function checkClearancePadToPad + * @param aRefPad The reference pad to check + * @param aPad Another pad to check against + * @return bool - true if clearance between aRefPad and pad is >= dist_min, else false + */ + bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_min ); + + + /** + * Function checkClearanceSegmToPad + * check the distance from a pad to segment. This function uses several + * instance variable not passed in: + * segmLength = length of the segment being tested + * segmAngle = angle d'inclinaison du segment; + * finx, finy = end coordinate of the segment + * spot_cX, spot_cY = position of pad / origin of segment + * @param pad_to_test Is the pad involved in the check + * @param w_segm Hhalf width of the segment to test + * @param dist_min Is the minimum clearance needed + * + * @return false distance >= dist_min, + * true if distance < dist_min + */ + bool checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min ); /** - * Function SetTests - * sets all the test flags and may be called before running the tests. + * Function checkMarginToCircle + * @todo this translation is no good, fix this: + * calculates the distance from a circle (via or round end of track) to the + * segment of reference on the right hand side. + * + * @param cx The x coordinate of the circle's center + * @param cy The y coordinate of the circle's center + * @param radius A "keep out" radius centered over the circle + * @param length The length of the segment (i.e. coordinate of end) + * @return bool - true if distance >= radius, else + * false when distance < radius + */ + static bool checkMarginToCircle( int cx, int cy, int radius, int length ); + + + /** + * Function checkLine + * tests to see if one track is in contact with another track. + * + * 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) + */ + bool checkLine( int x1, int y1, int x2, int y2 ); + + //-------------------------------------------------- + +public: + DRC( WinEDA_PcbFrame* aPcbWindow ); + + + /** + * Function Drc + * tests the current segment and returns the result and displays the error + * in the status panel only if one exists. + * @param aRefSeg The current segment to test. + * @param aList The track list to test (usually m_Pcb->m_Track) + * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK + */ + int Drc( TRACK* aRefSeg, TRACK* aList ); + + + /** + * Function DrcBlind + * tests the current segment and returns the result. Any error is not + * displayed in the status panel. + * @param aRefSeg The current segment to test. + * @param aList The track list to test (usually m_Pcb->m_Track) + * @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK + */ + int DrcBlind( TRACK* aRefSeg, TRACK* aList ) + { + updatePointers(); + + return doTrackDrc( aRefSeg, aList ) ? OK_DRC : BAD_DRC; + } + + + /** + * Function ShowDialog + * opens a dialog and prompts the user, then if a test run button is + * clicked, runs the test(s) and creates the MARKERS. + */ + void ShowDialog(); + + + /** + * Function SetSettings + * saves all the UI or test settings and may be called before running the tests. * @param aPad2PadTest Tells whether to test pad to pad distances. * @param aUnconnectedTest Tells whether to list unconnected pads. * @param aZonesTest Tells whether to test zones. - * @param aRptFilename If non-Empty, is the name of the file to - * save the report to. If Empty, means save no report. + * @param aReportName A string telling the disk file report name entered. + * @param aSaveReport A boolean telling whether to generate disk file report. */ - void SetTests( bool aPad2PadTest, bool aUnconnectedTest, bool aZonesTest, const wxString& aRptFilename ) + void SetSettings( bool aPad2PadTest, bool aUnconnectedTest, + bool aZonesTest, const wxString& aReportName, bool aSaveReport ) { m_doPad2PadTest = aPad2PadTest; m_doUnconnectedTest = aUnconnectedTest; m_doZonesTest = aZonesTest; - - m_rptFilename = aRptFilename; - if( m_rptFilename.IsEmpty() ) - m_doCreateRptFile = false; - else - m_doCreateRptFile = true; + m_rptFilename = aReportName; + m_doCreateRptFile = aSaveReport; } + + void RunTests(); + + + /** + * Function WriteReport + * outputs the MARKER items with commentary to an open text file. + * @param fpOut The text file to write the report to. + */ + void WriteReport( FILE* fpOut ); }; diff --git a/pcbnew/edit_track_width.cpp b/pcbnew/edit_track_width.cpp index 4e2e0d6e84..159f13ec9d 100644 --- a/pcbnew/edit_track_width.cpp +++ b/pcbnew/edit_track_width.cpp @@ -1,7 +1,7 @@ - /***************************************************************/ - /* Edition des pistes: Routines de modification de dimensions: */ - /* Modif de largeurs de segment, piste, net , zone et diam Via */ - /***************************************************************/ +/***************************************************************/ +/* Edition des pistes: Routines de modification de dimensions: */ +/* Modif de largeurs de segment, piste, net , zone et diam Via */ +/***************************************************************/ #include "fctsys.h" #include "gr_basic.h" @@ -15,142 +15,158 @@ /* Routines Locales */ /*********************************************************************/ -int WinEDA_PcbFrame::Edit_TrackSegm_Width(wxDC * DC, TRACK * pt_segm) +int WinEDA_PcbFrame::Edit_TrackSegm_Width( wxDC* DC, TRACK* pt_segm ) /*********************************************************************/ + /* Routine to modify one track segment width or one via diameter. - Basic routine used by other routines when editing tracks or vias -*/ + * Basic routine used by other routines when editing tracks or vias + */ { -int errdrc = OK_DRC; -int old_w, consigne ; + int errdrc = OK_DRC; + int old_w, consigne; - DrawPanel->CursorOff(DC); // Erase cursor shape - pt_segm->Draw(DrawPanel, DC, GR_XOR) ; // Erase old track shape + DrawPanel->CursorOff( DC ); // Erase cursor shape + pt_segm->Draw( DrawPanel, DC, GR_XOR ); // Erase old track shape - /* Test DRC and width change */ - old_w = pt_segm->m_Width; - consigne = pt_segm->m_Width = g_DesignSettings.m_CurrentTrackWidth; - if( pt_segm->Type() == TYPEVIA ) - { - consigne = pt_segm->m_Width = g_DesignSettings.m_CurrentViaSize; - } + /* Test DRC and width change */ + old_w = pt_segm->m_Width; + consigne = pt_segm->m_Width = g_DesignSettings.m_CurrentTrackWidth; + if( pt_segm->Type() == TYPEVIA ) + { + consigne = pt_segm->m_Width = g_DesignSettings.m_CurrentViaSize; + } - if ( old_w < consigne) /* DRC utile puisque augm de dimension */ - { - if(Drc_On) errdrc = Drc(this, DC, pt_segm, m_Pcb->m_Track,1); - if(errdrc == BAD_DRC) pt_segm->m_Width = old_w; - else GetScreen()->SetModify(); - } + if( old_w < consigne ) /* DRC utile puisque augm de dimension */ + { + if( Drc_On ) + errdrc = m_drc->Drc( pt_segm, m_Pcb->m_Track ); + if( errdrc == BAD_DRC ) + pt_segm->m_Width = old_w; + else + GetScreen()->SetModify(); + } + else + GetScreen()->SetModify(); /* Correction systematiquement faite si reduction */ - else GetScreen()->SetModify(); /* Correction systematiquement faite si reduction */ - - pt_segm->Draw(DrawPanel, DC, GR_OR) ; // Display new track shape - DrawPanel->CursorOn(DC); // Display cursor shape - return(errdrc); + pt_segm->Draw( DrawPanel, DC, GR_OR ); // Display new track shape + DrawPanel->CursorOn( DC ); // Display cursor shape + return errdrc; } + /*****************************************************************/ -void WinEDA_PcbFrame::Edit_Track_Width(wxDC * DC,TRACK * pt_segm) +void WinEDA_PcbFrame::Edit_Track_Width( wxDC* DC, TRACK* pt_segm ) /*****************************************************************/ { -int ii; -TRACK * pt_track; -int errdrc; -int nb_segm, nb_segm_modifies = 0, nb_segm_non_modifies = 0; + int ii; + TRACK* pt_track; + int errdrc; + int nb_segm, nb_segm_modifies = 0, nb_segm_non_modifies = 0; - if( pt_segm == NULL) return; + if( pt_segm == NULL ) + return; - pt_track = Marque_Une_Piste(this, DC, pt_segm, &nb_segm, 0); - for(ii = 0; ii < nb_segm; ii++, pt_track = (TRACK*) pt_track->Pnext) - { - pt_track->SetState(BUSY,OFF); - errdrc = Edit_TrackSegm_Width(DC, pt_track); - if(errdrc == BAD_DRC) nb_segm_non_modifies++; - else nb_segm_modifies++; - } + pt_track = Marque_Une_Piste( this, DC, pt_segm, &nb_segm, 0 ); + for( ii = 0; ii < nb_segm; ii++, pt_track = (TRACK*) pt_track->Pnext ) + { + pt_track->SetState( BUSY, OFF ); + errdrc = Edit_TrackSegm_Width( DC, pt_track ); + if( errdrc == BAD_DRC ) + nb_segm_non_modifies++; + else + nb_segm_modifies++; + } } /***********************************************************/ -void WinEDA_PcbFrame::Edit_Net_Width(wxDC * DC, int Netcode) +void WinEDA_PcbFrame::Edit_Net_Width( wxDC* DC, int Netcode ) /***********************************************************/ { -TRACK *pt_segm; -int errdrc; -int nb_segm_modifies = 0; -int nb_segm_non_modifies = 0; + TRACK* pt_segm; + int errdrc; + int nb_segm_modifies = 0; + int nb_segm_non_modifies = 0; - if (Netcode <= 0 ) return; + if( Netcode <= 0 ) + return; - if( ! IsOK(this, _("Change track width (entire NET) ?") ) ) return; + if( !IsOK( this, _( "Change track width (entire NET) ?" ) ) ) + return; - /* balayage des segments */ - for( pt_segm = m_Pcb->m_Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) - { - if ( Netcode != pt_segm->GetNet() ) /* mauvaise piste */ - continue ; - /* piste d'un net trouvee */ - errdrc = Edit_TrackSegm_Width(DC, pt_segm); - if(errdrc == BAD_DRC) nb_segm_non_modifies++; - else nb_segm_modifies++; - } + /* balayage des segments */ + for( pt_segm = m_Pcb->m_Track; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) + { + if( Netcode != pt_segm->GetNet() ) /* mauvaise piste */ + continue; + /* piste d'un net trouvee */ + errdrc = Edit_TrackSegm_Width( DC, pt_segm ); + if( errdrc == BAD_DRC ) + nb_segm_non_modifies++; + else + nb_segm_modifies++; + } } - - /*************************************************************************/ -bool WinEDA_PcbFrame::Resize_Pistes_Vias(wxDC * DC, bool Track, bool Via) +bool WinEDA_PcbFrame::Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via ) /*************************************************************************/ + /* remet a jour la largeur des pistes et/ou le diametre des vias - Si piste == 0 , pas de cht sur les pistes - Si via == 0 , pas de cht sur les vias -*/ + * Si piste == 0 , pas de cht sur les pistes + * Si via == 0 , pas de cht sur les vias + */ { -TRACK * pt_segm ; -int errdrc; -int nb_segm_modifies = 0; -int nb_segm_non_modifies = 0; + TRACK* pt_segm; + int errdrc; + int nb_segm_modifies = 0; + int nb_segm_non_modifies = 0; - if ( Track && Via) - { - if( ! IsOK(this, _("Edit All Tracks and Vias Sizes")) ) return FALSE; - } + if( Track && Via ) + { + if( !IsOK( this, _( "Edit All Tracks and Vias Sizes" ) ) ) + return FALSE; + } + else if( Via ) + { + if( !IsOK( this, _( "Edit All Via Sizes" ) ) ) + return FALSE; + } + else if( Track ) + { + if( !IsOK( this, _( "Edit All Track Sizes" ) ) ) + return FALSE; + } - else if ( Via ) - { - if( ! IsOK(this, _("Edit All Via Sizes")) ) return FALSE; - } + pt_segm = m_Pcb->m_Track; + for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) + { + if( pt_segm->Type() == TYPEVIA ) /* mise a jour du diametre de la via */ + { + if( Via ) + { + errdrc = Edit_TrackSegm_Width( DC, pt_segm ); + if( errdrc == BAD_DRC ) + nb_segm_non_modifies++; + else + nb_segm_modifies++; + } + } + else /* mise a jour de la largeur du segment */ + { + if( Track ) + { + errdrc = Edit_TrackSegm_Width( DC, pt_segm ); + if( errdrc == BAD_DRC ) + nb_segm_non_modifies++; + else + nb_segm_modifies++; + } + } + } - else if( Track ) - { - if( ! IsOK(this, _("Edit All Track Sizes")) ) return FALSE; - } - - pt_segm = m_Pcb->m_Track ; - for ( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext ) - { - if( pt_segm->Type() == TYPEVIA ) /* mise a jour du diametre de la via */ - { - if ( Via ) - { - errdrc = Edit_TrackSegm_Width(DC, pt_segm); - if(errdrc == BAD_DRC) nb_segm_non_modifies++; - else nb_segm_modifies++; - } - } - else /* mise a jour de la largeur du segment */ - { - if ( Track ) - { - errdrc = Edit_TrackSegm_Width(DC, pt_segm); - if(errdrc == BAD_DRC) nb_segm_non_modifies++; - else nb_segm_modifies++; - } - } - } - - if ( nb_segm_modifies ) return TRUE; - return FALSE; + if( nb_segm_modifies ) + return TRUE; + return FALSE; } - diff --git a/pcbnew/editrack-part2.cpp b/pcbnew/editrack-part2.cpp index 74795dcaf4..ad051a0a97 100644 --- a/pcbnew/editrack-part2.cpp +++ b/pcbnew/editrack-part2.cpp @@ -123,8 +123,9 @@ void WinEDA_PcbFrame::ExChange_Track_Layer( TRACK* pt_segm, wxDC* DC ) else if( pt_segm->GetLayer() == l2 ) pt_segm->SetLayer( l1 ); - if( (Drc_On) && ( Drc( this, DC, pt_segm, m_Pcb->m_Track, 1 ) == BAD_DRC ) ) - { /* Annulation du changement */ + if( Drc_On && BAD_DRC==m_drc->Drc( pt_segm, m_Pcb->m_Track ) ) + { + /* Annulation du changement */ ii = 0; pt_segm = pt_track; for( ; ii < nb_segm; ii++, pt_segm = (TRACK*) pt_segm->Pnext ) { @@ -197,12 +198,13 @@ void WinEDA_PcbFrame::Other_Layer_Route( TRACK* track, wxDC* DC ) /* Is the current segment Ok (no DRC error) ? */ if( Drc_On ) { - if( Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 ) == BAD_DRC ) + if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track ) ) /* DRC error, the change layer is not made */ return; + if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() ) // We must handle 2 segments { - if( Drc( this, DC, g_CurrentTrackSegment->Back(), m_Pcb->m_Track, 1 ) == BAD_DRC ) + if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), m_Pcb->m_Track ) ) return; } } @@ -248,7 +250,7 @@ void WinEDA_PcbFrame::Other_Layer_Route( TRACK* track, wxDC* DC ) Via->SetLayerPair( COPPER_LAYER_N, LAYER_CMP_N ); } - if( Drc_On &&( Drc( this, DC, Via, m_Pcb->m_Track, 1 ) == BAD_DRC ) ) + if( Drc_On && BAD_DRC==m_drc->Drc( Via, m_Pcb->m_Track ) ) { /* DRC fault: the Via cannot be placed here ... */ delete Via; diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 2414b6c571..05402060c0 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -11,14 +11,13 @@ #include "autorout.h" #include "protos.h" +#include "drc_stuff.h" /* Routines Locales */ static void Exit_Editrack( WinEDA_DrawPanel* panel, wxDC* DC ); void ShowNewTrackWhenMovingCursor( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); -static int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, - TRACK* ptfinsegment ); static void ComputeBreakPoint( TRACK* track, int n ); static TRACK* DeleteNullTrackSegments( BOARD* pcb, TRACK* track, int* segmcount ); static void EnsureEndTrackOnPad( D_PAD* Pad ); @@ -160,9 +159,13 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC ) g_CurrentTrackSegment->Display_Infos( this ); SetCurItem( g_CurrentTrackSegment ); DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); - if( Drc_On && (Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 ) == BAD_DRC) ) + + if( Drc_On ) { - return g_CurrentTrackSegment; + if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track ) ) + { + return g_CurrentTrackSegment; + } } } else /* Track in progress : segment coordinates are updated by ShowNewTrackWhenMovingCursor*/ @@ -170,12 +173,13 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC ) /* Tst for a D.R.C. error: */ if( Drc_On ) { - if( Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 ) == BAD_DRC ) + if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track ) ) return NULL; + if( g_TwoSegmentTrackBuild // We must handle 2 segments && g_CurrentTrackSegment->Back() ) { - if( Drc( this, DC, g_CurrentTrackSegment->Back(), m_Pcb->m_Track, 1 ) == BAD_DRC ) + if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), m_Pcb->m_Track ) ) return NULL; } } @@ -196,7 +200,7 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC ) if( g_Raccord_45_Auto ) { - if( Add_45_degrees_Segment( this, DC, g_CurrentTrackSegment ) != 0 ) + if( Add_45_degrees_Segment( DC, g_CurrentTrackSegment ) != 0 ) g_TrackSegmentCount++; } Track = g_CurrentTrackSegment->Copy(); @@ -229,7 +233,7 @@ TRACK* WinEDA_PcbFrame::Begin_Route( TRACK* track, wxDC* DC ) /**************************************************************************/ -int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm ) +int WinEDA_PcbFrame::Add_45_degrees_Segment( wxDC* DC, TRACK* pt_segm ) /***************************************************************************/ /* rectifie un virage a 90 et le modifie par 2 coudes a 45 @@ -260,9 +264,9 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm return 0; } - pas_45 = frame->GetScreen()->GetGrid().x / 2; + pas_45 = GetScreen()->GetGrid().x / 2; if( pas_45 < pt_segm->m_Width ) - pas_45 = frame->GetScreen()->GetGrid().x; + pas_45 = GetScreen()->GetGrid().x; while( pas_45 < pt_segm->m_Width ) pas_45 *= 2; @@ -309,7 +313,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm else NewTrack->m_End.x -= pas_45; - if( Drc_On && (Drc( frame, DC, pt_segm, frame->m_Pcb->m_Track, 1 ) == BAD_DRC) ) + if( Drc_On && BAD_DRC==m_drc->Drc( pt_segm, m_Pcb->m_Track ) ) { delete NewTrack; return 0; @@ -317,7 +321,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm Previous->m_End = NewTrack->m_Start; pt_segm->m_Start = NewTrack->m_End; - NewTrack->Insert( frame->m_Pcb, Previous ); + NewTrack->Insert( m_Pcb, Previous ); return 1; } @@ -345,7 +349,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm else NewTrack->m_End.y -= pas_45; - if( Drc_On && (Drc( frame, DC, NewTrack, frame->m_Pcb->m_Track, 1 ) == BAD_DRC) ) + if( Drc_On && BAD_DRC==m_drc->Drc( NewTrack, m_Pcb->m_Track ) ) { delete NewTrack; return 0; @@ -353,7 +357,7 @@ int Add_45_degrees_Segment( WinEDA_BasePcbFrame* frame, wxDC* DC, TRACK* pt_segm Previous->m_End = NewTrack->m_Start; pt_segm->m_Start = NewTrack->m_End; - NewTrack->Insert( frame->m_Pcb, Previous ); + NewTrack->Insert( m_Pcb, Previous ); return 1; } @@ -378,7 +382,7 @@ void WinEDA_PcbFrame::End_Route( TRACK* track, wxDC* DC ) if( track == NULL ) return; - if( Drc_On && Drc( this, DC, g_CurrentTrackSegment, m_Pcb->m_Track, 1 )==BAD_DRC ) + if( Drc_On && BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, m_Pcb->m_Track) ) return; /* Sauvegarde des coord du point terminal de la piste */ diff --git a/pcbnew/find.cpp b/pcbnew/find.cpp index 929b287587..b886cbadfb 100644 --- a/pcbnew/find.cpp +++ b/pcbnew/find.cpp @@ -75,7 +75,7 @@ void WinEDA_PcbFindFrame::FindItem( wxCommandEvent& event ) if( marker ) { foundItem = marker; - locate_pos = marker->m_Pos; + locate_pos = marker->GetPosition(); } } else @@ -89,7 +89,7 @@ void WinEDA_PcbFindFrame::FindItem( wxCommandEvent& event ) if( StartCount > s_ItemCount ) { foundItem = module; - locate_pos = module->m_Pos; + locate_pos = module->GetPosition(); s_ItemCount++; break; } diff --git a/pcbnew/initpcb.cpp b/pcbnew/initpcb.cpp index 768ca6c722..6a27dbd0fc 100644 --- a/pcbnew/initpcb.cpp +++ b/pcbnew/initpcb.cpp @@ -351,5 +351,6 @@ void WinEDA_PcbFrame::Erase_Marqueurs() { m_Pcb->DeleteMARKERs(); GetScreen()->SetModify(); + } diff --git a/pcbnew/move_or_drag_track.cpp b/pcbnew/move_or_drag_track.cpp index 66003f5c11..80629b205f 100644 --- a/pcbnew/move_or_drag_track.cpp +++ b/pcbnew/move_or_drag_track.cpp @@ -783,14 +783,14 @@ bool WinEDA_PcbFrame::PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC ) // DRC control: if( Drc_On ) { - errdrc = Drc( this, DC, Track, m_Pcb->m_Track, 1 ); + errdrc = m_drc->Drc( Track, m_Pcb->m_Track ); if( errdrc == BAD_DRC ) return FALSE; /* Redraw the dragged segments */ pt_drag = g_DragSegmentList; for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext ) { - errdrc = Drc( this, DC, pt_drag->m_Segm, m_Pcb->m_Track, 1 ); + errdrc = m_drc->Drc( pt_drag->m_Segm, m_Pcb->m_Track ); if( errdrc == BAD_DRC ) return FALSE; } diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 34417e8f2b..5b49ed5a62 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -11,6 +11,7 @@ #include "bitmaps.h" #include "protos.h" #include "id.h" +#include "drc_stuff.h" /*******************************/ @@ -191,6 +192,8 @@ WinEDA_PcbFrame::WinEDA_PcbFrame( wxWindow* father, WinEDA_App* parent, m_ZoomMaxValue = 2048; m_SelTrackWidthBox_Changed = FALSE; m_SelViaSizeBox_Changed = FALSE; + + m_drc = new DRC( this ); // these 2 objects point to each other m_DisplayPcbTrackFill = DisplayOpt.DisplayPcbTrackFill; m_DisplayPadFill = DisplayOpt.DisplayPadFill; @@ -237,6 +240,7 @@ WinEDA_PcbFrame::~WinEDA_PcbFrame() { m_Parent->m_PcbFrame = NULL; m_CurrentScreen = ScreenPcb; + delete m_drc; } diff --git a/pcbnew/solve.cpp b/pcbnew/solve.cpp index 0db6c7437f..5f2ce6e58f 100644 --- a/pcbnew/solve.cpp +++ b/pcbnew/solve.cpp @@ -380,8 +380,8 @@ static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC, int cY = (g_GridRoutingSize * row_source) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.y; int dx = pt_cur_ch->pad_start->m_Size.x / 2; int dy = pt_cur_ch->pad_start->m_Size.y / 2; - int px = pt_cur_ch->pad_start->m_Pos.x; - int py = pt_cur_ch->pad_start->m_Pos.y; + int px = pt_cur_ch->pad_start->GetPosition().x; + int py = pt_cur_ch->pad_start->GetPosition().y; if( ( (pt_cur_ch->pad_start->m_Orient / 900) & 1 ) != 0 ) EXCHG( dx, dy ); @@ -392,8 +392,8 @@ static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC, cY = (g_GridRoutingSize * row_target) + pcbframe->m_Pcb->m_BoundaryBox.m_Pos.y; dx = pt_cur_ch->pad_end->m_Size.x / 2; dy = pt_cur_ch->pad_end->m_Size.y / 2; - px = pt_cur_ch->pad_end->m_Pos.x; - py = pt_cur_ch->pad_end->m_Pos.y; + px = pt_cur_ch->pad_end->GetPosition().x; + py = pt_cur_ch->pad_end->GetPosition().y; if( ( (pt_cur_ch->pad_end->m_Orient / 900) & 1 ) != 0 ) EXCHG( dx, dy ); @@ -968,14 +968,13 @@ static void OrCell_Trace( BOARD* pcb, int col, int row, /* Replacement sur le centre du pad si hors grille */ dx1 = g_CurrentTrackSegment->m_End.x - g_CurrentTrackSegment->m_Start.x; dy1 = g_CurrentTrackSegment->m_End.y - g_CurrentTrackSegment->m_Start.y; - dx0 = pt_cur_ch->pad_end->m_Pos.x - g_CurrentTrackSegment->m_Start.x; - dy0 = pt_cur_ch->pad_end->m_Pos.y - g_CurrentTrackSegment->m_Start.y; + dx0 = pt_cur_ch->pad_end->GetPosition().x - g_CurrentTrackSegment->m_Start.x; + dy0 = pt_cur_ch->pad_end->GetPosition().y - g_CurrentTrackSegment->m_Start.y; /* si aligne: modif du point origine */ if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) /* Alignes ! */ { - g_CurrentTrackSegment->m_Start.x = pt_cur_ch->pad_end->m_Pos.x; - g_CurrentTrackSegment->m_Start.y = pt_cur_ch->pad_end->m_Pos.y; + g_CurrentTrackSegment->m_Start = pt_cur_ch->pad_end->GetPosition(); } else /* Creation d'un segment suppl raccord */ { @@ -983,10 +982,9 @@ static void OrCell_Trace( BOARD* pcb, int col, int row, g_TrackSegmentCount++; NewTrack->Insert( pcb, g_CurrentTrackSegment ); - g_CurrentTrackSegment->m_Start.x = pt_cur_ch->pad_end->m_Pos.x; - g_CurrentTrackSegment->m_Start.y = pt_cur_ch->pad_end->m_Pos.y; - NewTrack->m_Start.x = g_CurrentTrackSegment->m_End.x; - NewTrack->m_Start.y = g_CurrentTrackSegment->m_End.y; + g_CurrentTrackSegment->m_Start = pt_cur_ch->pad_end->GetPosition(); + + NewTrack->m_Start = g_CurrentTrackSegment->m_End; g_CurrentTrackSegment = NewTrack; } @@ -1053,26 +1051,25 @@ static void Place_Piste_en_Buffer( WinEDA_PcbFrame* pcbframe, wxDC* DC ) dy1 = g_CurrentTrackSegment->m_End.y - g_CurrentTrackSegment->m_Start.y; /* Replacement sur le centre du pad si hors grille */ - dx0 = pt_cur_ch->pad_start->m_Pos.x - g_CurrentTrackSegment->m_Start.x; - dy0 = pt_cur_ch->pad_start->m_Pos.y - g_CurrentTrackSegment->m_Start.y; + dx0 = pt_cur_ch->pad_start->GetPosition().x - g_CurrentTrackSegment->m_Start.x; + dy0 = pt_cur_ch->pad_start->GetPosition().y - g_CurrentTrackSegment->m_Start.y; /* si aligne: modif du point origine */ if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) /* Alignes ! */ { - g_CurrentTrackSegment->m_End.x = pt_cur_ch->pad_start->m_Pos.x; - g_CurrentTrackSegment->m_End.y = pt_cur_ch->pad_start->m_Pos.y; + g_CurrentTrackSegment->m_End = pt_cur_ch->pad_start->GetPosition(); } else /* Creation d'un segment suppl raccord */ { TRACK* NewTrack = g_CurrentTrackSegment->Copy(); NewTrack->Insert( pcbframe->m_Pcb, g_CurrentTrackSegment ); - NewTrack->m_End.x = pt_cur_ch->pad_start->m_Pos.x; - NewTrack->m_End.y = pt_cur_ch->pad_start->m_Pos.y; - NewTrack->m_Start.x = g_CurrentTrackSegment->m_End.x; - NewTrack->m_Start.y = g_CurrentTrackSegment->m_End.y; + NewTrack->m_End = pt_cur_ch->pad_start->GetPosition(); + + NewTrack->m_Start = g_CurrentTrackSegment->m_End; - g_CurrentTrackSegment = NewTrack; g_TrackSegmentCount++; + g_CurrentTrackSegment = NewTrack; + g_TrackSegmentCount++; } diff --git a/pcbnew/zones.cpp b/pcbnew/zones.cpp index eda5f2e24b..0527da881f 100644 --- a/pcbnew/zones.cpp +++ b/pcbnew/zones.cpp @@ -40,7 +40,6 @@ static void Display_Zone_Netname( WinEDA_PcbFrame* frame ); static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ); static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code ); -static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ); /* Local variables */ static bool Zone_Debug = FALSE; @@ -1037,7 +1036,7 @@ void WinEDA_PcbFrame::Fill_Zone( wxDC* DC ) /* Create the thermal reliefs */ g_DesignSettings.m_CurrentTrackWidth = lp_tmp; if( Zone_Exclude_Pads && s_Zone_Create_Thermal_Relief ) - Genere_Pad_Connexion( this, DC, GetScreen()->m_Active_Layer ); + Genere_Pad_Connexion( DC, GetScreen()->m_Active_Layer ); g_DesignSettings.m_TrackClearence = save_isol; @@ -1313,7 +1312,7 @@ int Propagation( WinEDA_PcbFrame* frame ) /*****************************************************************************/ -static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ) +bool WinEDA_PcbFrame::Genere_Pad_Connexion( wxDC* DC, int layer ) /*****************************************************************************/ /* Create the thermal relief for each pad in the zone: @@ -1329,16 +1328,16 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ) int sommet[4][2]; wxString msg; - if( frame->m_Pcb->m_Zone == NULL ) + if( m_Pcb->m_Zone == NULL ) return FALSE; /* error: no zone */ - if( frame->m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* error: this is not the new zone */ + if( m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* error: this is not the new zone */ return FALSE; /* Count the pads, i.e. the thermal relief to create count, and displays it */ - Affiche_1_Parametre( frame, 50, wxT( "NPads" ), wxT( " " ), CYAN ); - pt_liste_pad = (LISTE_PAD*) frame->m_Pcb->m_Pads; - for( ii = 0, Npads = 0; ii < frame->m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) + Affiche_1_Parametre( this, 50, wxT( "NPads" ), wxT( " " ), CYAN ); + pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads; + for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) { pt_pad = *pt_liste_pad; @@ -1353,12 +1352,12 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ) } msg.Printf( wxT( "%d" ), Npads ); - Affiche_1_Parametre( frame, -1, wxEmptyString, msg, CYAN ); + Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN ); /* Create the thermal reliefs */ - Affiche_1_Parametre( frame, 57, wxT( "Pads" ), wxT( " " ), CYAN ); - pt_liste_pad = (LISTE_PAD*) frame->m_Pcb->m_Pads; - for( ii = 0, Npads = 0; ii < frame->m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) + Affiche_1_Parametre( this, 57, wxT( "Pads" ), wxT( " " ), CYAN ); + pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads; + for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) { pt_pad = *pt_liste_pad; @@ -1370,11 +1369,17 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ) continue; /* Create the theram relief for the current pad */ - Npads++; msg.Printf( wxT( "%d" ), Npads ); - Affiche_1_Parametre( frame, -1, wxEmptyString, msg, CYAN ); - cX = pt_pad->m_Pos.x; cY = pt_pad->m_Pos.y; + Npads++; + + msg.Printf( wxT( "%d" ), Npads ); + Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN ); + + cX = pt_pad->GetPosition().x; + cY = pt_pad->GetPosition().y; + dx = pt_pad->m_Size.x / 2; dy = pt_pad->m_Size.y / 2; + dx += g_DesignSettings.m_TrackClearence + g_GridRoutingSize; dy += g_DesignSettings.m_TrackClearence + g_GridRoutingSize; @@ -1395,7 +1400,7 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ) { RotatePoint( &sommet[jj][0], &sommet[jj][1], angle ); - pt_track = new SEGZONE( frame->m_Pcb ); + pt_track = new SEGZONE( m_Pcb ); pt_track->SetLayer( layer ); pt_track->m_Width = g_DesignSettings.m_CurrentTrackWidth; @@ -1407,20 +1412,22 @@ static bool Genere_Pad_Connexion( WinEDA_PcbFrame* frame, wxDC* DC, int layer ) pt_track->m_TimeStamp = s_TimeStamp; /* Test if the segment is allowed */ - if( Drc( frame, DC, pt_track, frame->m_Pcb->m_Track, 0 ) == BAD_DRC ) + if( BAD_DRC==m_drc->DrcBlind( pt_track, m_Pcb->m_Track ) ) { - delete pt_track; continue; + delete pt_track; + continue; } /* Search for a zone segment */ - loctrack = Locate_Zone( frame->m_Pcb->m_Zone, pt_track->m_End, layer ); + loctrack = Locate_Zone( m_Pcb->m_Zone, pt_track->m_End, layer ); if( (loctrack == NULL) || (loctrack->m_TimeStamp != s_TimeStamp) ) { - delete pt_track; continue; + delete pt_track; + continue; } - pt_track->Insert( frame->m_Pcb, NULL ); - pt_track->Draw( frame->DrawPanel, DC, GR_OR ); + pt_track->Insert( m_Pcb, NULL ); + pt_track->Draw( DrawPanel, DC, GR_OR ); } }