From 3bb1764dff15acccb463a70fc4dae1c059778407 Mon Sep 17 00:00:00 2001 From: dickelbeck Date: Mon, 10 Mar 2008 15:00:22 +0000 Subject: [PATCH] delete track uses dirty rect --- change_log.txt | 5 +- include/drawpanel_wxstruct.h | 12 ++ include/wxPcbStruct.h | 4 +- pcbnew/class_track.cpp | 69 ++++----- pcbnew/clean.cpp | 280 +++++++++++++++++------------------ pcbnew/deltrack.cpp | 48 ++---- pcbnew/track.cpp | 17 ++- share/drawpanel.cpp | 15 ++ 8 files changed, 229 insertions(+), 221 deletions(-) diff --git a/change_log.txt b/change_log.txt index e4645d82e3..76e74bb7c0 100644 --- a/change_log.txt +++ b/change_log.txt @@ -8,7 +8,7 @@ email address. 2008-Mar-10 UPDATE Dick Hollenbeck ================================================================================ +pcbnew - * Improved some comments on new functions. + * Improved some comments on new functions dirty area functions * Changed void ConvertPcbUnitsToPixelsUnits( EDA_Rect& aRect ); to void ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect ); @@ -21,6 +21,9 @@ email address. * Changed from "new wxDCClip()" to use an automatic wxDCClip() variable in drawpanel.cpp * Removed a printf() from "release" build of drawpanel.cpp + * Added WinEDA_DrawPanel::PostDirtyRect() + * Renamed Supprime_Une_Piste() to Remove_One_Track() and it now uses + PostDirtyRect(). 2008-Mar-10 UPDATE Jean-Pierre Charras diff --git a/include/drawpanel_wxstruct.h b/include/drawpanel_wxstruct.h index 550c2cecd6..de514d8a68 100644 --- a/include/drawpanel_wxstruct.h +++ b/include/drawpanel_wxstruct.h @@ -96,6 +96,18 @@ public: wxPoint CursorRealPosition( const wxPoint& ScreenPos ); wxPoint CursorScreenPosition(); + /** + * Function PostDirtyRect + * appends the given rectangle in pcb units to the DrawPanel's invalid + * region list so that very soon (but not immediately), this rectangle + * along with any other recently posted rectangles is redrawn. Conversion + * to pixels is done in here. + * @param aRect The rectangle to append, it must be orthogonal + * (vertical and horizontal edges only), and it must be [,) in nature, i.e. + * [pos, dim) == [inclusive, exclusive) + */ + void PostDirtyRect( EDA_Rect aRect ); + /** * Function ConvertPcbUnitsToPixelsUnits * converts pos and size of the given EDA_Rect to pos and size in pixels, diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index cdbd972cd8..73c6f456a5 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -476,7 +476,7 @@ public: TRACK* Delete_Segment( wxDC* DC, TRACK* Track ); void Delete_Track( wxDC* DC, TRACK* Track ); void Delete_net( wxDC* DC, TRACK* Track ); - void Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm ); + void Remove_One_Track( wxDC* DC, TRACK* pt_segm ); bool Resize_Pistes_Vias( wxDC* DC, bool Track, bool Via ); void Edit_Net_Width( wxDC* DC, int Netcode ); void Edit_Track_Width( wxDC* DC, TRACK* Track ); @@ -489,7 +489,7 @@ public: void Attribut_net( wxDC* DC, int net_code, bool Flag_On ); void Start_MoveOneNodeOrSegment( TRACK* track, wxDC* DC, int command ); bool PlaceDraggedTrackSegment( TRACK* Track, wxDC* DC ); - bool MergeCollinearTracks( TRACK* track, wxDC* DC, int end ); + bool MergeCollinearTracks( TRACK* track, wxDC* DC, int end ); void Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC ); void SwitchLayer( wxDC* DC, int layer ); int Add_45_degrees_Segment( wxDC* DC, TRACK* pt_segm ); diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index d6299a5292..29ce28d41e 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -210,11 +210,37 @@ EDA_Rect TRACK::GetBoundingBox() const // end of track is round, this is its radius, rounded up int radius = ( m_Width+1 )/2; - int ymax = MAX( m_Start.y, m_End.y ); - int xmax = MAX( m_Start.x, m_End.x ); + int ymax; + int xmax; - int ymin = MIN( m_Start.y, m_End.y ); - int xmin = MIN( m_Start.x, m_End.x ); + int ymin; + int xmin; + + if( Type() == TYPEVIA ) + { + // because vias are sometimes drawn larger than their m_Width would + // provide, erasing them using a dirty rect must also compensate for + // possibility (that the via is larger than its m_Width would provide). + // because it is cheap to return a larger BoundingBox, do it so that + // the via gets erased properly. Do not divide width by 2 for this reason. + radius = m_Width; + + ymax = m_Start.y; + xmax = m_Start.x; + + ymin = m_Start.y; + xmin = m_Start.x; + } + else + { + radius = ( m_Width+1 )/2; + + ymax = MAX( m_Start.y, m_End.y ); + xmax = MAX( m_Start.x, m_End.x ); + + ymin = MIN( m_Start.y, m_End.y ); + xmin = MIN( m_Start.x, m_End.x ); + } ymax += radius; xmax += radius; @@ -890,39 +916,6 @@ void TRACK::Display_Infos( WinEDA_DrawFrame* frame ) */ bool TRACK::HitTest( const wxPoint& ref_pos ) { -#if 0 - int l_piste; /* demi-largeur de la piste */ - int dx, dy, spot_cX, spot_cY; - int ux0, uy0; - - /* calcul des coordonnees du segment teste */ - l_piste = m_Width >> 1; /* l_piste = demi largeur piste */ - - ux0 = m_Start.x; - uy0 = m_Start.y; /* coord de depart */ - - dx = m_End.x; - dy = m_End.y; /* coord d'arrivee */ - - /* recalcul des coordonnees avec ux0, uy0 = origine des coordonnees */ - dx -= ux0; - dy -= uy0; - - spot_cX = ref_pos.x - ux0; - spot_cY = ref_pos.y - uy0; - - if( Type() == TYPEVIA ) /* VIA rencontree */ - { - return (double) spot_cX * spot_cX + (double) spot_cY * spot_cY <= - (double) l_piste * l_piste; - } - else - { - if( DistanceTest( l_piste, dx, dy, spot_cX, spot_cY ) ) - return true; - } -#else - int radius = m_Width >> 1; // (dx, dy) is a vector from m_Start to m_End (an origin of m_Start) @@ -944,8 +937,6 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) return true; } -#endif - return false; } diff --git a/pcbnew/clean.cpp b/pcbnew/clean.cpp index 775e53a1ac..11347b1c84 100644 --- a/pcbnew/clean.cpp +++ b/pcbnew/clean.cpp @@ -53,7 +53,7 @@ void WinEDA_PcbFrame::Clean_Pcb( wxDC* DC ) { s_ConnectToPads = false; WinEDA_CleaningOptionsFrame* frame = new WinEDA_CleaningOptionsFrame( this, DC ); - frame->ShowModal(); + frame->ShowModal(); frame->Destroy(); DrawPanel->Refresh( true ); } @@ -74,7 +74,7 @@ void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC ) { frame->MsgPanel->EraseMsgBox(); frame->m_Pcb->GetNumSegmTrack(); // update the count - + /* Rebuild the pad infos (pad list and netcodes) to ensure an up to date info */ frame->m_Pcb->m_Status_Pcb = 0; frame->build_liste_pads(); @@ -88,7 +88,7 @@ void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC ) { if( track->Shape() != VIA_THROUGH ) continue; - + // Search and delete others vias at same location TRACK* alt_track = track->Next(); for( ; alt_track != NULL; alt_track = next_track ) @@ -96,10 +96,10 @@ void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC ) next_track = alt_track->Next(); if( alt_track->m_Shape != VIA_THROUGH ) continue; - + if( alt_track->m_Start != track->m_Start ) continue; - + /* delete via */ alt_track->UnLink(); delete alt_track; @@ -112,7 +112,7 @@ void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC ) next_track = track->Next(); if( track->m_Shape != VIA_THROUGH ) continue; - + D_PAD* pad = Fast_Locate_Pad_Connecte( frame->m_Pcb, track->m_Start, ALL_CU_LAYERS ); if( pad && (pad->m_Masque_Layer & EXTERNAL_LAYERS) == EXTERNAL_LAYERS ) // redundant Via { @@ -124,18 +124,18 @@ void Clean_Pcb_Items( WinEDA_PcbFrame* frame, wxDC* DC ) } #ifdef CONN2PAD_ENBL - /* Create missing segments when a track end covers a pad or a via, - but is not on the pad or the via center */ + /* Create missing segments when a track end covers a pad or a via, + but is not on the pad or the via center */ if( s_ConnectToPads ) { - /* Create missing segments when a track end covers a pad, but is not on the pad center */ + /* Create missing segments when a track end covers a pad, but is not on the pad center */ if( s_ConnectToPads ) ConnectDanglingEndToPad( frame, DC ); // creation of points of connections at the intersection of tracks // Gen_Raccord_Track(frame, DC); - /* Create missing segments when a track end covers a via, but is not on the via center */ + /* Create missing segments when a track end covers a via, but is not on the via center */ if( s_ConnectToPads ) ConnectDanglingEndToVia( frame->m_Pcb ); } @@ -169,7 +169,7 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) TRACK* other; TRACK* startNetcode; TRACK* next; - + int nbpoints_supprimes = 0; int masklayer, oldnetcode; int type_end, flag_erase; @@ -186,13 +186,13 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) { frame->m_Pcb->m_NbSegmTrack++; next = segment->Next(); - + if( segment->Type() == TYPEVIA ) { if( segment->m_Start != segment->m_End ) { segment->m_End = segment->m_Start; - + ii++; msg.Printf( wxT( "%d " ), ii ); Affiche_1_Parametre( frame, POS_AFF_PASSE, _( "ViaDef" ), msg, LIGHTRED ); @@ -202,15 +202,15 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) } // removal of unconnected tracks - percent = 0; + percent = 0; oldpercent = -1; - oldnetcode = 0; - + oldnetcode = 0; + segment = startNetcode = frame->m_Pcb->m_Track; for( ii = 0; segment; segment = next, ii++ ) { next = segment->Next(); - + // display activity percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack; if( percent != oldpercent ) @@ -220,7 +220,7 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) msg.Printf( wxT( "%d " ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_MAX, wxT( "Max" ), msg, GREEN ); - + msg.Printf( wxT( "%d " ), ii ); Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN ); } @@ -230,11 +230,11 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) if( segment->GetNet() != oldnetcode ) { - startNetcode = segment; + startNetcode = segment; oldnetcode = segment->GetNet(); } - flag_erase = 0; + flag_erase = 0; type_end = 0; /* Is a pad found on a track end ? */ @@ -242,7 +242,7 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) masklayer = segment->ReturnMaskLayer(); D_PAD* pad; - + pad = Fast_Locate_Pad_Connecte( frame->m_Pcb, segment->m_Start, masklayer ); if( pad != NULL ) { @@ -268,19 +268,19 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) else // segment or via connected to this end { segment->start = other; - - if( other->Type() == TYPEVIA ) + + if( other->Type() == TYPEVIA ) { // search for another segment following the via - + segment->SetState( BUSY, ON ); - + TRACK* via = other; other = Locate_Piste_Connectee( via, frame->m_Pcb->m_Track, NULL, START ); if( other == NULL ) flag_erase |= 2; - + segment->SetState( BUSY, OFF ); } } @@ -293,22 +293,22 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) NULL, END ); if( other == NULL ) flag_erase |= 0x10; - + else // segment or via connected to this end { segment->end = other; if( other->Type() == TYPEVIA ) { // search for another segment following the via - + segment->SetState( BUSY, ON ); - + TRACK* via = other; other = Locate_Piste_Connectee( via, frame->m_Pcb->m_Track, NULL, END ); if( other == NULL ) flag_erase |= 0x20; - + segment->SetState( BUSY, OFF ); } } @@ -317,10 +317,10 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) if( flag_erase ) { oldpercent = -1; // force dispay activity - - nbpoints_supprimes++; + + nbpoints_supprimes++; ii--; - + msg.Printf( wxT( "%d " ), nbpoints_supprimes ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "NoConn." ), msg, LIGHTRED ); @@ -336,7 +336,7 @@ static void DeleteUnconnectedTracks( WinEDA_PcbFrame* frame, wxDC* DC ) // remove segment from screen and board segment->Draw( frame->DrawPanel, DC, GR_XOR ); segment->DeleteStructure(); - + if( next == NULL ) break; } @@ -362,15 +362,15 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) /**********************************************/ a_color = GREEN; - nbpoints_supprimes = 0; - percent = 0; + nbpoints_supprimes = 0; + percent = 0; oldpercent = -1; - + frame->MsgPanel->EraseMsgBox(); frame->Affiche_Message( _( "Clean Null Segments" ) ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "NullSeg" ), wxT( "0" ), a_color ); - + for( segment = frame->m_Pcb->m_Track; segment; segment = segment->Next() ) { if( !segment->IsNull() ) @@ -390,10 +390,10 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) /**************************************/ Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "Ident" ), wxT( "0" ), a_color ); - + percent = 0; oldpercent = -1; - + for( segment = frame->m_Pcb->m_Track, ii = 0; segment; segment = segment->Next(), ii++ ) { /* Display activity */ @@ -405,7 +405,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_MAX, wxT( "Max" ), msg, GREEN ); - + msg.Printf( wxT( "%d" ), ii ); Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN ); @@ -419,10 +419,10 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) if( segment->Type() != other->Type() ) continue; - + if( segment->GetLayer() != other->GetLayer() ) continue; - + if( segment->GetNet() != other->GetNet() ) break; @@ -457,7 +457,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) /*******************************/ nbpoints_supprimes = 0; - percent = 0; + percent = 0; oldpercent = -1; frame->Affiche_Message( _( "Merging Segments:" ) ); @@ -472,17 +472,17 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) TRACK* segDelete; next = segment->Next(); - + ii++; percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack; if( percent != oldpercent ) { frame->DisplayActivity( percent, _( "Merge: " ) ); oldpercent = percent; - + msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_MAX, wxT( "Max" ), msg, GREEN ); - + msg.Printf( wxT( "%d" ), ii ); Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN ); @@ -518,7 +518,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) if( other == NULL ) flag = 1; /* OK */ - + break; } break; @@ -542,7 +542,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) { if( segment->m_Width != segEnd->m_Width ) break; - + if( segEnd->Type() != TYPETRACK ) break; @@ -551,10 +551,10 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) other = Locate_Piste_Connectee( segment, frame->m_Pcb->m_Track, NULL, END ); segEnd->SetState( BUSY, OFF ); - + if( other == NULL ) flag |= 2; /* Ok */ - + break; } else @@ -566,7 +566,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) segDelete = AlignSegment( frame->m_Pcb, segment, segEnd, END ); if( segDelete ) { - nbpoints_supprimes++; + nbpoints_supprimes++; no_inc = 1; segDelete->DeleteStructure(); } @@ -576,7 +576,7 @@ static int clean_segments( WinEDA_PcbFrame* frame, wxDC* DC ) { msg.Printf( wxT( "%d " ), nbpoints_supprimes ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxEmptyString, msg, a_color ); - + next = segment->Next(); } } @@ -593,7 +593,7 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre * and see if the common point is not on a pad (i.e. if this common point can be removed). * the ending point of pt_ref is the start point (extremite == START) * or the end point (extremite == FIN) - * if the common end can be deleted, this function + * if the common end can be deleted, this function * change the common point coordinate of the pt_ref segm * (and therefore connect the 2 other ending points) * and return pt_segm (which can be deleted). @@ -602,10 +602,10 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre { int flag = 0; - int refdx = pt_ref->m_End.x - pt_ref->m_Start.x; + int refdx = pt_ref->m_End.x - pt_ref->m_Start.x; int refdy = pt_ref->m_End.y - pt_ref->m_Start.y; - - int segmdx = pt_segm->m_End.x - pt_segm->m_Start.x; + + int segmdx = pt_segm->m_End.x - pt_segm->m_Start.x; int segmdy = pt_segm->m_End.y - pt_segm->m_Start.y; // test for vertical alignment (easy to handle) @@ -616,7 +616,7 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre else flag = 1; } - + // test for horizontal alignment (easy to handle) if( refdy == 0 ) { @@ -637,10 +637,10 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre } /* Here we have 2 aligned segments: - We must change the pt_ref common point only if not on a pad - (this function) is called when thre is only 2 connected segments, - and if this point is not on a pad, it can be removed and the 2 segments will be merged - */ + We must change the pt_ref common point only if not on a pad + (this function) is called when thre is only 2 connected segments, + and if this point is not on a pad, it can be removed and the 2 segments will be merged + */ if( extremite == START ) { /* We do not have a pad */ @@ -648,28 +648,28 @@ static TRACK* AlignSegment( BOARD* Pcb, TRACK* pt_ref, TRACK* pt_segm, int extre g_TabOneLayerMask[pt_ref->GetLayer()] ) ) return NULL; - /* change the common point coordinate of pt_segm tu use the other point - of pt_segm (pt_segm will be removed later) */ + /* change the common point coordinate of pt_segm tu use the other point + of pt_segm (pt_segm will be removed later) */ if( pt_ref->m_Start == pt_segm->m_Start ) { - pt_ref->m_Start = pt_segm->m_End; + pt_ref->m_Start = pt_segm->m_End; return pt_segm; } else { - pt_ref->m_Start = pt_segm->m_Start; + pt_ref->m_Start = pt_segm->m_Start; return pt_segm; } } else /* extremite == END */ { /* We do not have a pad */ - if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_End, + if( Fast_Locate_Pad_Connecte( Pcb, pt_ref->m_End, g_TabOneLayerMask[pt_ref->GetLayer()] ) ) return NULL; - /* change the common point coordinate of pt_segm tu use the other point - of pt_segm (pt_segm will be removed later) */ + /* change the common point coordinate of pt_segm tu use the other point + of pt_segm (pt_segm will be removed later) */ if( pt_ref->m_End == pt_segm->m_Start ) { pt_ref->m_End = pt_segm->m_End; @@ -691,7 +691,7 @@ int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche ) /** * Function Netliste_Controle_piste - * finds all track segments which are mis-connected (to more than one net). + * finds all track segments which are mis-connected (to more than one net). * When such a bad segment is found, mark it as needing to be removed (supression). */ { @@ -702,11 +702,11 @@ int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche ) int nbpoints_modifies = 0; int flag = 0; wxString msg; - int percent = 0; + int percent = 0; int oldpercent = -1; a_color = RED; - + frame->Affiche_Message( _( "DRC Control:" ) ); frame->DrawPanel->m_AbortRequest = FALSE; @@ -724,10 +724,10 @@ int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche ) { frame->DisplayActivity( percent, wxT( "Drc: " ) ); oldpercent = percent; - + msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_MAX, wxT( "Max" ), msg, GREEN ); - + msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN ); @@ -751,7 +751,7 @@ int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche ) if( other ) net_code_s = other->GetNet(); } - + if( net_code_s < 0 ) continue; // the "start" of segment is not connected @@ -783,17 +783,17 @@ int Netliste_Controle_piste( WinEDA_PcbFrame* frame, wxDC* DC, int affiche ) for( segment = frame->m_Pcb->m_Track; segment; segment = next ) { next = (TRACK*) segment->Next(); - + if( segment->GetState( FLAG0 ) ) //* if segment is marked as needing to be removed { segment->SetState( FLAG0, OFF ); - - flag = 1; + + flag = 1; oldpercent = -1; frame->m_Pcb->m_Status_Pcb = 0; - - frame->Supprime_Une_Piste( DC, segment ); - + + frame->Remove_One_Track( DC, segment ); + next = frame->m_Pcb->m_Track; /* NextS a peut etre ete efface */ if( affiche ) { @@ -818,7 +818,7 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC ) * Function Gen_Raccord_Track * tests the ends of segments. If and end is on a segment of other track, but not * on other's end, the other segment is cut into 2, the point of cut being the end of - * segment first being operated on. This is done so that the subsequent tests + * segment first being operated on. This is done so that the subsequent tests * of connection, which do not test segment overlaps, will see this continuity. */ { @@ -845,10 +845,10 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC ) { frame->DisplayActivity( percent, wxT( "Tracks: " ) ); oldpercent = percent; - + msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_MAX, wxT( "Max" ), msg, GREEN ); - + msg.Printf( wxT( "%d" ), ii ); Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, wxT( "Segm" ), msg, CYAN ); } @@ -862,47 +862,47 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC ) for( other = frame->m_Pcb->m_Track; other; other = other->Next() ) { TRACK* newTrack; - + other = Locate_Pistes( other, segment->m_Start, masquelayer ); if( other == NULL ) break; - + if( other == segment ) continue; - + if( other->Type() == TYPEVIA ) continue; - + if( segment->m_Start == other->m_Start ) continue; - + if( segment->m_Start == other->m_End ) continue; // Test if the "end" of this segment is already connected to other if( segment->m_End == other->m_Start ) continue; - + if( segment->m_End == other->m_End ) continue; other->Draw( frame->DrawPanel, DC, GR_XOR ); - + nn++; msg.Printf( wxT( "%d" ), nn ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "New <" ), msg, YELLOW ); frame->m_Pcb->m_NbSegmTrack++; - - // create a new segment and insert it next to "other", then shorten other. + + // create a new segment and insert it next to "other", then shorten other. newTrack = other->Copy(); newTrack->Insert( frame->m_Pcb, other ); - + other->m_End = segment->m_Start; newTrack->m_Start = segment->m_Start; - + Trace_Une_Piste( frame->DrawPanel, DC, other, 2, GR_OR ); - + // skip forward one, skipping the newTrack other = newTrack; } @@ -911,46 +911,46 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC ) for( other = frame->m_Pcb->m_Track; other; other = other->Next() ) { TRACK* newTrack; - + other = Locate_Pistes( other, segment->m_End, masquelayer ); if( other == NULL ) break; - + if( other == segment ) continue; - + if( other->Type() == TYPEVIA ) continue; if( segment->m_End == other->m_Start ) continue; - + if( segment->m_End == other->m_End ) continue; if( segment->m_Start == other->m_Start ) continue; - + if( segment->m_Start == other->m_End ) continue; other->Draw( frame->DrawPanel, DC, GR_XOR ); - nn++; + nn++; msg.Printf( wxT( "%d" ), nn ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxT( "New >" ), msg, YELLOW ); - + frame->m_Pcb->m_NbSegmTrack++; - - // create a new segment and insert it next to "other", then shorten other. + + // create a new segment and insert it next to "other", then shorten other. newTrack = other->Copy(); newTrack->Insert( frame->m_Pcb, other ); - other->m_End = segment->m_End; - newTrack->m_Start = segment->m_End; - + other->m_End = segment->m_End; + newTrack->m_Start = segment->m_End; + Trace_Une_Piste( frame->DrawPanel, DC, other, 2, GR_OR ); - + // skip forward one, skipping the newTrack other = newTrack; } @@ -969,15 +969,15 @@ static void Gen_Raccord_Track( WinEDA_PcbFrame* frame, wxDC* DC ) * Note that this is not a rigorous electrical check, but is better than * testing for the track endpoint equaling the via center. When such a via * is found, then add a small track to bridge from the overlapping track to - * the via and change the via's netcode so that subsequent continuity checks - * can be done with the faster equality algorithm. + * the via and change the via's netcode so that subsequent continuity checks + * can be done with the faster equality algorithm. */ static void ConnectDanglingEndToVia( BOARD* pcb ) { for( TRACK* track = pcb->m_Track; track; track = track->Next() ) { SEGVIA* via; - + if( track->Type()!=TYPEVIA || (via = (SEGVIA*)track)->GetNet()!=0 ) continue; @@ -988,47 +988,47 @@ static void ConnectDanglingEndToVia( BOARD* pcb ) if( !via->IsOnLayer( other->GetLayer() ) ) continue; - + // 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->GetPosition() && via->HitTest( other->m_Start ) && !other->start ) { TRACK* newTrack = other->Copy(); newTrack->Insert( pcb, other ); - + newTrack->m_End = via->GetPosition(); - + newTrack->start = other; newTrack->end = via; other->start = newTrack; - + via->SetNet( other->GetNet() ); - + if( !via->start ) via->start = other; - + if( !via->end ) via->end = other; } - + // 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->GetPosition() && 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->GetPosition(); - + newTrack->start = via; newTrack->end = other; other->end = newTrack; - + via->SetNet( other->GetNet() ); - + if( !via->start ) via->start = other; - + if( !via->end ) via->end = other; } @@ -1044,18 +1044,18 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) /** * Function ConnectDanglingEndToPad * possibly adds a segment to the end of any and all tracks if their end is not exactly - * connected into the center of the pad. This allows faster control of + * connected into the center of the pad. This allows faster control of * connections. */ { TRACK* segment; int nb_new_piste = 0; wxString msg; - int percent = 0; + int percent = 0; int oldpercent = -1; a_color = GREEN; - + frame->DrawPanel->m_AbortRequest = FALSE; Affiche_1_Parametre( frame, POS_AFF_VAR, _( "Centre" ), _( "0 " ), a_color ); @@ -1064,17 +1064,17 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) for( segment = frame->m_Pcb->m_Track; segment; segment = segment->Next() ) { D_PAD* pad; - + ii++; percent = (100 * ii) / frame->m_Pcb->m_NbSegmTrack; if( percent != oldpercent ) { frame->DisplayActivity( percent, _( "Pads: " ) ); oldpercent = percent; - + msg.Printf( wxT( "%d" ), frame->m_Pcb->m_NbSegmTrack ); Affiche_1_Parametre( frame, POS_AFF_MAX, _( "Max" ), msg, GREEN ); - + msg.Printf( wxT( "%d" ), ii ); Affiche_1_Parametre( frame, POS_AFF_NUMSEGM, _( "Segm" ), msg, CYAN ); @@ -1084,7 +1084,7 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) pad = Locate_Pad_Connecte( frame->m_Pcb, segment, START ); if( pad ) - { + { // test if the track is not precisely starting on the found pad if( segment->m_Start != pad->m_Pos ) { @@ -1093,14 +1093,14 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) { TRACK* newTrack = segment->Copy(); newTrack->Insert( frame->m_Pcb, segment ); - + newTrack->m_End = pad->m_Pos; - + newTrack->start = segment; newTrack->end = pad; - + nb_new_piste++; - + newTrack->Draw( frame->DrawPanel, DC, GR_OR ); Affiche_1_Parametre( frame, POS_AFF_VAR, wxEmptyString, msg, a_color ); } @@ -1109,7 +1109,7 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) pad = Locate_Pad_Connecte( frame->m_Pcb, segment, END ); if( pad ) - { + { // test if the track is not precisely ending on the found pad if( segment->m_End != pad->m_Pos ) { @@ -1118,12 +1118,12 @@ void ConnectDanglingEndToPad( WinEDA_PcbFrame* frame, wxDC* DC ) { TRACK* newTrack = segment->Copy(); newTrack->Insert( frame->m_Pcb, segment ); - + newTrack->m_Start = pad->m_Pos; - + newTrack->start = pad; newTrack->end = segment; - + nb_new_piste++; msg.Printf( wxT( "e %d" ), nb_new_piste ); diff --git a/pcbnew/deltrack.cpp b/pcbnew/deltrack.cpp index 1b07339724..61ccc0bd79 100644 --- a/pcbnew/deltrack.cpp +++ b/pcbnew/deltrack.cpp @@ -119,29 +119,8 @@ TRACK* WinEDA_PcbFrame::Delete_Segment( wxDC* DC, TRACK* Track ) current_net_code = Track->GetNet(); -#if 0 - - Track->Draw( DrawPanel, DC, GR_XOR ); - -#else - // redraw the area where the track was - // this rectangle is correct - EDA_Rect dirty = Track->GetBoundingBox(); - - // Convert the rect coordinates and size in pixels (make a draw clip box): - DrawPanel->ConvertPcbUnitsToPixelsUnits( &dirty ); - - /* now that TRACK::GetBoundingBox() returns a [,) type of rectangle, and - rounds up the track radius, let's see if this is really needed. - // Ensure the last line and column are in the dirty rectangle after truncatures - dirty.m_Size.x += 1; dirty.m_Size.y += 1; - */ - - // pass wxRect() via EDA_Rect::operator wxRect() overload - DrawPanel->RefreshRect( dirty, TRUE ); - -#endif + DrawPanel->PostDirtyRect( Track->GetBoundingBox() ); SaveItemEfface( Track, 1 ); GetScreen()->SetModify(); @@ -159,7 +138,7 @@ void WinEDA_PcbFrame::Delete_Track( wxDC* DC, TRACK* Track ) if( Track != NULL ) { int current_net_code = Track->GetNet(); - Supprime_Une_Piste( DC, Track ); + Remove_One_Track( DC, Track ); GetScreen()->SetModify(); test_1_net_connexion( DC, current_net_code ); } @@ -205,7 +184,7 @@ void WinEDA_PcbFrame::Delete_net( wxDC* DC, TRACK* Track ) /********************************************************************/ -void WinEDA_PcbFrame::Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm ) +void WinEDA_PcbFrame::Remove_One_Track( wxDC* DC, TRACK* pt_segm ) /********************************************************************/ /* Routine de suppression de 1 piste: @@ -213,26 +192,25 @@ void WinEDA_PcbFrame::Supprime_Une_Piste( wxDC* DC, TRACK* pt_segm ) * jusqu'a un pad ou un point de jonction de plus de 2 segments */ { - TRACK* pt_track, * Struct; - int ii, nb_segm; + TRACK* trackList; + int nb_segm; if( pt_segm == NULL ) return; - pt_track = Marque_Une_Piste( this, DC, pt_segm, - &nb_segm, GR_OR | GR_SURBRILL ); + trackList = Marque_Une_Piste( this, DC, pt_segm, &nb_segm, 0 ); if( nb_segm ) /* Il y a nb_segm segments de piste a effacer */ { - Trace_Une_Piste( DrawPanel, DC, pt_track, nb_segm, GR_XOR | GR_SURBRILL ); - - /* Effacement flag BUSY */ - Struct = pt_track;; - for( ii = 0; iiPnext ) + TRACK* t; + int ii; + for( t = trackList, ii=0; iiNext() ) { - Struct->SetState( BUSY, OFF ); + t->SetState( BUSY, OFF ); + + DrawPanel->PostDirtyRect( t->GetBoundingBox() ); } - SaveItemEfface( pt_track, nb_segm ); + SaveItemEfface( trackList, nb_segm ); } } diff --git a/pcbnew/track.cpp b/pcbnew/track.cpp index 468f1a147b..bc3f0e06c5 100644 --- a/pcbnew/track.cpp +++ b/pcbnew/track.cpp @@ -110,17 +110,23 @@ TRACK* Marque_Une_Piste( WinEDA_BasePcbFrame* frame, wxDC* DC, int layer; if( Segm->RefTrack->Type() != TYPEVIA ) continue; + if( Segm->RefTrack == pt_segm ) continue; + Segm->RefTrack->SetState( BUSY, ON ); + masque_layer = Segm->RefTrack->ReturnMaskLayer(); + Track = Fast_Locate_Piste( frame->m_Pcb->m_Track, NULL, Segm->RefTrack->m_Start, masque_layer ); if( Track == NULL ) continue; + /* Test des connexions: si via utile: suppression marquage */ layer = Track->GetLayer(); + while( ( Track = Fast_Locate_Piste( (TRACK*) Track->Pnext, NULL, Segm->RefTrack->m_Start, masque_layer ) ) != NULL ) @@ -136,7 +142,8 @@ TRACK* Marque_Une_Piste( WinEDA_BasePcbFrame* frame, wxDC* DC, /* liberation memoire */ for( Segm = ListSegm; Segm != NULL; Segm = NextSegm ) { - NextSegm = Segm->Pnext; delete Segm; + NextSegm = Segm->Pnext; + delete Segm; } ListSegm = NULL; @@ -144,10 +151,12 @@ TRACK* Marque_Une_Piste( WinEDA_BasePcbFrame* frame, wxDC* DC, /* Reclassement des segments marques en une chaine */ FirstTrack = frame->m_Pcb->m_Track; NbSegmBusy = 0; for( ; FirstTrack != NULL; FirstTrack = (TRACK*) FirstTrack->Pnext ) - { /* recherche du debut de la liste des segments marques a BUSY */ + { + /* recherche du debut de la liste des segments marques a BUSY */ if( FirstTrack->GetState( BUSY ) ) { - NbSegmBusy = 1; break; + NbSegmBusy = 1; + break; } } @@ -182,7 +191,7 @@ static void Marque_Chaine_segments( BOARD* Pcb, wxPoint ref_pos, int masque_laye * routine utilisee par Supprime_1_Piste() * Positionne le bit BUSY dans la chaine de segments commencant * au point ox, oy sur la couche layer - * + * * Les vias sont mises en liste des segments traites mais ne sont pas * marquees. */ diff --git a/share/drawpanel.cpp b/share/drawpanel.cpp index 8e110cba2c..a8dc88f09c 100644 --- a/share/drawpanel.cpp +++ b/share/drawpanel.cpp @@ -266,6 +266,21 @@ bool WinEDA_DrawPanel::IsPointOnDisplay( wxPoint ref_pos ) } +void WinEDA_DrawPanel::PostDirtyRect( EDA_Rect aRect ) +{ + // Convert the rect coordinates and size to pixels (make a draw clip box): + ConvertPcbUnitsToPixelsUnits( &aRect ); + + // Ensure the last line and column are in the dirty rectangle after truncations. + // The pcb units have finer granularity than the pixels, so this can happen. + aRect.m_Size.x += 1; + aRect.m_Size.y += 1; + + // pass wxRect() via EDA_Rect::operator wxRect() overload + RefreshRect( aRect, TRUE ); +} + + /************************************************************************/ void WinEDA_DrawPanel::ConvertPcbUnitsToPixelsUnits( EDA_Rect* aRect ) /************************************************************************/