Commit 69ce4a2b authored by charras's avatar charras
Browse files

Pcbnew:solved: bug in autorouter.

parent c5725437
Loading
Loading
Loading
Loading
+109 −87
Original line number Diff line number Diff line
@@ -184,13 +184,14 @@ static struct
};

static long newmask[8] = { /* patterns to mask out in neighbor cells */
    0,                                   CORNER_NORTHWEST | CORNER_NORTHEAST, 0,
    0,                                   CORNER_NORTHWEST | CORNER_NORTHEAST,
    0,
    CORNER_NORTHWEST | CORNER_SOUTHWEST, CORNER_NORTHEAST | CORNER_SOUTHEAST,
    0,                                   CORNER_SOUTHWEST | CORNER_SOUTHEAST, 0
    0,                                   CORNER_SOUTHWEST | CORNER_SOUTHEAST,
    0
};



/********************************************************/
/* int WinEDA_PcbFrame::Solve(wxDC * DC, int two_sides) */
/********************************************************/
@@ -306,9 +307,11 @@ int WinEDA_PcbFrame::Solve( wxDC* DC, int two_sides )
}


/**************************/
/* int Route_1_Trace(xxx) */
/**************************/
/**********************************************************************************/
static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
                          int two_sides, int row_source, int col_source,
                          int row_target, int col_target, CHEVELU* pt_chevelu )
/**********************************************************************************/

/* Route une piste du BOARD.
 *  Parametres:
@@ -325,9 +328,6 @@ int WinEDA_PcbFrame::Solve( wxDC* DC, int two_sides )
 *      STOP_FROM_ESC si Escape demande
 *      ERR_MEMORY defaut alloc RAM
 */
static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
                          int two_sides, int row_source, int col_source,
                          int row_target, int col_target, CHEVELU* pt_chevelu )
{
    int        r, c, side, d, apx_dist, nr, nc;
    int        result, skip;
@@ -419,7 +419,8 @@ static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
    /* Placement du bit de suppression d'obstacle relative aux 2 pads a relier */
    pcbframe->Affiche_Message( wxT( "Gen Cells" ) );

    Place_1_Pad_Board( pcbframe->GetBoard(), pt_cur_ch->pad_start, CURRENT_PAD, marge, WRITE_OR_CELL );
    Place_1_Pad_Board(
        pcbframe->GetBoard(), pt_cur_ch->pad_start, CURRENT_PAD, marge, WRITE_OR_CELL );
    Place_1_Pad_Board( pcbframe->GetBoard(), pt_cur_ch->pad_end, CURRENT_PAD, marge, WRITE_OR_CELL );

    /* Regenere les barrieres restantes (qui peuvent empieter sur le placement
@@ -678,8 +679,10 @@ static int Route_1_Trace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
    }

end_of_route:
    Place_1_Pad_Board( pcbframe->GetBoard(), pt_cur_ch->pad_start, ~CURRENT_PAD, marge, WRITE_AND_CELL );
    Place_1_Pad_Board( pcbframe->GetBoard(), pt_cur_ch->pad_end, ~CURRENT_PAD, marge, WRITE_AND_CELL );
    Place_1_Pad_Board(
        pcbframe->GetBoard(), pt_cur_ch->pad_start, ~CURRENT_PAD, marge, WRITE_AND_CELL );
    Place_1_Pad_Board(
        pcbframe->GetBoard(), pt_cur_ch->pad_end, ~CURRENT_PAD, marge, WRITE_AND_CELL );

    return result;
}
@@ -688,30 +691,40 @@ end_of_route:
static long bit[8][9] = { /* OT=Otherside */
    /* N, NE, E, SE, S, SW, W, NW, OT */
/* N */
    { LINE_VERTICAL,    BENT_StoNE,   CORNER_SOUTHEAST, SHARP_StoSE,  0,
    { LINE_VERTICAL,    BENT_StoNE,                 CORNER_SOUTHEAST,
           SHARP_StoSE,
           0,
           SHARP_StoSW, CORNER_SOUTHWEST, BENT_StoNW, (HOLE | HOLE_SOUTH) },
/* NE */ { BENT_NtoSW,       DIAG_NEtoSW,  BENT_EtoSW,       ANGLE_SEtoSW, SHARP_StoSW,
/* NE */ { BENT_NtoSW,       DIAG_NEtoSW,                BENT_EtoSW,             ANGLE_SEtoSW,
           SHARP_StoSW,
           0, SHARP_WtoSW, ANGLE_SWtoNW, (HOLE | HOLE_SOUTHWEST) },
/* E */  { CORNER_NORTHWEST, BENT_WtoNE,                 LINE_HORIZONTAL,        BENT_WtoSE,
           CORNER_SOUTHWEST, SHARP_WtoSW, 0, SHARP_WtoNW, (HOLE | HOLE_WEST) },
/* SE */ { SHARP_NtoNW,      ANGLE_NWtoNE, BENT_EtoNW,       DIAG_SEtoNW,  BENT_StoNW,
/* SE */ { SHARP_NtoNW,      ANGLE_NWtoNE,               BENT_EtoNW,             DIAG_SEtoNW,
           BENT_StoNW,
           ANGLE_SWtoNW, SHARP_WtoNW, 0, (HOLE | HOLE_NORTHWEST) },
/* S */  { 0,                SHARP_NtoNE,  CORNER_NORTHEAST, BENT_NtoSE,   LINE_VERTICAL,
/* S */  { 0,                SHARP_NtoNE,                CORNER_NORTHEAST,       BENT_NtoSE,
           LINE_VERTICAL,
           BENT_NtoSW, CORNER_NORTHWEST, SHARP_NtoNW, (HOLE | HOLE_NORTH) },
/* SW */ { SHARP_NtoNE,      0,            SHARP_EtoNE,      ANGLE_NEtoSE, BENT_StoNE,
/* SW */ { SHARP_NtoNE,      0,                          SHARP_EtoNE,            ANGLE_NEtoSE,
           BENT_StoNE,
           DIAG_NEtoSW,
           BENT_WtoNE, ANGLE_NWtoNE, (HOLE | HOLE_NORTHEAST) },
/* W */  { CORNER_NORTHEAST, SHARP_EtoNE,  0,                SHARP_EtoSE,  CORNER_SOUTHEAST,
/* W */  { CORNER_NORTHEAST, SHARP_EtoNE,                0,                      SHARP_EtoSE,
           CORNER_SOUTHEAST,
           BENT_EtoSW, LINE_HORIZONTAL, BENT_EtoNW, (HOLE | HOLE_EAST) },
/* NW */ { BENT_NtoSE,       ANGLE_NEtoSE, SHARP_EtoSE,      0,            SHARP_StoSE,
/* NW */ { BENT_NtoSE,       ANGLE_NEtoSE,               SHARP_EtoSE,            0,
           SHARP_StoSE,
           ANGLE_SEtoSW, BENT_WtoSE, DIAG_SEtoNW, (HOLE | HOLE_SOUTHEAST) }
};

/*****************************************************************/
/* int Retrace (COMMAND * Cmd, int row_source, int col_source	 */
/*				int row_target, int col_target, int target_side, */
/*				 		int current_net_code )					 */
/*****************************************************************/

/*******************************************************************/
static int Retrace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
                    int row_source, int col_source,
                    int row_target, int col_target, int target_side,
                    int current_net_code )
/*******************************************************************/

/* work from target back to source, actually laying the traces
 *  Parametres:
@@ -729,10 +742,6 @@ static long bit[8][9] = { /* OT=Otherside */
 *      > 0 si Ok
 */

static int Retrace( WinEDA_PcbFrame* pcbframe, wxDC* DC,
                    int row_source, int col_source,
                    int row_target, int col_target, int target_side,
                    int current_net_code )
{
    int  r0, c0, s0;
    int  r1, c1, s1;    /* row, col, side d'ou on vient */
@@ -995,8 +1004,7 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,

                if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) /* le dernier segment est en ligne*/
                {
                    oldTrack->m_End.x = g_CurrentTrackSegment->m_End.x;
                    oldTrack->m_End.y = g_CurrentTrackSegment->m_End.y;
                    oldTrack->m_End = g_CurrentTrackSegment->m_End;

                    delete g_CurrentTrackList.PopBack();
                }
@@ -1006,16 +1014,18 @@ static void OrCell_Trace( BOARD* pcb, int col, int row,
}


/*******************************************/
/* static void Place_Piste_en_Buffer() */
/*******************************************/
/***********************************************************************/
static void Place_Piste_en_Buffer( WinEDA_PcbFrame* pcbframe, wxDC* DC )
/***********************************************************************/

/* Insere la nouvelle piste creee dans la liste standard des pistes.
 *  Modifie les points de debut et fin de piste pour qu'ils soient relies
 *  au centre des pads corresponadants, meme hors grille
 */
static void Place_Piste_en_Buffer( WinEDA_PcbFrame* pcbframe, wxDC* DC )
{
    if( g_FirstTrackSegment == NULL )
        return;

    int dx0, dy0, dx1, dy1;
    int marge, via_marge;
    WinEDA_DrawPanel* panel = pcbframe->DrawPanel;
@@ -1047,27 +1057,39 @@ static void Place_Piste_en_Buffer( WinEDA_PcbFrame* pcbframe, wxDC* DC )
        g_CurrentTrackList.PushBack( newTrack );
    }

    g_FirstTrackSegment->start = Locate_Pad_Connecte( pcbframe->GetBoard(), g_FirstTrackSegment, START );
    g_FirstTrackSegment->start = Locate_Pad_Connecte(
        pcbframe->GetBoard(), g_FirstTrackSegment, START );
    if( g_FirstTrackSegment->start )
        g_FirstTrackSegment->SetState( BEGIN_ONPAD, ON );

    g_CurrentTrackSegment->end = Locate_Pad_Connecte( pcbframe->GetBoard(), g_CurrentTrackSegment, END );
    g_CurrentTrackSegment->end = Locate_Pad_Connecte(
        pcbframe->GetBoard(), g_CurrentTrackSegment, END );
    if( g_CurrentTrackSegment->end )
        g_CurrentTrackSegment->SetState( END_ONPAD, ON );

    /* recherche de la zone de rangement et insertion de la nouvelle piste */
    pcbframe->GetBoard()->Add( g_FirstTrackSegment );

    Trace_Une_Piste( panel, DC, g_FirstTrackSegment, g_CurrentTrackList.GetCount(), GR_OR );

    pcbframe->test_1_net_connexion( DC, g_FirstTrackSegment->GetNet() );

    /* Trace de la forme exacte de la piste en BOARD */
    /* Out the new track on the matrix board */
    for( TRACK* track = g_FirstTrackSegment;  track;  track = track->Next() )
    {
        TraceSegmentPcb( pcbframe->GetBoard(), track, HOLE, marge, WRITE_CELL );
        TraceSegmentPcb( pcbframe->GetBoard(), track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
    }

    // Insert new segments in  real board
    int    netcode    = g_FirstTrackSegment->GetNet();
    TRACK* firstTrack = g_FirstTrackSegment;
    int    newCount   = g_CurrentTrackList.GetCount();

    // Put entire new current segment list in BOARD
    TRACK* track;
    TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( pcbframe->GetBoard() );
    while( ( track = g_CurrentTrackList.PopFront() ) != NULL )
    {
        pcbframe->GetBoard()->m_Track.Insert( track, insertBeforeMe );
    }

    Trace_Une_Piste( panel, DC, firstTrack, newCount, GR_OR );

    pcbframe->test_1_net_connexion( DC, netcode );

    ActiveScreen->SetModify();
}