Exemplo n.º 1
0
/* work from target back to source, actually laying the traces
 *  Parameters:
 *      start on side target_side, of coordinates row_target, col_target.
 *      arrive on side masque_layer_start, coordinate row_source, col_source
 * The search is done in reverse routing, the point of arrival (target) to
 * the starting point (source)
 * The router.
 *
 * Target_side = symbol (TOP / BOTTOM) of departure
 * = Mask_layer_source mask layers Arrival
 *
 * Returns:
 * 0 if error
 * > 0 if Ok
 */
static int Retrace( PCB_EDIT_FRAME* 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, starting side.
    int  r2, c2, s2;    // row, col, ending side.
    int  x, y = -1;
    long b;

    r1 = row_target;
    c1 = col_target;    // start point is target ( end point is source )
    s1 = target_side;
    r0 = c0 = s0 = ILLEGAL;

    wxASSERT( g_CurrentTrackList.GetCount() == 0 );

    do
    {
        // find where we came from to get here
        r2 = r1; c2 = c1; s2 = s1;
        x  = RoutingMatrix.GetDir( r1, c1, s1 );

        switch( x )
        {
        case FROM_NORTH:
            r2++;
            break;

        case FROM_EAST:
            c2++;
            break;

        case FROM_SOUTH:
            r2--;
            break;

        case FROM_WEST:
            c2--;
            break;

        case FROM_NORTHEAST:
            r2++;
            c2++;
            break;

        case FROM_SOUTHEAST:
            r2--;
            c2++;
            break;

        case FROM_SOUTHWEST:
            r2--;
            c2--;
            break;

        case FROM_NORTHWEST:
            r2++;
            c2--;
            break;

        case FROM_OTHERSIDE:
            s2 = 1 - s2;
            break;

        default:
            wxMessageBox( wxT( "Retrace: internal error: no way back" ) );
            return 0;
        }

        if( r0 != ILLEGAL )
            y = RoutingMatrix.GetDir( r0, c0, s0 );

        // see if target or hole
        if( ( ( r1 == row_target ) && ( c1 == col_target ) ) || ( s1 != s0 ) )
        {
            int p_dir;

            switch( x )
            {
            case FROM_NORTH:
                p_dir = HOLE_NORTH;
                break;

            case FROM_EAST:
                p_dir = HOLE_EAST;
                break;

            case FROM_SOUTH:
                p_dir = HOLE_SOUTH;
                break;

            case FROM_WEST:
                p_dir = HOLE_WEST;
                break;

            case FROM_NORTHEAST:
                p_dir = HOLE_NORTHEAST;
                break;

            case FROM_SOUTHEAST:
                p_dir = HOLE_SOUTHEAST;
                break;

            case FROM_SOUTHWEST:
                p_dir = HOLE_SOUTHWEST;
                break;

            case FROM_NORTHWEST:
                p_dir = HOLE_NORTHWEST;
                break;

            case FROM_OTHERSIDE:
            default:
                DisplayError( pcbframe, wxT( "Retrace: error 1" ) );
                return 0;
            }

            OrCell_Trace( pcbframe->GetBoard(), r1, c1, s1, p_dir, current_net_code );
        }
        else
        {
            if( ( y == FROM_NORTH || y == FROM_NORTHEAST
                  || y == FROM_EAST || y == FROM_SOUTHEAST
                  || y == FROM_SOUTH || y == FROM_SOUTHWEST
                  || y == FROM_WEST || y == FROM_NORTHWEST )
               && ( x == FROM_NORTH || x == FROM_NORTHEAST
                    || x == FROM_EAST || x == FROM_SOUTHEAST
                    || x == FROM_SOUTH || x == FROM_SOUTHWEST
                    || x == FROM_WEST || x == FROM_NORTHWEST
                    || x == FROM_OTHERSIDE )
               && ( ( b = bit[y - 1][x - 1] ) != 0 ) )
            {
                OrCell_Trace( pcbframe->GetBoard(), r1, c1, s1, b, current_net_code );

                if( b & HOLE )
                    OrCell_Trace( pcbframe->GetBoard(), r2, c2, s2, HOLE, current_net_code );
            }
            else
            {
                wxMessageBox( wxT( "Retrace: error 2" ) );
                return 0;
            }
        }

        if( ( r2 == row_source ) && ( c2 == col_source ) ) // see if source
        {
            int p_dir;

            switch( x )
            {
            case FROM_NORTH:
                p_dir = HOLE_SOUTH;
                break;

            case FROM_EAST:
                p_dir = HOLE_WEST;
                break;

            case FROM_SOUTH:
                p_dir = HOLE_NORTH;
                break;

            case FROM_WEST:
                p_dir = HOLE_EAST;
                break;

            case FROM_NORTHEAST:
                p_dir = HOLE_SOUTHWEST;
                break;

            case FROM_SOUTHEAST:
                p_dir = HOLE_NORTHWEST;
                break;

            case FROM_SOUTHWEST:
                p_dir = HOLE_NORTHEAST;
                break;

            case FROM_NORTHWEST:
                p_dir = HOLE_SOUTHEAST;
                break;

            case FROM_OTHERSIDE:
            default:
                wxMessageBox( wxT( "Retrace: error 3" ) );
                return 0;
            }

            OrCell_Trace( pcbframe->GetBoard(), r2, c2, s2, p_dir, current_net_code );
        }

        // move to next cell
        r0 = r1;
        c0 = c1;
        s0 = s1;
        r1 = r2;
        c1 = c2;
        s1 = s2;
    } while( !( ( r2 == row_source ) && ( c2 == col_source ) ) );

    AddNewTrace( pcbframe, DC );
    return 1;
}
Exemplo n.º 2
0
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 */
int r2, c2, s2;		/* row, col, side ou on va */
int x, y = -1;
long b;

	r1 = row_target;
	c1 = col_target;	/* start point is target ( end point is source )*/
	s1 = target_side;
	r0 = c0 = s0 = ILLEGAL;

	g_FirstTrackSegment = g_CurrentTrackSegment = NULL;
	g_TrackSegmentCount = 0;

	do {
		/* find where we came from to get here */
		r2 = r1; c2 = c1; s2 = s1;
		x = GetDir( r1, c1, s1 );
		switch ( x )
			{
			case FROM_NORTH:		r2++;	break;
			case FROM_EAST:			c2++;	break;
			case FROM_SOUTH:		r2--;	break;
			case FROM_WEST:			c2--;	break;
			case FROM_NORTHEAST:	r2++;	c2++;	break;
			case FROM_SOUTHEAST:	r2--;	c2++;	break;
			case FROM_SOUTHWEST:	r2--;	c2--;	break;
			case FROM_NORTHWEST:	r2++;	c2--;	break;
			case FROM_OTHERSIDE:	s2 = 1-s2;	break;
			default:
				DisplayError(pcbframe, wxT("Retrace: internal error: no way back"));
				return(0);
			}

		if (r0 != ILLEGAL) y = GetDir( r0, c0, s0 );

		/* see if target or hole */
		if( ( (r1 == row_target) && (c1 == col_target) )
			|| (s1 != s0))
			{
			int p_dir;
			switch (x)
				{
				case FROM_NORTH:
					p_dir = HOLE_NORTH; break;
				case FROM_EAST:
					p_dir = HOLE_EAST; break;
				case FROM_SOUTH:
					p_dir = HOLE_SOUTH;	break;
				case FROM_WEST:
					p_dir = HOLE_WEST;	break;
				case FROM_NORTHEAST:
					p_dir = HOLE_NORTHEAST;	break;
				case FROM_SOUTHEAST:
					p_dir = HOLE_SOUTHEAST;	break;
				case FROM_SOUTHWEST:
					p_dir = HOLE_SOUTHWEST;	break;
				case FROM_NORTHWEST:
					p_dir = HOLE_NORTHWEST;	break;

				case FROM_OTHERSIDE:
				default:
					DisplayError(pcbframe, wxT("Retrace: error 1"));
					return(0);
				}
			OrCell_Trace(pcbframe->m_Pcb, r1, c1, s1, p_dir, current_net_code );
			}

		else {
			if( (y == FROM_NORTH || y == FROM_NORTHEAST
				|| y == FROM_EAST || y == FROM_SOUTHEAST
				|| y == FROM_SOUTH || y == FROM_SOUTHWEST
				|| y == FROM_WEST || y == FROM_NORTHWEST) &&
				(x == FROM_NORTH || x == FROM_NORTHEAST
				|| x == FROM_EAST || x == FROM_SOUTHEAST
				|| x == FROM_SOUTH || x == FROM_SOUTHWEST
				|| x == FROM_WEST || x == FROM_NORTHWEST
				|| x == FROM_OTHERSIDE) &&
				((b = bit[y-1][x-1]) != 0) )
				{
				OrCell_Trace(pcbframe->m_Pcb, r1, c1, s1, b, current_net_code );
				if (b & HOLE)
					OrCell_Trace(pcbframe->m_Pcb, r2, c2, s2, HOLE, current_net_code );
				}
			else
				{
				DisplayError(pcbframe, wxT("Retrace: error 2"));
				return(0);
				}
			}

		if( (r2 == row_source) && (c2 == col_source) )
			{ /* see if source */
			int p_dir;
			switch (x)
				{
				case FROM_NORTH: p_dir = HOLE_SOUTH; break;
				case FROM_EAST:  p_dir = HOLE_WEST;	 break;
				case FROM_SOUTH: p_dir = HOLE_NORTH; break;
				case FROM_WEST:  p_dir = HOLE_EAST;	break;
				case FROM_NORTHEAST: p_dir = HOLE_SOUTHWEST; break;
				case FROM_SOUTHEAST: p_dir = HOLE_NORTHWEST; break;
				case FROM_SOUTHWEST: p_dir = HOLE_NORTHEAST; break;
				case FROM_NORTHWEST: p_dir = HOLE_SOUTHEAST; break;

				case FROM_OTHERSIDE:
				default:
					DisplayError(pcbframe, wxT("Retrace: error 3"));
					return(0);
				}
			OrCell_Trace(pcbframe->m_Pcb, r2, c2, s2, p_dir, current_net_code );
			}
		/* move to next cell */
		r0 = r1; c0 = c1; s0 = s1;
		r1 = r2; c1 = c2; s1 = s2;
		} while( !( (r2 == row_source) && (c2 == col_source) ) );

	Place_Piste_en_Buffer(pcbframe, DC);
	return(1);
}