void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset, GR_DRAWMODE DrawMode, EDA_COLOR_T Color ) { EDA_COLOR_T color; int linewidth = ( m_Thickness == 0 ) ? GetDefaultLineThickness() : m_Thickness; linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold ); if( Color >= 0 ) color = Color; else color = ReturnLayerColor( m_Layer ); GRSetDrawMode( DC, DrawMode ); wxPoint text_offset = aOffset + GetSchematicTextOffset(); EXCHG( linewidth, m_Thickness ); // Set the minimum width EDA_TEXT::Draw( panel, DC, text_offset, color, DrawMode, FILLED, UNSPECIFIED_COLOR ); EXCHG( linewidth, m_Thickness ); // set initial value if( m_isDangling ) DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color ); // Enable these line to draw the bounding box (debug tests purposes only) #if 0 { EDA_RECT BoundaryBox = GetBoundingBox(); GRRect( panel->GetClipBox(), DC, BoundaryBox, 0, BROWN ); } #endif }
void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( outputFile ); if( radius <= 0 ) return; if( StAngle > EndAngle ) EXCHG( StAngle, EndAngle ); SetCurrentLineWidth( width ); // Calculate start point. DPOINT centre_dev = userToDeviceCoordinates( centre ); double radius_dev = userToDeviceSize( radius ); if( m_plotMirror ) { if( m_mirrorIsHorizontal ) { StAngle = 1800.0 -StAngle; EndAngle = 1800.0 -EndAngle; EXCHG( StAngle, EndAngle ); } else { StAngle = -StAngle; EndAngle = -EndAngle; } } fprintf( outputFile, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y, radius_dev, StAngle / 10.0, EndAngle / 10.0, fill ); }
void PCB_TARGET::Exchg( PCB_TARGET* source ) { EXCHG( m_Pos, source->m_Pos ); EXCHG( m_Width, source->m_Width ); EXCHG( m_Size, source->m_Size ); EXCHG( m_Shape, source->m_Shape ); }
void SCH_JUNCTION::SwapData( SCH_ITEM* aItem ) { wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_JUNCTION_T), wxT( "Cannot swap junction data with invalid item." ) ); SCH_JUNCTION* item = (SCH_JUNCTION*) aItem; EXCHG( m_pos, item->m_pos ); EXCHG( m_size, item->m_size ); }
void SCH_NO_CONNECT::SwapData( SCH_ITEM* aItem ) { wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_NO_CONNECT_T), wxT( "Cannot swap no connect data with invalid item." ) ); SCH_NO_CONNECT* item = (SCH_NO_CONNECT*)aItem; EXCHG( m_pos, item->m_pos ); EXCHG( m_size, item->m_size ); }
void SCH_BUS_ENTRY::SwapData( SCH_ITEM* aItem ) { wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_BUS_ENTRY_T), wxT( "Cannot swap bus entry data with invalid item." ) ); SCH_BUS_ENTRY* item = (SCH_BUS_ENTRY*)aItem; EXCHG( m_pos, item->m_pos ); EXCHG( m_size, item->m_size ); EXCHG( m_width, item->m_width ); }
void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); int x0, y0, x1, y1, delta; wxSize size( aSize ); /* Plot a flashed shape. */ if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 ) && trace_mode == FILLED ) { if( orient == 900 || orient == 2700 ) /* orientation turned 90 deg. */ EXCHG( size.x, size.y ); DPOINT pos_dev = userToDeviceCoordinates( pos ); selectAperture( size, APERTURE::Oval ); emitDcode( pos_dev, 3 ); } else /* Plot pad as a segment. */ { if( size.x > size.y ) { EXCHG( size.x, size.y ); if( orient < 2700 ) orient += 900; else orient -= 2700; } if( trace_mode == FILLED ) { /* XXX to do: use an aperture macro to declare the rotated pad */ /* The pad is reduced to an oval with dy > dx */ delta = size.y - size.x; x0 = 0; y0 = -delta / 2; x1 = 0; y1 = delta / 2; RotatePoint( &x0, &y0, orient ); RotatePoint( &x1, &y1, orient ); ThickSegment( wxPoint( pos.x + x0, pos.y + y0 ), wxPoint( pos.x + x1, pos.y + y1 ), size.x, trace_mode ); } else { sketchOval( pos, size, orient, -1 ); } } }
/* Plot oval pad at position pos: * Dimensions dx, dy, * Orient Orient * For a vertical or horizontal orientation, the shape is flashed * For any orientation the shape is drawn as a segment */ void GERBER_PLOTTER::flash_pad_oval( wxPoint pos, wxSize size, int orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( output_file ); int x0, y0, x1, y1, delta; /* Plot a flashed shape. */ if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 ) && trace_mode == FILLED ) { if( orient == 900 || orient == 2700 ) /* orientation turned 90 deg. */ EXCHG( size.x, size.y ); user_to_device_coordinates( pos ); select_aperture( size, APERTURE::Oval ); fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y ); } else /* Plot pad as a segment. */ { if( size.x > size.y ) { EXCHG( size.x, size.y ); if( orient < 2700 ) orient += 900; else orient -= 2700; } if( trace_mode == FILLED ) { /* The pad is reduced to an oval with dy > dx */ delta = size.y - size.x; x0 = 0; y0 = -delta / 2; x1 = 0; y1 = delta / 2; RotatePoint( &x0, &y0, orient ); RotatePoint( &x1, &y1, orient ); thick_segment( wxPoint( pos.x + x0, pos.y + y0 ), wxPoint( pos.x + x1, pos.y + y1 ), size.x, trace_mode ); } else { sketch_oval( pos, size, orient, -1 ); } } }
void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxPoint start, end; const int delta = 50; // increment (in 0.1 degrees) to draw circles if( StAngle > EndAngle ) EXCHG( StAngle, EndAngle ); SetCurrentLineWidth( width ); /* Please NOTE the different sign due to Y-axis flip */ start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) ); start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) ); MoveTo( start ); for( int ii = StAngle + delta; ii < EndAngle; ii += delta ) { end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) ); end.y = centre.y + KiROUND( sindecideg( radius, -ii ) ); LineTo( end ); } end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) ); end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) ); FinishTo( end ); }
wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition ) const { /* Note: RS274Xrevd_e is obscure about the order of transforms: * For instance: Rotation must be made after or before mirroring ? * Note: if something is changed here, GetYXPosition must reflect changes */ wxPoint abPos = aXYPosition + m_imageParams->m_ImageJustifyOffset; if( m_swapAxis ) EXCHG( abPos.x, abPos.y ); abPos += m_layerOffset + m_imageParams->m_ImageOffset; abPos.x = KiROUND( abPos.x * m_drawScale.x ); abPos.y = KiROUND( abPos.y * m_drawScale.y ); double rotation = m_lyrRotation * 10 + m_imageParams->m_ImageRotation * 10; if( rotation ) RotatePoint( &abPos, -rotation ); // Negate A axis if mirrored if( m_mirrorA ) NEGATE( abPos.x ); // abPos.y must be negated when no mirror, because draw axis is top to bottom if( !m_mirrorB ) NEGATE( abPos.y ); return abPos; }
void DIALOG_EESCHEMA_CONFIG::OnButtonDownClick( wxCommandEvent& event ) { wxArrayInt selections; m_ListLibr->GetSelections(selections); if ( selections.GetCount() <= 0 ) // No selection. return; // The last lib is selected. cannot move down it if( selections.Last() == (int)(m_ListLibr->GetCount()-1) ) return; wxArrayString libnames = m_ListLibr->GetStrings(); for( int ii = selections.GetCount()-1; ii >= 0; ii-- ) { int jj = selections[ii]; EXCHG( libnames[jj], libnames[jj+1]); } m_ListLibr->Set( libnames ); // Reselect previously selected names for( size_t ii = 0; ii < selections.GetCount(); ii++ ) { int jj = selections[ii]; m_ListLibr->SetSelection(jj+1); } m_LibListChanged = true; }
/* Plot oval pad. */ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); int deltaxy, cx, cy; wxSize size( aSize ); /* The pad is reduced to an oval with size.y > size.x * (Oval vertical orientation 0) */ if( size.x > size.y ) { EXCHG( size.x, size.y ); orient = AddAngles( orient, 900 ); } deltaxy = size.y - size.x; // distance between centers of the oval if( trace_mode == FILLED ) { FlashPadRect( pos, wxSize( size.x, deltaxy + KiROUND( penDiameter ) ), orient, trace_mode ); cx = 0; cy = deltaxy / 2; RotatePoint( &cx, &cy, orient ); FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode ); cx = 0; cy = -deltaxy / 2; RotatePoint( &cx, &cy, orient ); FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode ); } else // Plot in SKETCH mode. { sketchOval( pos, size, orient, KiROUND( penDiameter ) ); } }
void PSLIKE_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T modetrace ) { wxASSERT( outputFile ); int x0, y0, x1, y1, delta; wxSize size( aSize ); // The pad is reduced to an oval by dy > dx if( size.x > size.y ) { EXCHG( size.x, size.y ); orient = AddAngles( orient, 900 ); } delta = size.y - size.x; x0 = 0; y0 = -delta / 2; x1 = 0; y1 = delta / 2; RotatePoint( &x0, &y0, orient ); RotatePoint( &x1, &y1, orient ); if( modetrace == FILLED ) ThickSegment( wxPoint( pos.x + x0, pos.y + y0 ), wxPoint( pos.x + x1, pos.y + y1 ), size.x, modetrace ); else sketchOval( pos, size, orient, -1 ); }
wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition ) { // do the inverse transform made by GetABPosition wxPoint xyPos = aABPosition; if( m_mirrorA ) NEGATE( xyPos.x ); if( !m_mirrorB ) NEGATE( xyPos.y ); double rotation = m_lyrRotation * 10 + m_imageParams->m_ImageRotation * 10; if( rotation ) RotatePoint( &xyPos, rotation ); xyPos.x = KiROUND( xyPos.x / m_drawScale.x ); xyPos.y = KiROUND( xyPos.y / m_drawScale.y ); xyPos -= m_layerOffset + m_imageParams->m_ImageOffset; if( m_swapAxis ) EXCHG( xyPos.x, xyPos.y ); return xyPos - m_imageParams->m_ImageJustifyOffset; }
/* Plot rectangular pad. * Gives its center, size, and orientation * For a vertical or horizontal shape, the shape is an aperture (Dcode) and * it is flashed. * For others shape the direction is plotted as a polygon. */ void GERBER_PLOTTER::flash_pad_rect( wxPoint pos, wxSize size, int orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( output_file ); /* Plot as flashed. */ switch( orient ) { case 900: case 2700: /* rotation of 90 degrees or 270 returns dimensions */ EXCHG( size.x, size.y ); // Pass through case 0: case 1800: switch( trace_mode ) { case LINE: case SKETCH: set_current_line_width( -1 ); rect( wxPoint( pos.x - (size.x - current_pen_width) / 2, pos.y - (size.y - current_pen_width) / 2 ), wxPoint( pos.x + (size.x - current_pen_width) / 2, pos.y + (size.y - current_pen_width) / 2 ), NO_FILL ); break; case FILLED: user_to_device_coordinates( pos ); select_aperture( size, APERTURE::Rect ); fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y ); break; } break; default: /* plot pad shape as polygon */ { wxPoint coord[4]; // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ coord[0].x = -size.x/2; // lower left coord[0].y = size.y/2; coord[1].x = -size.x/2; // upper left coord[1].y = -size.y/2; coord[2].x = size.x/2; // upper right coord[2].y = -size.y/2; coord[3].x = size.x/2; //lower right coord[3].y = size.y/2; flash_pad_trapez( pos, coord, orient, trace_mode ); } break; } }
int IsBusLabel( const char * LabelDrawList ) /**************************************************/ /* Routine qui verifie si le Label a une notation de type Bus Retourne 0 si non nombre de membres si oui met a jour FirstNumWireBus, LastNumWireBus et RootBusNameLength */ { char * Num; char BufLine[1024]; if ( strchr(LabelDrawList,'[') == NULL ) /* 1er [ trouve : c'est une notation de Bus */ return(0); strcpy(BufLine, LabelDrawList); Num = strtok(BufLine,"["); RootBusNameLength = strlen(Num); Num = strtok(NULL,"."); FirstNumWireBus = atoi(Num); Num = strtok(NULL,".]"); LastNumWireBus = atoi(Num); if( FirstNumWireBus < 0 ) FirstNumWireBus = 0; if( LastNumWireBus < 0 ) LastNumWireBus = 0; if( FirstNumWireBus > LastNumWireBus ) { EXCHG( FirstNumWireBus, LastNumWireBus); } return(LastNumWireBus - FirstNumWireBus + 1 ); }
void DIALOG_EESCHEMA_CONFIG::OnButtonUpClick( wxCommandEvent& event ) { wxArrayInt selections; m_ListLibr->GetSelections( selections ); if ( selections.GetCount() <= 0 ) // No selection. return; if( selections[0] == 0 ) // The first lib is selected. cannot move up it return; wxArrayString libnames = m_ListLibr->GetStrings(); for( size_t ii = 0; ii < selections.GetCount(); ii++ ) { int jj = selections[ii]; EXCHG( libnames[jj], libnames[jj-1]); } m_ListLibr->Set(libnames); // Reselect previously selected names for( size_t ii = 0; ii < selections.GetCount(); ii++ ) { int jj = selections[ii]; m_ListLibr->SetSelection(jj-1); } m_LibListChanged = true; }
int gr_vline(int y1, int y2, int x) { int i; if (y1 > y2) EXCHG(y1,y2); for (i=y1; i<=y2; i++ ) gr_upixel( x, i ); return 0; }
int gr_vline(int y1, int y2, int x) { int i; if (y1 > y2) EXCHG(y1, y2); for (i = y1; i <= y2; i++) // gr_upixel( x, i ); DATA[ROWSIZE*i + x] = COLOR; return 0; }
void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, double orient, EDA_DRAW_MODE_T trace_mode ) { wxASSERT( outputFile ); wxSize size( aSize ); // Plot as an aperture flash switch( int( orient ) ) { case 900: case 2700: // rotation of 90 degrees or 270 swaps sizes EXCHG( size.x, size.y ); // Pass through case 0: case 1800: if( trace_mode == SKETCH ) { SetCurrentLineWidth( -1 ); Rect( wxPoint( pos.x - (size.x - currentPenWidth) / 2, pos.y - (size.y - currentPenWidth) / 2 ), wxPoint( pos.x + (size.x - currentPenWidth) / 2, pos.y + (size.y - currentPenWidth) / 2 ), NO_FILL ); } else { DPOINT pos_dev = userToDeviceCoordinates( pos ); selectAperture( size, APERTURE::Rect ); emitDcode( pos_dev, 3 ); } break; default: // plot pad shape as polygon { // XXX to do: use an aperture macro to declare the rotated pad wxPoint coord[4]; // coord[0] is assumed the lower left // coord[1] is assumed the upper left // coord[2] is assumed the upper right // coord[3] is assumed the lower right /* Trace the outline. */ coord[0].x = -size.x/2; // lower left coord[0].y = size.y/2; coord[1].x = -size.x/2; // upper left coord[1].y = -size.y/2; coord[2].x = size.x/2; // upper right coord[2].y = -size.y/2; coord[3].x = size.x/2; // lower right coord[3].y = size.y/2; FlashPadTrapez( pos, coord, orient, trace_mode ); } break; } }
int gr_hline(int x1, int x2, int y) { int i; if (x1 > x2) EXCHG(x1,x2); for (i=x1; i<=x2; i++ ) gr_upixel( i, y ); return 0; }
int gr_hline(int x1, int x2, int y) { int i; int t; if (x1 > x2) EXCHG(x1, x2); t = ROWSIZE * y; for (i = x1; i <= x2; i++) { // gr_upixel( i, y ); DATA[t + i] = COLOR; } return 0; }
bool LIB_TEXT::HitTest( wxPoint aPosition, int aThreshold, const TRANSFORM& aTransform ) { if( aThreshold < 0 ) aThreshold = 0; wxPoint physicalpos = aTransform.TransformCoordinate( m_Pos ); wxPoint tmp = m_Pos; m_Pos = physicalpos; /* The text orientation may need to be flipped if the * transformation matrix causes xy axes to be flipped. * this simple algo works only for schematic matrix (rot 90 or/and mirror) */ int t1 = ( aTransform.x1 != 0 ) ^ ( m_Orient != 0 ); int orient = t1 ? TEXT_ORIENT_HORIZ : TEXT_ORIENT_VERT; EXCHG( m_Orient, orient ); bool hit = TextHitTest( aPosition ); EXCHG( m_Orient, orient ); m_Pos = tmp; return hit; }
void SCH_SHEET::SwapData( SCH_ITEM* aItem ) { wxCHECK_RET( aItem->Type() == SCH_SHEET_T, wxString::Format( wxT( "SCH_SHEET object cannot swap data with %s object." ), GetChars( aItem->GetClass() ) ) ); SCH_SHEET* sheet = ( SCH_SHEET* ) aItem; EXCHG( m_pos, sheet->m_pos ); EXCHG( m_size, sheet->m_size ); EXCHG( m_name, sheet->m_name ); EXCHG( m_sheetNameSize, sheet->m_sheetNameSize ); EXCHG( m_fileNameSize, sheet->m_fileNameSize ); m_pins.swap( sheet->m_pins ); // Ensure sheet labels have their .m_Parent member pointing really on their // parent, after swapping. BOOST_FOREACH( SCH_SHEET_PIN& sheetPin, m_pins ) { sheetPin.SetParent( this ); }
// Rotate selected pad 90 degrees. void PCB_BASE_FRAME::RotatePad( D_PAD* aPad, wxDC* DC ) { if( aPad == NULL ) return; MODULE* module = aPad->GetParent(); module->SetLastEditTime(); OnModify(); if( DC ) module->Draw( m_canvas, DC, GR_XOR ); wxSize sz = aPad->GetSize(); EXCHG( sz.x, sz.y ); aPad->SetSize( sz ); sz = aPad->GetDrillSize(); EXCHG( sz.x, sz.y ); aPad->SetDrillSize( sz ); wxPoint pt = aPad->GetOffset(); EXCHG( pt.x, pt.y ); aPad->SetOffset( pt ); aPad->SetOffset( wxPoint( aPad->GetOffset().x, -aPad->GetOffset().y ) ); sz = aPad->GetDelta(); EXCHG( sz.x, sz.y ); sz.x = -sz.x; aPad->SetDelta( sz ); module->CalculateBoundingBox(); SetMsgPanel( aPad ); if( DC ) module->Draw( m_canvas, DC, GR_OR ); }
void LIB_ARC::MirrorHorizontal( const wxPoint& aCenter ) { m_Pos.x -= aCenter.x; m_Pos.x *= -1; m_Pos.x += aCenter.x; m_ArcStart.x -= aCenter.x; m_ArcStart.x *= -1; m_ArcStart.x += aCenter.x; m_ArcEnd.x -= aCenter.x; m_ArcEnd.x *= -1; m_ArcEnd.x += aCenter.x; EXCHG( m_ArcStart, m_ArcEnd ); }
void LIB_ARC::MirrorVertical( const wxPoint& aCenter ) { m_Pos.y -= aCenter.y; m_Pos.y *= -1; m_Pos.y += aCenter.y; m_ArcStart.y -= aCenter.y; m_ArcStart.y *= -1; m_ArcStart.y += aCenter.y; m_ArcEnd.y -= aCenter.y; m_ArcEnd.y *= -1; m_ArcEnd.y += aCenter.y; EXCHG( m_ArcStart, m_ArcEnd ); }
/** * Function used by TestForActiveLinksInRatsnest * Function testing the ratsnest between 2 blocks ( of the same net ) * The search is made between pads in block 1 and the others blocks * The block n ( n > 1 ) is merged with block 1 and linked by the smallest ratsnest * between block 1 and the block n (activate the logical connection) * @param aRatsnestBuffer = the buffer to store NETINFO_ITEM* items * @param aNetinfo = the current NETINFO_ITEM for the current net * output: .state member, bit CH_ACTIF of the ratsnest item * @return last subratsnest id in use */ static int tst_links_between_blocks( NETINFO_ITEM* aNetinfo, std::vector<RATSNEST_ITEM>& aRatsnestBuffer ) { int subratsnest_id, min_id; RATSNEST_ITEM* link, * best_link; // Search a link from a block to an other block best_link = NULL; for( unsigned ii = aNetinfo->m_RatsnestStartIdx; ii < aNetinfo->m_RatsnestEndIdx; ii++ ) { link = &aRatsnestBuffer[ii]; // If this link joints 2 pads inside the same block, do nothing // (these pads are already connected) if( link->m_PadStart->GetSubRatsnest() == link->m_PadEnd->GetSubRatsnest() ) continue; // This link joints 2 pads of different blocks: this is a candidate, // but we want to select the shorter link, so use it only if it is shorter // than the previous candidate: if( best_link == NULL ) // no candidate best_link = link; else if( best_link->m_Lenght > link->m_Lenght ) // It is a better candidate. best_link = link; } if( best_link == NULL ) return 1; /* At this point we have found a link between 2 different blocks (subratsnest) * we must set its status to ACTIVE and merge the 2 blocks */ best_link->m_Status |= CH_ACTIF; subratsnest_id = best_link->m_PadStart->GetSubRatsnest(); min_id = best_link->m_PadEnd->GetSubRatsnest(); if( min_id > subratsnest_id ) EXCHG( min_id, subratsnest_id ); // Merge the 2 blocks in one sub ratsnest: for( unsigned ii = 0; ii < aNetinfo->m_PadInNetList.size(); ii++ ) { if( aNetinfo->m_PadInNetList[ii]->GetSubRatsnest() == subratsnest_id ) { aNetinfo->m_PadInNetList[ii]->SetSubRatsnest( min_id ); } } return subratsnest_id; }
double compute_Ratsnest_PlaceModule( BOARD* aBrd ) { double curr_cost; wxPoint start; // start point of a ratsnest wxPoint end; // end point of a ratsnest int dx, dy; if( ( aBrd->m_Status_Pcb & RATSNEST_ITEM_LOCAL_OK ) == 0 ) return -1; curr_cost = 0; for( unsigned ii = 0; ii < aBrd->m_LocalRatsnest.size(); ii++ ) { RATSNEST_ITEM* pt_local_rats_nest = &aBrd->m_LocalRatsnest[ii]; if( ( pt_local_rats_nest->m_Status & LOCAL_RATSNEST_ITEM ) ) continue; // Skip ratsnest between 2 pads of the current module // Skip modules not inside the board area MODULE* module = pt_local_rats_nest->m_PadEnd->GetParent(); if( !RoutingMatrix.m_BrdBox.Contains( module->GetPosition() ) ) continue; start = pt_local_rats_nest->m_PadStart->GetPosition() - g_Offset_Module; end = pt_local_rats_nest->m_PadEnd->GetPosition(); // Cost of the ratsnest. dx = end.x - start.x; dy = end.y - start.y; dx = abs( dx ); dy = abs( dy ); // ttry to have always dx >= dy to calculate the cost of the rastsnet if( dx < dy ) EXCHG( dx, dy ); // Cost of the connection = lenght + penalty due to the slope // dx is the biggest lenght relative to the X or Y axis // the penalty is max for 45 degrees ratsnests, // and 0 for horizontal or vertical ratsnests. // For Horizontal and Vertical ratsnests, dy = 0; double conn_cost = hypot( dx, dy * 2.0 ); curr_cost += conn_cost; // Total cost = sum of costs of each connection } return curr_cost; }
void VIA::SetLayerPair( LAYER_NUM aTopLayer, LAYER_NUM aBottomLayer ) { if( GetViaType() == VIA_THROUGH ) { aTopLayer = LAYER_N_FRONT; aBottomLayer = LAYER_N_BACK; } if( aBottomLayer > aTopLayer ) EXCHG( aBottomLayer, aTopLayer ); m_Layer = aTopLayer; m_BottomLayer = aBottomLayer; }