diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 0a703179fa..289d3c3c72 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -274,7 +274,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() bool hightQualityMode = false; for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; - layer++ ) + ++layer ) { if( layer != LAST_COPPER_LAYER && layer >= g_Parm_3D_Visu.m_CopperLayersCount ) @@ -528,21 +528,19 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() } int thickness = g_Parm_3D_Visu.GetCopperThicknessBIU(); - for( TRACK* track = pcb->m_Track; track != NULL; track = track->Next() ) - { - // Add via hole - if( track->Type() == PCB_VIA_T ) - { - const VIA *via = static_cast( track ); - VIATYPE_T viatype = via->GetViaType(); - int holediameter = via->GetDrillValue(); - int hole_outer_radius = (holediameter + thickness) / 2; - if( viatype == VIA_THROUGH ) - TransformCircleToPolygon( allLayerHoles, - via->GetStart(), hole_outer_radius, - segcountLowQuality ); - } + // Add via holes + for( VIA* via = GetFirstVia( pcb->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) + { + VIATYPE_T viatype = via->GetViaType(); + int holediameter = via->GetDrillValue(); + int hole_outer_radius = (holediameter + thickness) / 2; + + if( viatype == VIA_THROUGH ) + TransformCircleToPolygon( allLayerHoles, + via->GetStart(), hole_outer_radius, + segcountLowQuality ); } // draw pads holes @@ -562,7 +560,7 @@ void EDA_3D_CANVAS::BuildTechLayers3DView() allLayerHoles.ExportTo( brdpolysetHoles ); for( LAYER_NUM layer = FIRST_NON_COPPER_LAYER; layer <= LAST_NON_COPPER_LAYER; - layer++ ) + ++layer ) { // Skip user layers, which are not drawn here if( IsUserLayer( layer) ) @@ -713,7 +711,7 @@ void EDA_3D_CANVAS::BuildBoard3DAuxLayers() bufferPolys.reserve( 5000 ); // Reserve for items not on board for( LAYER_NUM layer = FIRST_USER_LAYER; layer <= LAST_USER_LAYER; - layer++ ) + ++layer ) { if( !Is3DLayerEnabled( layer ) ) continue; diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 86a8ed9727..9a7d2a5390 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -1345,7 +1345,7 @@ SCH_SCREEN* SCH_SCREENS::GetNext() } -SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) +SCH_SCREEN* SCH_SCREENS::GetScreen( unsigned int aIndex ) const { if( aIndex < m_screens.size() ) return m_screens[ aIndex ]; diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 23ef5272c3..230ea77fe3 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -112,7 +112,7 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const } -SCH_SHEET* SCH_SHEET_PATH::Last() +SCH_SHEET* SCH_SHEET_PATH::Last() const { if( m_numSheets ) return m_sheets[m_numSheets - 1]; @@ -121,7 +121,7 @@ SCH_SHEET* SCH_SHEET_PATH::Last() } -SCH_SCREEN* SCH_SHEET_PATH::LastScreen() +SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const { SCH_SHEET* lastSheet = Last(); @@ -132,7 +132,7 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen() } -SCH_ITEM* SCH_SHEET_PATH::LastDrawList() +SCH_ITEM* SCH_SHEET_PATH::LastDrawList() const { SCH_SHEET* lastSheet = Last(); @@ -143,7 +143,7 @@ SCH_ITEM* SCH_SHEET_PATH::LastDrawList() } -SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() +SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() const { SCH_ITEM* item = NULL; @@ -316,7 +316,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu } -SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) +SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const { bool hasWrapped = false; bool firstItemFound = false; @@ -349,7 +349,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool } -SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) +SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) const { bool hasWrapped = false; bool firstItemFound = false; diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index dcfe9b690a..f6a32fbeb9 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -129,20 +129,20 @@ public: * returns a pointer to the last sheet of the list * One can see the others sheet as the "path" to reach this last sheet */ - SCH_SHEET* Last(); + SCH_SHEET* Last() const; /** * Function LastScreen * @return the SCH_SCREEN relative to the last sheet in list */ - SCH_SCREEN* LastScreen(); + SCH_SCREEN* LastScreen() const; /** * Function LastDrawList * @return a pointer to the first schematic item handled by the * SCH_SCREEN relative to the last sheet in list */ - SCH_ITEM* LastDrawList(); + SCH_ITEM* LastDrawList() const; /** * Get the last schematic item relative to the first sheet in the list. @@ -150,7 +150,7 @@ public: * @return Last schematic item relative to the first sheet in the list if list * is not empty. Otherwise NULL. */ - SCH_ITEM* FirstDrawList(); + SCH_ITEM* FirstDrawList() const; /** * Function Push @@ -248,7 +248,7 @@ public: * is defined. * @return - The next schematic item if found. Otherwise, NULL is returned. */ - SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); + SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const; /** * Find the previous schematic item in this sheet path object. @@ -260,7 +260,7 @@ public: * is defined. * @return - The previous schematic item if found. Otherwise, NULL is returned. */ - SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); + SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ) const; SCH_SHEET_PATH& operator=( const SCH_SHEET_PATH& d1 ); @@ -318,7 +318,7 @@ public: * @return the number of sheets in list: * usually the number of sheets found in the whole hierarchy */ - int GetCount() { return m_count; } + int GetCount() const { return m_count; } /** * Function GetFirst diff --git a/gerbview/class_gbr_screen.h b/gerbview/class_gbr_screen.h index 8be96b21d5..9e89373e53 100644 --- a/gerbview/class_gbr_screen.h +++ b/gerbview/class_gbr_screen.h @@ -26,7 +26,7 @@ public: ~GBR_SCREEN(); - GBR_SCREEN* Next() { return (GBR_SCREEN*) Pnext; } + GBR_SCREEN* Next() const { return static_cast( Pnext ); } // void SetNextZoom(); // void SetPreviousZoom(); diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h index 2989333c0a..70ad0a1164 100644 --- a/gerbview/class_gerber_draw_item.h +++ b/gerbview/class_gerber_draw_item.h @@ -116,8 +116,8 @@ public: */ GERBER_DRAW_ITEM* Copy() const; - GERBER_DRAW_ITEM* Next() const { return (GERBER_DRAW_ITEM*) Pnext; } - GERBER_DRAW_ITEM* Back() const { return (GERBER_DRAW_ITEM*) Pback; } + GERBER_DRAW_ITEM* Next() const { return static_cast( Pnext ); } + GERBER_DRAW_ITEM* Back() const { return static_cast( Pback ); } /** * Function GetLayer diff --git a/include/base_struct.h b/include/base_struct.h index 8679cfdd5b..9ec7af03c8 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -375,8 +375,8 @@ public: void SetTimeStamp( time_t aNewTimeStamp ) { m_TimeStamp = aNewTimeStamp; } time_t GetTimeStamp() const { return m_TimeStamp; } - EDA_ITEM* Next() const { return (EDA_ITEM*) Pnext; } - EDA_ITEM* Back() const { return (EDA_ITEM*) Pback; } + EDA_ITEM* Next() const { return Pnext; } + EDA_ITEM* Back() const { return Pback; } EDA_ITEM* GetParent() const { return m_Parent; } DHEAD* GetList() const { return m_List; } diff --git a/include/class_board_item.h b/include/class_board_item.h index ceb428af5e..26a30af896 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -108,8 +108,8 @@ public: */ static wxPoint ZeroOffset; - BOARD_ITEM* Next() const { return (BOARD_ITEM*) Pnext; } - BOARD_ITEM* Back() const { return (BOARD_ITEM*) Pback; } + BOARD_ITEM* Next() const { return static_cast( Pnext ); } + BOARD_ITEM* Back() const { return static_cast( Pback ); } BOARD_ITEM* GetParent() const { return (BOARD_ITEM*) m_Parent; } /** diff --git a/include/class_pcb_screen.h b/include/class_pcb_screen.h index e15082be40..59f3f3d592 100644 --- a/include/class_pcb_screen.h +++ b/include/class_pcb_screen.h @@ -31,7 +31,7 @@ public: ~PCB_SCREEN(); - PCB_SCREEN* Next() { return (PCB_SCREEN*) Pnext; } + PCB_SCREEN* Next() const { return static_cast( Pnext ); } void SetNextZoom(); void SetPreviousZoom(); diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index 02a6787679..acf8f20819 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -523,7 +523,7 @@ public: int GetCount() const { return m_screens.size(); } SCH_SCREEN* GetFirst(); SCH_SCREEN* GetNext(); - SCH_SCREEN* GetScreen( unsigned int aIndex ); + SCH_SCREEN* GetScreen( unsigned int aIndex ) const; /** * Function ClearAnnotation diff --git a/include/sch_item_struct.h b/include/sch_item_struct.h index e425e1d6b1..5fe90cd69f 100644 --- a/include/sch_item_struct.h +++ b/include/sch_item_struct.h @@ -136,8 +136,8 @@ public: */ virtual void SwapData( SCH_ITEM* aItem ); - SCH_ITEM* Next() { return (SCH_ITEM*) Pnext; } - SCH_ITEM* Back() { return (SCH_ITEM*) Pback; } + SCH_ITEM* Next() const { return static_cast( Pnext ); } + SCH_ITEM* Back() const { return static_cast( Pback ); } /** * Function GetLayer diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 2960e9e315..a7b4e35987 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1563,19 +1563,12 @@ int BOARD::SetAreasNetCodesFromNetNames( void ) VIA* BOARD::GetViaByPosition( const wxPoint& aPosition, LAYER_NUM aLayer) const { - for( TRACK *track = m_Track; track; track = track->Next() ) + for( VIA *via = GetFirstVia( m_Track); via; via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - if( track->GetStart() != aPosition ) - continue; - - if( track->GetState( BUSY | IS_DELETED ) ) - continue; - - if( (aLayer == UNDEFINED_LAYER) || (track->IsOnLayer( aLayer )) ) - return static_cast( track ); + if( (via->GetStart() == aPosition) && + (via->GetState( BUSY | IS_DELETED ) == 0) && + ((aLayer == UNDEFINED_LAYER) || (via->IsOnLayer( aLayer ))) ) + return via; } return NULL; diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h index 635a3235d7..64ce5dcb8c 100644 --- a/pcbnew/class_drawsegment.h +++ b/pcbnew/class_drawsegment.h @@ -68,9 +68,6 @@ public: /// skip the linked list stuff, and parent const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs ); - DRAWSEGMENT* Next() const { return (DRAWSEGMENT*) Pnext; } - DRAWSEGMENT* Back() const { return (DRAWSEGMENT*) Pback; } - void SetWidth( int aWidth ) { m_Width = aWidth; } int GetWidth() const { return m_Width; } diff --git a/pcbnew/class_edge_mod.h b/pcbnew/class_edge_mod.h index 8c6559ad74..18790d9b9b 100644 --- a/pcbnew/class_edge_mod.h +++ b/pcbnew/class_edge_mod.h @@ -51,9 +51,6 @@ public: ~EDGE_MODULE(); - EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; } - EDGE_MODULE* Back() const { return (EDGE_MODULE*) Pback; } - /// skip the linked list stuff, and parent const EDGE_MODULE& operator = ( const EDGE_MODULE& rhs ); diff --git a/pcbnew/class_mire.h b/pcbnew/class_mire.h index da42a07fb0..0a7186b6b1 100644 --- a/pcbnew/class_mire.h +++ b/pcbnew/class_mire.h @@ -56,9 +56,6 @@ public: ~PCB_TARGET(); - PCB_TARGET* Next() const { return (PCB_TARGET*) Pnext; } - PCB_TARGET* Back() const { return (PCB_TARGET*) Pnext; } - void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // override const wxPoint& GetPosition() const { return m_Pos; } // override diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 26527c095a..ca343a6333 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -422,9 +422,12 @@ EDA_RECT MODULE::GetFootprintRect() const area.SetEnd( m_Pos ); area.Inflate( Millimeter2iu( 0.25 ) ); // Give a min size to the area - for( EDGE_MODULE* edge = (EDGE_MODULE*) m_Drawings.GetFirst(); edge; edge = edge->Next() ) - if( edge->Type() == PCB_MODULE_EDGE_T ) + for( const BOARD_ITEM* item = m_Drawings.GetFirst(); item; item = item->Next() ) + { + const EDGE_MODULE *edge = dynamic_cast( item ); + if( edge ) area.Merge( edge->GetBoundingBox() ); + } for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) area.Merge( pad->GetBoundingBox() ); diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h index 3127d73fb1..189abfe6be 100644 --- a/pcbnew/class_module.h +++ b/pcbnew/class_module.h @@ -77,8 +77,8 @@ public: ~MODULE(); - MODULE* Next() const { return (MODULE*) Pnext; } - MODULE* Back() const { return (MODULE*) Pback; } + MODULE* Next() const { return static_cast( Pnext ); } + MODULE* Back() const { return static_cast( Pback ); } void Copy( MODULE* Module ); // Copy structure diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h index 11b49568c1..3cbdcbe82a 100644 --- a/pcbnew/class_pad.h +++ b/pcbnew/class_pad.h @@ -106,7 +106,7 @@ public: void Copy( D_PAD* source ); - D_PAD* Next() const { return (D_PAD*) Pnext; } + D_PAD* Next() const { return static_cast( Pnext ); } MODULE* GetParent() const { return (MODULE*) m_Parent; } diff --git a/pcbnew/class_text_mod.h b/pcbnew/class_text_mod.h index 97e15ab202..bc207e7254 100644 --- a/pcbnew/class_text_mod.h +++ b/pcbnew/class_text_mod.h @@ -98,10 +98,6 @@ public: void Flip( const wxPoint& aCentre ); - TEXTE_MODULE* Next() const { return (TEXTE_MODULE*) Pnext; } - - TEXTE_MODULE* Back() const { return (TEXTE_MODULE*) Pback; } - /// @deprecated it seems (but the type is used to 'protect' //reference and value from deletion, and for identification) void SetType( TEXT_TYPE aType ) { m_Type = aType; } diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index abf4d7a732..8b454c9610 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -88,12 +88,9 @@ inline bool IsNear( const wxPoint& p1, const wxPoint& p2, int max_dist ) } -TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, +TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ) { - if( aStartTrace == NULL ) - return NULL; - for( TRACK *PtSegm = aStartTrace; PtSegm != NULL; PtSegm = PtSegm->Next() ) { if( PtSegm->GetState( IS_DELETED | BUSY ) == 0 ) @@ -180,7 +177,6 @@ VIA::VIA( BOARD_ITEM* aParent ) : { SetViaType( VIA_THROUGH ); m_BottomLayer = LAYER_N_BACK; - m_Width = Millimeter2iu( 0.5 ); SetDrillDefault(); } @@ -369,9 +365,14 @@ void TRACK::Flip( const wxPoint& aCentre ) { m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y); + SetLayer( FlipLayer( GetLayer() ) ); +} - if( Type() != PCB_VIA_T ) - SetLayer( FlipLayer( GetLayer() ) ); + +void VIA::Flip( const wxPoint& aCentre ) +{ + m_Start.y = aCentre.y - (m_Start.y - aCentre.y); + m_End.y = aCentre.y - (m_End.y - aCentre.y); } diff --git a/pcbnew/class_track.h b/pcbnew/class_track.h index 63c9026967..0417048fa3 100644 --- a/pcbnew/class_track.h +++ b/pcbnew/class_track.h @@ -74,7 +74,7 @@ enum VIATYPE_T * layer mask. * @return A TRACK object pointer if found otherwise NULL. */ -extern TRACK* GetTrack( TRACK* aStartTrace, TRACK* aEndTrace, +extern TRACK* GetTrack( TRACK* aStartTrace, const TRACK* aEndTrace, const wxPoint& aPosition, LAYER_MSK aLayerMask ); class TRACK : public BOARD_CONNECTED_ITEM @@ -100,8 +100,8 @@ public: // Do not create a copy constructor. The one generated by the compiler is adequate. - TRACK* Next() const { return (TRACK*) Pnext; } - TRACK* Back() const { return (TRACK*) Pback; } + TRACK* Next() const { return static_cast( Pnext ); } + TRACK* Back() const { return static_cast( Pback ); } virtual void Move( const wxPoint& aMoveVector ) { @@ -350,7 +350,7 @@ public: } - SEGZONE* Next() const { return (SEGZONE*) Pnext; } + SEGZONE* Next() const { return static_cast( Pnext ); } wxString GetSelectMenuText() const; @@ -415,6 +415,8 @@ public: /// @copydoc VIEW_ITEM::ViewGetLayers() virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + virtual void Flip( const wxPoint& aCentre ); + #if defined (DEBUG) virtual void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif @@ -469,5 +471,13 @@ private: int m_Drill; // for vias: via drill (- 1 for default value) }; +/// Scan a track list for the first VIA o NULL if not found (or NULL passed) +inline VIA *GetFirstVia( TRACK *aTrk, const TRACK *aStopPoint = NULL ) +{ + while( aTrk && (aTrk != aStopPoint) && (aTrk->Type() != PCB_VIA_T) ) + aTrk = aTrk->Next(); + + return static_cast( aTrk ); +} #endif /* CLASS_TRACK_H */ diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 4bcfb5127e..127f0cbae5 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -87,6 +87,11 @@ private: */ TRACK* mergeCollinearSegmentIfPossible( TRACK* aTrackRef, TRACK* aCandidate, ENDPOINT_T aEndType ); + + const ZONE_CONTAINER* zoneForTrackEndpoint( const TRACK *aTrack, + ENDPOINT_T aEndPoint ); + + bool testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint ); }; /* Install the cleanup dialog frame to know what should be cleaned @@ -101,7 +106,7 @@ void PCB_EDIT_FRAME::Clean_Pcb() wxBusyCursor( dummy ); TRACKS_CLEANER cleaner( GetBoard() ); - cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, + cleaner.CleanupBoard( this, dlg.m_cleanVias, dlg.m_mergeSegments, dlg.m_deleteUnconnectedSegm ); m_canvas->Refresh( true ); } @@ -134,8 +139,6 @@ bool TRACKS_CLEANER::CleanupBoard( PCB_EDIT_FRAME *aFrame, if( modified ) { // Clear undo and redo lists to avoid inconsistencies between lists - // XXX This is very involved... maybe a member in PCB_EDIT_FRAME - // would be better? aFrame->GetScreen()->ClearUndoRedoList(); aFrame->SetCurItem( NULL ); aFrame->Compile_Ratsnest( NULL, true ); @@ -158,7 +161,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() BuildTracksCandidatesList( m_Brd->m_Track, NULL); // clear flags and variables used in cleanup - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() ) { track->start = NULL; track->end = NULL; @@ -168,7 +171,7 @@ void TRACKS_CLEANER::buildTrackConnectionInfo() // Build connections info tracks to pads SearchTracksConnectedToPads(); - for( TRACK * track = m_Brd->m_Track; track; track = track->Next() ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = track->Next() ) { // Mark track if connected to pads for( unsigned jj = 0; jj < track->m_PadsConnected.size(); jj++ ) @@ -194,70 +197,50 @@ bool TRACKS_CLEANER::clean_vias() { bool modified = false; - for( TRACK* track = m_Brd->m_Track; track; track = track->Next() ) + for( VIA* via = GetFirstVia( m_Brd->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) { - // Correct via m_End defects (if any) - if( track->Type() == PCB_VIA_T ) + // Correct via m_End defects (if any), should never happen + if( via->GetStart() != via->GetEnd() ) { - if( track->GetStart() != track->GetEnd() ) - track->SetEnd( track->GetStart() ); - - VIA *via = static_cast( track ); - /* Important: this cleanup only does thru hole vias, it doesn't - * (yet) handle high density interconnects */ - if( via->GetViaType() != VIA_THROUGH ) - continue; + wxFAIL_MSG( "Via with mismatching ends" ); + via->SetEnd( via->GetStart() ); } - else - continue; - // Search and delete others vias at same location - TRACK* alt_track = track->Next(); - - TRACK* next_track; - for( ; alt_track != NULL; alt_track = next_track ) + /* Important: these cleanups only do thru hole vias, they don't + * (yet) handle high density interconnects */ + if( via->GetViaType() != VIA_THROUGH ) { - next_track = alt_track->Next(); - VIA *alt_via = dynamic_cast( alt_track ); - if( alt_via ) + // Search and delete others vias at same location + VIA* next_via; + for( VIA* alt_via = GetFirstVia( via->Next() ); alt_via != NULL; + alt_via = next_via ) { - if( alt_via->GetViaType() != VIA_THROUGH ) - continue; + next_via = GetFirstVia( alt_via->Next() ); - if( alt_via->GetStart() != track->GetStart() ) - continue; - - // delete via - alt_track->UnLink(); - delete alt_track; - modified = true; + if( (alt_via->GetViaType() == VIA_THROUGH) && + (alt_via->GetStart() == via->GetStart()) ) + { + // delete via + alt_via->DeleteStructure(); + modified = true; + } } - } - } - // Delete Via on pads at same location - TRACK* next_track; - for( TRACK* track = m_Brd->m_Track; track != NULL; track = next_track ) - { - next_track = track->Next(); - - VIA *via = dynamic_cast( track ); - if( !via || (via->GetViaType() != VIA_THROUGH )) - continue; - - // Examine the list of connected pads: - // if one pad through is found, the via can be removed - for( unsigned ii = 0; ii < track->m_PadsConnected.size(); ii++ ) - { - D_PAD * pad = track->m_PadsConnected[ii]; - - if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + /* To delete through Via on THT pads at same location + * Examine the list of connected pads: + * if one through pad is found, the via can be removed */ + for( unsigned ii = 0; ii < via->m_PadsConnected.size(); ++ii ) { - // redundant: via delete it - track->UnLink(); - delete track; - modified = true; - break; + const D_PAD *pad = via->m_PadsConnected[ii]; + + if( (pad->GetLayerMask() & ALL_CU_LAYERS) == ALL_CU_LAYERS ) + { + // redundant: delete the via + via->DeleteStructure(); + modified = true; + break; + } } } } @@ -265,6 +248,64 @@ bool TRACKS_CLEANER::clean_vias() return modified; } +/// Utility for checking if a track/via ends on a zone +const ZONE_CONTAINER* TRACKS_CLEANER::zoneForTrackEndpoint( const TRACK *aTrack, + ENDPOINT_T aEndPoint ) +{ + // Vias are special cased, since they get a layer range, not a single one + LAYER_NUM top_layer, bottom_layer; + const VIA *via = dynamic_cast( aTrack ); + + if( via ) + via->LayerPair( &top_layer, &bottom_layer ); + else + { + top_layer = aTrack->GetLayer(); + bottom_layer = top_layer; + } + return m_Brd->HitTestForAnyFilledArea( aTrack->GetEndPoint( aEndPoint ), + top_layer, bottom_layer, aTrack->GetNetCode() ); +} + +/** Utility: does the endpoint unconnected processed for one endpoint of one track + * Returns true if the track must be deleted, false if not necessarily */ +bool TRACKS_CLEANER::testTrackEndpointDangling( TRACK *aTrack, ENDPOINT_T aEndPoint ) +{ + bool flag_erase = false; + + TRACK* other = aTrack->GetTrack( m_Brd->m_Track, NULL, aEndPoint ); + if( (other == NULL) && + (zoneForTrackEndpoint( aTrack, aEndPoint ) == NULL) ) + flag_erase = true; // Start endpoint is neither on pad, zone or other track + else // segment, via or zone connected to this end + { + // Fill connectivity informations + if( aEndPoint == ENDPOINT_START ) + aTrack->start = other; + else + aTrack->end = other; + + /* If a via is connected to this end, test if this via has a second item connected. + * If not, remove the current segment (the via would then become + * unconnected and remove on the following pass) */ + VIA* via = dynamic_cast( other ); + if( via ) + { + // search for another segment following the via + aTrack->SetState( BUSY, true ); + + other = via->GetTrack( m_Brd->m_Track, NULL, aEndPoint ); + + // There is a via on the start but it goes nowhere + if( (other == NULL) && + (zoneForTrackEndpoint( via, aEndPoint ) == NULL) ) + flag_erase = true; + + aTrack->SetState( BUSY, false ); + } + } + return flag_erase; +} /* * Delete dangling tracks @@ -277,161 +318,44 @@ bool TRACKS_CLEANER::deleteUnconnectedTracks() return false; bool modified = false; - bool item_erased = true; - while( item_erased ) // Iterate when at least one track is deleted + bool item_erased; + do // Iterate when at least one track is deleted { item_erased = false; TRACK* next_track; - for( TRACK * track = m_Brd->m_Track; track ; track = next_track ) + for( TRACK *track = m_Brd->m_Track; track != NULL; track = next_track ) { next_track = track->Next(); - int flag_erase = 0; //Not connected indicator - int type_end = 0; + bool flag_erase = false; // Start without a good reason to erase it - if( track->GetState( START_ON_PAD ) ) - type_end |= START_ON_PAD; + /* if a track endpoint is not connected to a pad, test if + * the endpoint is connected to another track or to a zone. + * For via test, an enhancement could be to test if + * connected to 2 items on different layers. Currently + * a via must be connected to 2 items, that can be on the + * same layer */ - if( track->GetState( END_ON_PAD ) ) - type_end |= END_ON_PAD; + // Check if there is nothing attached on the start + if( !(track->GetState( START_ON_PAD )) ) + flag_erase |= testTrackEndpointDangling( track, ENDPOINT_START ); - // if the track start point is not connected to a pad, - // test if this track start point is connected to another track - // For via test, an enhancement could be to test if connected - // to 2 items on different layers. - // Currently a via must be connected to 2 items, that can be on the same layer - LAYER_NUM top_layer, bottom_layer; - ZONE_CONTAINER* zone; - - if( (type_end & START_ON_PAD ) == 0 ) - { - TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); - - if( other == NULL ) // Test a connection to zones - { - if( track->Type() != PCB_VIA_T ) - { - zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), - track->GetLayer(), - track->GetLayer(), - track->GetNetCode() ); - } - else - { - ((VIA*)track)->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( track->GetStart(), - top_layer, bottom_layer, - track->GetNetCode() ); - } - } - - if( (other == NULL) && (zone == NULL) ) - { - flag_erase |= 1; - } - else // segment, via or zone connected to this end - { - track->start = other; - // If a via is connected to this end, - // test if this via has a second item connected. - // If no, remove it with the current segment - - if( other && other->Type() == PCB_VIA_T ) - { - // search for another segment following the via - track->SetState( BUSY, true ); - - VIA* via = (VIA*) other; - other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_START ); - - if( other == NULL ) - { - via->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( via->GetStart(), - bottom_layer, - top_layer, - via->GetNetCode() ); - } - - if( (other == NULL) && (zone == NULL) ) - flag_erase |= 2; - - track->SetState( BUSY, false ); - } - } - } - - // if track end point is not connected to a pad, - // test if this track end point is connected to an other track - if( (type_end & END_ON_PAD ) == 0 ) - { - TRACK* other = track->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); - - if( other == NULL ) // Test a connection to zones - { - if( track->Type() != PCB_VIA_T ) - { - zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), - track->GetLayer(), - track->GetLayer(), - track->GetNetCode() ); - } - else - { - ((VIA*)track)->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( track->GetEnd(), - top_layer, bottom_layer, - track->GetNetCode() ); - } - } - - if ( (other == NULL) && (zone == NULL) ) - { - flag_erase |= 0x10; - } - else // segment, via or zone connected to this end - { - track->end = other; - - // If a via is connected to this end, test if this via has a second item connected - // if no, remove it with the current segment - - if( other && other->Type() == PCB_VIA_T ) - { - // search for another segment following the via - - track->SetState( BUSY, true ); - - VIA* via = (VIA*) other; - other = via->GetTrack( m_Brd->m_Track, NULL, ENDPOINT_END ); - - if( other == NULL ) - { - via->LayerPair( &top_layer, &bottom_layer ); - zone = m_Brd->HitTestForAnyFilledArea( via->GetEnd(), - bottom_layer, top_layer, - via->GetNetCode() ); - } - - if( (other == NULL) && (zone == NULL) ) - flag_erase |= 0x20; - - track->SetState( BUSY, false ); - } - } - } + // Check if there is nothing attached on the end + if( !(track->GetState( END_ON_PAD )) ) + flag_erase |= testTrackEndpointDangling( track, ENDPOINT_END ); if( flag_erase ) { // remove segment from board track->DeleteStructure(); - // iterate, because a track connected to the deleted track - // is now perhaps now not connected and should be deleted + + /* keep iterating, because a track connected to the deleted track + * now perhaps is not connected and should be deleted */ item_erased = true; modified = true; } } - } + } while( item_erased ); return modified; } diff --git a/pcbnew/edgemod.cpp b/pcbnew/edgemod.cpp index 7239dc37a8..77019494f2 100644 --- a/pcbnew/edgemod.cpp +++ b/pcbnew/edgemod.cpp @@ -169,12 +169,11 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge ) { aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems(); - for( ; aEdge != NULL; aEdge = aEdge->Next() ) + for( BOARD_ITEM *item = module->GraphicalItems(); item; item = item->Next() ) { - if( aEdge->Type() != PCB_MODULE_EDGE_T ) - continue; - - aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); + aEdge = dynamic_cast( item ); + if( aEdge ) + aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); } } else @@ -216,14 +215,12 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge ) if( aEdge == NULL ) { - aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->GraphicalItems(); - - for( ; aEdge != NULL; aEdge = aEdge->Next() ) + for( BOARD_ITEM *item = module->GraphicalItems() ; item != NULL; + item = item->Next() ) { - if( aEdge->Type() != PCB_MODULE_EDGE_T ) - continue; + aEdge = dynamic_cast( item ); - if( aEdge->GetLayer() != new_layer ) + if( aEdge && (aEdge->GetLayer() != new_layer) ) { if( ! modified ) // save only once SaveCopyInUndoList( module, UR_MODEDIT ); diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index 683b7d41d7..220668148c 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -62,9 +62,9 @@ static void Abort_Create_Track( EDA_DRAW_PANEL* Panel, wxDC* DC ) { PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Panel->GetParent(); BOARD* pcb = frame->GetBoard(); - TRACK* track = (TRACK*) frame->GetCurItem(); + TRACK* track = dynamic_cast( frame->GetCurItem() ); - if( track && ( track->Type()==PCB_VIA_T || track->Type()==PCB_TRACE_T ) ) + if( track ) { // Erase the current drawing ShowNewTrackWhenMovingCursor( Panel, DC, wxDefaultPosition, false ); diff --git a/pcbnew/exporters/export_gencad.cpp b/pcbnew/exporters/export_gencad.cpp index 601c91ae6d..c1895cbc7b 100644 --- a/pcbnew/exporters/export_gencad.cpp +++ b/pcbnew/exporters/export_gencad.cpp @@ -271,12 +271,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) } // The same for vias - for( TRACK* track = aPcb->m_Track; track != NULL; track = track->Next() ) + for( VIA* via = GetFirstVia( aPcb->m_Track ); via != NULL; + via = GetFirstVia( via->Next() ) ) { - if( track->Type() == PCB_VIA_T ) - { - vias.push_back( static_cast(track) ); - } + vias.push_back( via ); } qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort ); diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp index a8a086187a..679df5bed1 100644 --- a/pcbnew/exporters/gendrill_Excellon_writer.cpp +++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp @@ -453,12 +453,9 @@ void EXCELLON_WRITER::BuildHolesList( int aFirstLayer, // build hole list for vias if( ! aGenerateNPTH_list ) // vias are always plated ! { - for( TRACK* track = m_pcb->m_Track; track; track = track->Next() ) + for( VIA* via = GetFirstVia( m_pcb->m_Track ); via; + via = GetFirstVia( via->Next() ) ) { - if( track->Type() != PCB_VIA_T ) - continue; - - const VIA* via = (const VIA*) track; hole_value = via->GetDrillValue(); if( hole_value == 0 ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 1535b3593f..8494eb560b 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -148,10 +148,11 @@ bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule ) PlotTextModule( &aModule->Value(), GetValueColor() ); } - for( textModule = (TEXTE_MODULE*) aModule->GraphicalItems().GetFirst(); - textModule != NULL; textModule = textModule->Next() ) + for( BOARD_ITEM *item = aModule->GraphicalItems().GetFirst(); + item != NULL; item = item->Next() ) { - if( textModule->Type() != PCB_MODULE_TEXT_T ) + textModule = dynamic_cast( item ); + if( !textModule ) continue; if( !GetPlotOtherText() ) @@ -350,13 +351,11 @@ void BRDITEMS_PLOTTER::Plot_Edges_Modules() { for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { - for( EDGE_MODULE* edge = (EDGE_MODULE*) module->GraphicalItems().GetFirst(); - edge; edge = edge->Next() ) + for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() ) { - if( edge->Type() != PCB_MODULE_EDGE_T ) - continue; + EDGE_MODULE *edge = dynamic_cast( item ); - if( ( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0 ) + if( !edge || (( GetLayerMask( edge->GetLayer() ) & m_layerMask ) == 0) ) continue; Plot_1_EdgeModule( edge );