/* 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; }
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); }