autorout.cpp 6.86 KB
Newer Older
1 2 3
/***************************************/
/* PCBNEW: Autorouting command control */
/***************************************/
4 5 6 7

#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
8 9
#include "class_drawpanel.h"
#include "confirm.h"
10 11 12
#include "pcbnew.h"
#include "autorout.h"
#include "cell.h"
13
#include "zones.h"
14 15 16 17 18 19 20 21

#include "protos.h"

/* routines internes */

/* Variables locales */

/********************************************************/
22
void WinEDA_PcbFrame::Autoroute( wxDC* DC, int mode )
23 24 25
/********************************************************/
/* init board, route traces*/
{
26 27 28 29 30 31 32 33 34
    int      ii, start, stop;
    CHEVELU* ptmp;
    MODULE*  Module = NULL;
    D_PAD*   Pad    = NULL;
    int      autoroute_net_code = -1;
    wxString msg;

    if( g_DesignSettings.m_CopperLayerCount > 1 )
    {
35 36
        Route_Layer_TOP    = ((PCB_SCREEN*)GetScreen())->m_Route_Layer_TOP;
        Route_Layer_BOTTOM = ((PCB_SCREEN*)GetScreen())->m_Route_Layer_BOTTOM;
37 38 39 40 41 42 43 44 45 46 47 48 49 50
    }
    else
    {
        Route_Layer_TOP =
            Route_Layer_BOTTOM = COPPER_LAYER_N;
    }

    switch( mode )
    {
    case ROUTE_NET:
        if( GetScreen()->GetCurItem() )
        {
            switch( GetScreen()->GetCurItem()->Type() )
            {
51
            case TYPE_PAD:
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
                Pad = (D_PAD*) GetScreen()->GetCurItem();
                autoroute_net_code = Pad->GetNet();
                break;

            default:
                break;
            }
        }
        if( autoroute_net_code <= 0 )
        {
            DisplayError( this, _( "Net not selected" ) ); return;
        }
        break;

    case ROUTE_MODULE:
        Module = (MODULE*) GetScreen()->GetCurItem();
68
        if( (Module == NULL) || (Module->Type() != TYPE_MODULE) )
69 70 71 72 73 74 75
        {
            DisplayError( this, _( "Module not selected" ) ); return;
        }
        break;

    case ROUTE_PAD:
        Pad = (D_PAD*) GetScreen()->GetCurItem();
76
        if( (Pad == NULL)  || (Pad->Type() != TYPE_PAD) )
77 78 79 80 81 82
        {
            DisplayError( this, _( "Pad not selected" ) ); return;
        }
        break;
    }

83
    if( (GetBoard()->m_Status_Pcb & LISTE_CHEVELU_OK ) == 0 )
84 85 86
        Compile_Ratsnest( DC, TRUE );

    /* Placement du flag CH_ROUTE_REQ sur les chevelus demandes */
87 88
    ptmp = (CHEVELU*) GetBoard()->m_Ratsnest;
    for( ii = GetBoard()->GetNumRatsnests(); ii > 0; ii--, ptmp++ )
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    {
        ptmp->status &= ~CH_ROUTE_REQ;

        switch( mode )
        {
        case ROUTE_ALL:
            ptmp->status |= CH_ROUTE_REQ; break;

        case ROUTE_NET:
            if( autoroute_net_code == ptmp->GetNet() )
                ptmp->status |= CH_ROUTE_REQ;
            break;

        case ROUTE_MODULE:
        {
            D_PAD* pt_pad = (D_PAD*) Module->m_Pads;
105
            for( ; pt_pad != NULL; pt_pad = pt_pad->Next() )
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
            {
                if( ptmp->pad_start == pt_pad )
                    ptmp->status |= CH_ROUTE_REQ;
                if( ptmp->pad_end == pt_pad )
                    ptmp->status |= CH_ROUTE_REQ;
            }

            break;
        }

        case ROUTE_PAD:
            if( (ptmp->pad_start == Pad) || (ptmp->pad_end == Pad) )
                ptmp->status |= CH_ROUTE_REQ;
            break;
        }
    }

123
    ptmp = (CHEVELU*) GetBoard()->m_Ratsnest;
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

    start = time( NULL );

    /* Calcul du pas de routage fixe a 5 mils et plus */
    g_GridRoutingSize = GetScreen()->GetGrid().x;
    if( g_GridRoutingSize < 50 )
        g_GridRoutingSize = 50;
    E_scale = g_GridRoutingSize / 50; if( E_scale < 1 )
        E_scale = 1;

    /* calcule de Ncols et Nrow, taille de la matrice de routage */
    ComputeMatriceSize( this, g_GridRoutingSize );

    MsgPanel->EraseMsgBox();

    /* Creation du mapping du board */
    Nb_Sides = ONE_SIDE;
    if( Route_Layer_TOP != Route_Layer_BOTTOM )
        Nb_Sides = TWO_SIDES;

    if( Board.InitBoard() < 0 )
    {
        DisplayError( this, _( "No memory for autorouting" ) );
        Board.UnInitBoard();  /* Libere la memoire BitMap */
        return;
    }

    Affiche_Message( _( "Place Cells" ) );
152
    PlaceCells( GetBoard(), -1, FORCE_PADS );
153 154

    /* Construction de la liste des pistes a router */
155
    Build_Work( GetBoard(), ptmp );
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

    // DisplayBoard(DrawPanel, DC);

    if( Nb_Sides == TWO_SIDES )
        Solve( DC, TWO_SIDES ); /* double face */
    else
        Solve( DC, ONE_SIDE );  /* simple face */

    /* Liberation de la memoire */
    FreeQueue();            /* Libere la memoire de routage */
    InitWork();             /* Libere la memoire de la liste des connexions a router */
    Board.UnInitBoard();    /* Libere la memoire BitMap */
    stop = time( NULL ) - start;
    msg.Printf( wxT( "time = %d second%s" ), stop, (stop == 1) ? wxT( "" ) : wxT( "s" ) );
    Affiche_Message( msg );
171 172
}

173

174
/************************************************/
175
void WinEDA_PcbFrame::Reset_Noroutable( wxDC* DC )
176
/*************************************************/
177 178 179 180 181

/* Remet a 0 le flag CH_NOROUTABLE qui est positionne a 1 par Solve()
 *  lorsque un chevelu n'a pas ete route.
 *  Si ce flag est a 1 il n'est pas reroute
 */
182
{
183 184
    int      ii;
    CHEVELU* pt_rats;
185

186
    if( (GetBoard()->m_Status_Pcb & LISTE_CHEVELU_OK )== 0 )
187
        Compile_Ratsnest( DC, TRUE );
188

189
    pt_rats = (CHEVELU*) GetBoard()->m_Ratsnest;
190 191
    if( pt_rats == NULL )
        return;
192

193
    for( ii = GetBoard()->GetNumRatsnests(); ii > 0; ii--, pt_rats++ )
194 195 196
    {
        pt_rats->status &= ~CH_UNROUTABLE;
    }
197 198
}

199

200
/*****************************************************/
201
void DisplayBoard( WinEDA_DrawPanel* panel, wxDC* DC )
202 203 204
/****************************************************/
/* Fonction de DEBUG : affiche le remplissage des cellules TOP et BOTTOM */
{
205 206 207 208
    int row, col, i, j;
    int dcell0, dcell1 = 0, color;
    int maxi;

209
    maxi = 600 / Ncols;
210 211 212 213
    maxi = (maxi * 3 ) / 4;
    if( !maxi )
        maxi = 1;

214
    GRSetDrawMode( DC, GR_COPY );
215 216 217 218 219
    for( col = 0; col < Ncols; col++ )
    {
        for( row = 0; row < Nrows; row++ )
        {
            color  = 0;
220
            dcell0 = GetCell( row, col, BOTTOM );
221
            if( dcell0 & HOLE )
222
                color = GREEN;
223 224
//            if( Nb_Sides )
//                dcell1 = GetCell( row, col, TOP );
225 226
            if( dcell1 & HOLE )
                color |= RED;
227
//            dcell0 |= dcell1;
228 229
            if( !color && (dcell0 & VIA_IMPOSSIBLE) )
                color = BLUE;
230
            if( dcell0 & CELL_is_EDGE )
231
                color = YELLOW;
232
            else if( dcell0 & CELL_is_ZONE )
233
                color = YELLOW;
234 235 236

            #define DRAW_OFFSET_X -20
            #define DRAW_OFFSET_Y 20
237
//            if( color )
238 239 240 241
            {
                for( i = 0; i < maxi; i++ )
                    for( j = 0; j < maxi; j++ )
                        GRSPutPixel( &panel->m_ClipBox, DC,
242
                                     (col * maxi) + i + DRAW_OFFSET_X,
243
                                     (row * maxi) + j + DRAW_OFFSET_Y, color );
244 245 246 247

            }
        }
    }
248
}