From 4b04d6c287e8f2b2c11e50a1eb7614e177609910 Mon Sep 17 00:00:00 2001 From: dickelbeck Date: Fri, 29 Feb 2008 20:35:11 +0000 Subject: [PATCH] fix for magnetic tracks for parallel case, cleanup of original patches --- change_log.txt | 43 +++++++------- eeschema/controle.cpp | 61 ++++++++++---------- pcbnew/controle.cpp | 128 +++++++++++++++++++++++++++++------------- pcbnew/editrack.cpp | 57 +++++++++---------- pcbnew/protos.h | 2 +- 5 files changed, 172 insertions(+), 119 deletions(-) diff --git a/change_log.txt b/change_log.txt index ca4890a0a6..bac97a5ee5 100644 --- a/change_log.txt +++ b/change_log.txt @@ -5,23 +5,28 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with email address. +2008-Feb-29 UPDATE Dick Hollenbeck +================================================================================ ++pcbnew + controle.cpp: fixed the magnetic track if tracks are parallel. + + 2008-Feb-29 UPDATE Jean-Pierre Charras ================================================================================ +eeschema - Renaming the sheet filename now works in simple and complex hierarchies. - Use carefully because this can change the whole schematic structure. - Gen Bom List now works in unicode build version - (label list generation crashed eeschema in unicode build version) - + Renaming the sheet filename now works in simple and complex hierarchies. + Use carefully because this can change the whole schematic structure. + Gen Bom List now works in unicode build version + (label list generation crashed eeschema in unicode build version) +all - Display filename and full sheet name ("sheet path") in sheet reference - the full sheet name has no meanning in pcbnew. + Display filename and full sheet name ("sheet path") in sheet reference + the full sheet name has no meanning in pcbnew. 2008-Feb-28 UPDATE Jean-Pierre Charras ================================================================================ +eeschema - Fixed: problem which could crash eeschema when a sub schematic file in a hierarchy was not found. + Fixed: problem which could crash eeschema when a sub schematic file in a hierarchy was not found. 2008-Feb-27 UPDATE Wayne Stambaugh @@ -40,18 +45,16 @@ email address. 2008-Feb-26 UPDATE Jean-Pierre Charras ================================================================================ +eeschema - changed in class DrawSheetStruct m_s member name to m_AssociatedScreen - some others minor problems solved. - some files "uncrustified" - Major problem in undo/redo when a sheet is deleted not yet solved - Only for a complex hierarchy, could lost data. - When a sheet is deleted by block delete. it is put in undo list. - It is really deleted after 10 changes (when the undo list is full). - At this time, the associated data is also deleted. - If an other (not deleted) sheet shares the same data, this data is lost. - Need work to solve this problem and keep the undo/redo feature. - - + changed in class DrawSheetStruct m_s member name to m_AssociatedScreen + some others minor problems solved. + some files "uncrustified" + Major problem in undo/redo when a sheet is deleted not yet solved + Only for a complex hierarchy, could lost data. + When a sheet is deleted by block delete. it is put in undo list. + It is really deleted after 10 changes (when the undo list is full). + At this time, the associated data is also deleted. + If an other (not deleted) sheet shares the same data, this data is lost. + Need work to solve this problem and keep the undo/redo feature. 2008-Feb-25 UPDATE Wayne Stambaugh diff --git a/eeschema/controle.cpp b/eeschema/controle.cpp index 45ede70dc8..a036d977df 100644 --- a/eeschema/controle.cpp +++ b/eeschema/controle.cpp @@ -55,22 +55,22 @@ SchematicGeneralLocateAndDisplay( bool IncludePin ) /* Cross probing to pcbnew if a pin or a component is found */ switch( DrawStruct->Type() ) { - case DRAW_PART_TEXT_STRUCT_TYPE: + case DRAW_PART_TEXT_STRUCT_TYPE: case COMPONENT_FIELD_DRAW_TYPE: LibItem = (EDA_SchComponentStruct*) DrawStruct->m_Parent; - SendMessageToPCBNEW( DrawStruct,LibItem ); + SendMessageToPCBNEW( DrawStruct,LibItem ); break; case DRAW_LIB_ITEM_STRUCT_TYPE: - Pin = LocateAnyPin( GetScreen()->EEDrawList, GetScreen()->m_Curseur, &LibItem ); + Pin = LocateAnyPin( GetScreen()->EEDrawList, GetScreen()->m_Curseur, &LibItem ); if( Pin ) break; // Priority is probing a pin first LibItem = (EDA_SchComponentStruct*) DrawStruct; - SendMessageToPCBNEW( DrawStruct, LibItem ); + SendMessageToPCBNEW( DrawStruct, LibItem ); break; default: - Pin = LocateAnyPin( GetScreen()->EEDrawList, GetScreen()->m_Curseur, &LibItem ); + Pin = LocateAnyPin( GetScreen()->EEDrawList, GetScreen()->m_Curseur, &LibItem ); break; case COMPONENT_PIN_DRAW_TYPE: @@ -89,7 +89,7 @@ SchematicGeneralLocateAndDisplay( bool IncludePin ) CYAN ); // Cross probing:2 - pin found, and send a locate pin command to pcbnew (hightlight net) - SendMessageToPCBNEW( Pin, LibItem ); + SendMessageToPCBNEW( Pin, LibItem ); } return DrawStruct; } @@ -156,7 +156,7 @@ SchematicGeneralLocateAndDisplay( const wxPoint& refpoint, bool IncludePin ) WIREITEM | BUSITEM | RACCORDITEM ); if( DrawStruct ) // Search for a pin { - Pin = LocateAnyPin( m_CurrentSheet->LastDrawList(), refpoint, &LibItem ); + Pin = LocateAnyPin( m_CurrentSheet->LastDrawList(), refpoint, &LibItem ); if( Pin ) { Pin->Display_Infos( this ); @@ -182,7 +182,7 @@ SchematicGeneralLocateAndDisplay( const wxPoint& refpoint, bool IncludePin ) } /* search for a pin */ - Pin = LocateAnyPin( m_CurrentSheet->LastDrawList(), refpoint, &LibItem ); + Pin = LocateAnyPin( m_CurrentSheet->LastDrawList(), refpoint, &LibItem ); if( Pin ) { Pin->Display_Infos( this ); @@ -230,16 +230,16 @@ void WinEDA_DrawFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels /***********************************************************************/ { wxSize delta; - SCH_SCREEN* screen = (SCH_SCREEN*)GetScreen(); - int zoom = screen->GetZoom(); + SCH_SCREEN* screen = (SCH_SCREEN*)GetScreen(); + int zoom = screen->GetZoom(); wxPoint curpos, oldpos; int hotkey = 0; - curpos = screen->m_MousePosition; - oldpos = screen->m_Curseur; + curpos = screen->m_MousePosition; + oldpos = screen->m_Curseur; - delta.x = screen->GetGrid().x / zoom; - delta.y = screen->GetGrid().y / zoom; + delta.x = screen->GetGrid().x / zoom; + delta.y = screen->GetGrid().y / zoom; if( delta.x <= 0 ) delta.x = 1; @@ -253,37 +253,37 @@ void WinEDA_DrawFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels case EDA_PANNING_UP_KEY: OnZoom( ID_ZOOM_PANNING_UP ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case EDA_PANNING_DOWN_KEY: OnZoom( ID_ZOOM_PANNING_DOWN ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case EDA_PANNING_LEFT_KEY: OnZoom( ID_ZOOM_PANNING_LEFT ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case EDA_PANNING_RIGHT_KEY: OnZoom( ID_ZOOM_PANNING_RIGHT ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case EDA_ZOOM_IN_FROM_MOUSE: OnZoom( ID_ZOOM_IN_KEY ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case EDA_ZOOM_OUT_FROM_MOUSE: OnZoom( ID_ZOOM_OUT_KEY ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case EDA_ZOOM_CENTER_FROM_MOUSE: OnZoom( ID_ZOOM_CENTER_KEY ); - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; break; case WXK_NUMPAD8: /* Deplacement curseur vers le haut */ @@ -294,6 +294,7 @@ void WinEDA_DrawFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels case WXK_NUMPAD2: /* Deplacement curseur vers le bas */ case WXK_DOWN: + D(printf("DOWN\n");) MousePositionInPixels.y += delta.y; DrawPanel->MouseTo( MousePositionInPixels ); break; @@ -316,22 +317,22 @@ void WinEDA_DrawFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels } /* Recalcul de la position du curseur schema */ - screen->m_Curseur = curpos; + screen->m_Curseur = curpos; /* Placement sur la grille generale */ - PutOnGrid( &(screen->m_Curseur) ); + PutOnGrid( &(screen->m_Curseur) ); - if( screen->IsRefreshReq() ) + if( screen->IsRefreshReq() ) { RedrawActiveWindow( DC, TRUE ); } - if( oldpos != screen->m_Curseur ) + if( oldpos != screen->m_Curseur ) { - curpos = screen->m_Curseur; + curpos = screen->m_Curseur; screen->m_Curseur = oldpos; DrawPanel->CursorOff( DC ); - GetScreen()->m_Curseur = curpos; + GetScreen()->m_Curseur = curpos; DrawPanel->CursorOn( DC ); if( DrawPanel->ManageCurseur ) @@ -342,9 +343,9 @@ void WinEDA_DrawFrame::GeneralControle( wxDC* DC, wxPoint MousePositionInPixels if( hotkey ) { - if( screen->GetCurItem() - && screen->GetCurItem()->m_Flags ) - OnHotKey( DC, hotkey, screen->GetCurItem() ); + if( screen->GetCurItem() + && screen->GetCurItem()->m_Flags ) + OnHotKey( DC, hotkey, screen->GetCurItem() ); else OnHotKey( DC, hotkey, NULL ); } diff --git a/pcbnew/controle.cpp b/pcbnew/controle.cpp index 04bb3d5a8a..710ae07c31 100644 --- a/pcbnew/controle.cpp +++ b/pcbnew/controle.cpp @@ -219,14 +219,20 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay( int aHotKeyCode ) } -/* - * "Join" finds the point where b0+x*(b1-b0) intersects with a0+y*(a1-a0). +/** + * Function Join + * finds the point where b0+x*(b1-b0) intersects with a0+y*(a1-a0). * If that point would be outside of a0-a1, the respective endpoint is used. * Join returns the point in "res" and "true" if a suitable point was found, * "false" if both lines are parallel. */ -static bool Join( wxPoint& res, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 ) +static bool Join( wxPoint* res, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 ) { + /* References: + http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ + http://www.gekkou.co.uk/blogs/monologues/2007/12/13/1197586800000.html + */ + int64_t denom; double t; @@ -234,16 +240,18 @@ static bool Join( wxPoint& res, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 ) b1 -= b0; b0 -= a0; - denom = (int64_t) b1.y*a1.x - (int64_t) b1.x*a1.y; - if (!denom) - return false; // parallel + denom = (int64_t) b1.y * a1.x - (int64_t) b1.x * a1.y; + if( !denom ) + { + return false; // parallel + } - t = ((int64_t) b1.y*b0.x - (int64_t) b1.x*b0.y)/(double) denom; + t = ((int64_t) b1.y * b0.x - (int64_t) b1.x * b0.y ) / (double) denom; t = min( max( t, 0.0 ), 1.0 ); - res.x = (int) round(a0.x+t*a1.x); - res.y = (int) round(a0.y+t*a1.y); + res->x = (int) round( a0.x + t * a1.x ); + res->y = (int) round( a0.y + t * a1.y ); return true; } @@ -253,7 +261,7 @@ static bool Join( wxPoint& res, wxPoint a0, wxPoint a1, wxPoint b0, wxPoint b1 ) * "Project" finds the projection of a grid point on a track. This is the point * from where we want to draw new orthogonal tracks when starting on a track. */ -bool Project( wxPoint& res, wxPoint on_grid, const TRACK* track ) +bool Project( wxPoint* res, wxPoint on_grid, const TRACK* track ) { wxPoint vec; double t; @@ -269,31 +277,40 @@ bool Project( wxPoint& res, wxPoint on_grid, const TRACK* track ) t /= (int64_t) vec.x*vec.x + (int64_t) vec.y*vec.y; t = min( max( t, 0.0 ), 1.0 ); - res.x = (int) round( track->m_Start.x + t*vec.x ); - res.y = (int) round( track->m_Start.y + t*vec.y ); + res->x = (int) round( track->m_Start.x + t*vec.x ); + res->y = (int) round( track->m_Start.y + t*vec.y ); return true; } +/** + * Function Magnetize + * tests to see if there are any magnetic items within near reach of the given + * "curpos". If yes, then curpos is adjusted appropriately according to that + * near magnetic item and true is returned. + * @param curpos The initial position, and what to adjust if a change is needed. + */ static bool Magnetize( BOARD* m_Pcb, WinEDA_PcbFrame* frame, - int m_ID_current_state, wxSize grid, wxPoint on_grid, wxPoint& curpos ) + int aCurrentTool, wxSize grid, wxPoint on_grid, wxPoint* curpos ) { - const D_PAD* pad; - const TRACK* curr = NULL; - const TRACK* via, * track; - int layer, layer_mask; + D_PAD* pad; + TRACK* curr = g_CurrentTrackSegment; + TRACK* via; + TRACK* track; + int layer, layer_mask; - bool sometimes = g_MagneticPadOption != capture_always && Drc_On; + bool doCheckNet = g_MagneticPadOption != capture_always && Drc_On; - curr = g_CurrentTrackSegment; if( frame->GetCurItem() != curr ) + { curr = NULL; + } switch( g_MagneticPadOption ) { case capture_cursor_in_track_tool: - if( m_ID_current_state != ID_TRACK_BUTT ) + if( aCurrentTool != ID_TRACK_BUTT ) return false; break; @@ -308,20 +325,22 @@ static bool Magnetize( BOARD* m_Pcb, WinEDA_PcbFrame* frame, pad = Locate_Any_Pad( m_Pcb, CURSEUR_OFF_GRILLE, TRUE ); if( pad ) { - if( curr && curr->GetNet() != pad->GetNet() && sometimes ) + if( doCheckNet && curr && curr->GetNet() != pad->GetNet() ) return false; - curpos = pad->m_Pos; + + *curpos = pad->m_Pos; return true; } layer = ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer; - via = Locate_Via_Area( m_Pcb, curpos, layer ); + via = Locate_Via_Area( m_Pcb, *curpos, layer ); if( via ) { - if( curr && curr->GetNet() != via->GetNet() && sometimes ) + if( doCheckNet && curr && curr->GetNet() != via->GetNet() ) return false; - curpos = via->m_Start; + + *curpos = via->m_Start; return true; } @@ -340,25 +359,57 @@ static bool Magnetize( BOARD* m_Pcb, WinEDA_PcbFrame* frame, * In two segment mode, ignore the final segment if it's inside a grid * square. */ - if( g_TwoSegmentTrackBuild && curr->Pback + if( g_TwoSegmentTrackBuild && curr->Back() && curr->m_Start.x - grid.x < curr->m_End.x && curr->m_Start.x + grid.x > curr->m_End.x && curr->m_Start.y - grid.y < curr->m_End.y && curr->m_Start.y + grid.y > curr->m_End.y ) + { curr = curr->Back(); + } - track = Locate_Pistes( m_Pcb->m_Track, layer_mask, CURSEUR_OFF_GRILLE ); - for( ; track; track = track->Next() ) + for( track = m_Pcb->m_Track; track; track = track->Next() ) { if( track->Type() != TYPETRACK ) continue; - if( curr->GetNet() != track->GetNet() && sometimes ) + if( doCheckNet && curr->GetNet() != track->GetNet() ) continue; - if( Join( curpos, track->m_Start, track->m_End, - curr->m_Start, curr->m_End ) ) + if( (g_DesignSettings.m_LayerColor[track->GetLayer()] & ITEM_NOT_SHOW) ) + continue; + + if( !track->IsOnLayer( layer ) ) + continue; + + // @todo, this should be a track overlap test, not a mouse on track test. + // The former would consider the new track's width. + if( !track->HitTest( *curpos ) ) + continue; + + if( Join( curpos, track->m_Start, track->m_End, curr->m_Start, curr->m_End ) ) + { return true; + } + + if( aCurrentTool == ID_TRACK_BUTT ) + { + // At this point we have a drawing mouse on a track, we are drawing + // a new track and that new track is parallel to the track the + // mouse is on. Find the nearest end point of the track under mouse + // to the mouse and return that. + double distStart = hypot( double( curpos->x - track->m_Start.x ), + double( curpos->y - track->m_Start.y )); + + double distEnd = hypot( double( curpos->x - track->m_End.x ), + double( curpos->y - track->m_End.y )); + + if( distStart < distEnd ) + *curpos = track->m_Start; + else + *curpos = track->m_End; + return true; + } } return false; @@ -505,20 +556,21 @@ void WinEDA_BasePcbFrame::GeneralControle( wxDC* DC, wxPoint Mouse ) PutOnGrid( &on_grid ); if( Magnetize(m_Pcb, (WinEDA_PcbFrame *) this, m_ID_current_state, - GetScreen()->GetGrid(), on_grid, curpos) ) + GetScreen()->GetGrid(), on_grid, &curpos) ) + { GetScreen()->m_Curseur = curpos; + } else { - /* - * If there's an intrusion and DRC is active, we pass the cursor - * "as is", and let ShowNewTrackWhenMovingCursor figure our what to - * do. - */ + // If there's no intrusion and DRC is active, we pass the cursor + // "as is", and let ShowNewTrackWhenMovingCursor figure out what to do. if( !Drc_On || !g_CurrentTrackSegment || g_CurrentTrackSegment != this->GetCurItem() - || !LocateIntrusion(m_Pcb->m_Track, g_CurrentTrackSegment->GetNet(), + || !LocateIntrusion( m_Pcb->m_Track, g_CurrentTrackSegment->GetNet(), g_CurrentTrackSegment->m_Width ) ) + { GetScreen()->m_Curseur = on_grid; + } } } diff --git a/pcbnew/editrack.cpp b/pcbnew/editrack.cpp index dfc5fe9f1f..11ef54904e 100644 --- a/pcbnew/editrack.cpp +++ b/pcbnew/editrack.cpp @@ -500,44 +500,41 @@ void WinEDA_PcbFrame::End_Route( TRACK* track, wxDC* DC ) TRACK* LocateIntrusion( TRACK* start, int net, int width ) { - int layer = ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer; - int layer_mask = g_TabOneLayerMask[layer]; - wxPoint ref = ActiveScreen->RefPos( 1 ); - TRACK* track, * found = NULL; + int layer = ( (PCB_SCREEN*) ActiveScreen )->m_Active_Layer; - for( track = start; track; track = track->Next() ) + wxPoint ref = ActiveScreen->RefPos( true ); + + TRACK* found = NULL; + + for( TRACK* track = start; track; track = track->Next() ) { - int dist; - wxPoint pos, vec; - int64_t tmp; + if( track->Type() == TYPETRACK ) // skip vias + { + if( track->GetState( BUSY | DELETED ) ) + continue; - /* Locate_Pistes */ - if( track->GetState( BUSY | DELETED ) ) - continue; + if( layer != track->GetLayer() ) + continue; - if( !(g_TabOneLayerMask[track->GetLayer()] & layer_mask) ) - continue; + if( track->GetNet() == net ) + continue; - if( track->GetNet() == net ) - continue; + /* TRACK::HitTest */ + int dist = width / 2 + track->m_Width / 2 + g_DesignSettings.m_TrackClearence; - if( track->Type() == TYPEVIA ) - continue; + wxPoint pos = ref - track->m_Start; + wxPoint vec = track->m_End - track->m_Start; - /* TRACK::HitTest */ - dist = width / 2 + track->m_Width / 2 + g_DesignSettings.m_TrackClearence; - pos = ref - track->m_Start; - vec = track->m_End - track->m_Start; + if( !DistanceTest( dist, vec.x, vec.y, pos.x, pos.y ) ) + continue; - if( !DistanceTest( dist, vec.x, vec.y, pos.x, pos.y ) ) - continue; + found = track; - found = track; - - /* prefer intrusions from the side, not the end */ - tmp = (int64_t) pos.x * vec.x + (int64_t) pos.y * vec.y; - if( tmp >= 0 && tmp <= (int64_t) vec.x * vec.x + (int64_t) vec.y * vec.y ) - break; + /* prefer intrusions from the side, not the end */ + int64_t tmp = (int64_t) pos.x * vec.x + (int64_t) pos.y * vec.y; + if( tmp >= 0 && tmp <= (int64_t) vec.x * vec.x + (int64_t) vec.y * vec.y ) + break; + } } return found; @@ -612,7 +609,7 @@ static void PushTrack( WinEDA_DrawPanel* panel ) n.x = (int) round( f * n.x ); n.y = (int) round( f * n.y ); - Project( track->m_End, cursor, other ); + Project( &track->m_End, cursor, other ); track->m_End += n; } diff --git a/pcbnew/protos.h b/pcbnew/protos.h index 19c5d8440b..cefaec5dfd 100644 --- a/pcbnew/protos.h +++ b/pcbnew/protos.h @@ -387,7 +387,7 @@ TRACK* CreateLockPoint( int* pX, int* pY, TRACK* ptsegm, TRACK* refsegm /* CONTROLE.CPP */ /****************/ void RemoteCommand( const char* cmdline ); -bool Project( wxPoint& res, wxPoint on_grid, const TRACK* track ); +bool Project( wxPoint* res, wxPoint on_grid, const TRACK* track ); /***************/