void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly ) { if( GetBoard()->m_Modules == NULL ) { DisplayInfoMessage( this, FMT_NO_MODULES ); return; } PROJECT& prj = Prj(); SEARCH_STACK& search = Kiface().KifaceSearch(); wxString last_nickname = prj.RPath(PROJECT::PCB_LIB).LastVisitedPath( search ); wxString nickname = SelectLibrary( last_nickname ); if( !nickname ) return; prj.RPath(PROJECT::PCB_LIB).SaveLastVisitedPath( nickname ); if( !aNewModulesOnly ) { wxString msg = wxString::Format( FMT_OK_OVERWRITE, GetChars( nickname ) ); if( !IsOK( this, msg ) ) return; } m_canvas->SetAbortRequest( false ); try { // Delete old library if we're replacing it entirely. if( !aNewModulesOnly ) { FootprintLibs()->FootprintLibDelete( nickname ); FootprintLibs()->FootprintLibCreate( nickname ); for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) { FootprintLibs()->FootprintSave( nickname, m, true ); } } else { for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() ) { FootprintLibs()->FootprintSave( nickname, m, false ); // Check for request to stop backup (ESCAPE key actuated) if( m_canvas->GetAbortRequest() ) break; } } } catch( const IO_ERROR& ioe ) { DisplayError( this, ioe.errorText ); } }
MODULE* FOOTPRINT_EDIT_FRAME::SelectFootprint( BOARD* aPcb ) { static wxString oldName; // Save name of last module selected. wxString fpname; wxString msg; wxArrayString listnames; MODULE* module = aPcb->m_Modules; for( ; module; module = module->Next() ) listnames.Add( module->GetReference() ); msg.Printf( _( "Modules [%d items]" ), listnames.GetCount() ); wxArrayString headers; headers.Add( _( "Module" ) ); std::vector<wxArrayString> itemsToDisplay; // Conversion from wxArrayString to vector of ArrayString for( unsigned i = 0; i < listnames.GetCount(); i++ ) { wxArrayString item; item.Add( listnames[i] ); itemsToDisplay.push_back( item ); } EDA_LIST_DIALOG dlg( this, msg, headers, itemsToDisplay, wxEmptyString, NULL, SORT_LIST ); if( dlg.ShowModal() == wxID_OK ) fpname = dlg.GetTextSelection(); else return NULL; oldName = fpname; module = aPcb->m_Modules; for( ; module; module = module->Next() ) { if( fpname == module->GetReference() ) break; } return module; }
/* * Creates a footprint position file * aSide = 0 -> Back (bottom) side) * aSide = 1 -> Front (top) side) * aSide = 2 -> both sides * if aFullFileName is empty, the file is not created, only the * count of footprints to place is returned */ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, bool aForceSmdItems, int aSide ) { MODULE* module; char line[1024]; File_Place_Offset = GetAuxOrigin(); // Calculating the number of useful modules (CMS attribute, not VIRTUAL) int moduleCount = 0; for( module = GetBoard()->m_Modules; module; module = module->Next() ) { if( aSide < 2 ) { if( module->GetLayer() == B_Cu && aSide == 1) continue; if( module->GetLayer() == F_Cu && aSide == 0) continue; } if( module->GetAttributes() & MOD_VIRTUAL ) { DBG( printf( "skipping module %s because it's virtual\n", TO_UTF8( module->GetReference() ) );) continue; }
bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName ) { FILE* cmpFile; cmpFile = wxFopen( aFullCmpFileName, wxT( "wt" ) ); if( cmpFile == NULL ) return false; fprintf( cmpFile, "Cmp-Mod V01 Created by PcbNew date = %s\n", TO_UTF8( DateAndTime() ) ); MODULE* module = aBrd->m_Modules; for( ; module != NULL; module = module->Next() ) { fprintf( cmpFile, "\nBeginCmp\n" ); fprintf( cmpFile, "TimeStamp = %8.8lX\n", (unsigned long)module->GetTimeStamp() ); fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) ); fprintf( cmpFile, "Reference = %s;\n", !module->GetReference().IsEmpty() ? TO_UTF8( module->GetReference() ) : "[NoRef]" ); fprintf( cmpFile, "ValeurCmp = %s;\n", !module->GetValue().IsEmpty() ? TO_UTF8( module->GetValue() ) : "[NoVal]" ); fprintf( cmpFile, "IdModule = %s;\n", module->GetFPID().Format().c_str() ); fprintf( cmpFile, "EndCmp\n" ); } fprintf( cmpFile, "\nEndListe\n" ); fclose( cmpFile ); return true; }
int MODULE_TOOLS::ModuleEdgeOutlines( const TOOL_EVENT& aEvent ) { KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() ); const LAYER_ID layers[] = { F_Adhes, B_Adhes, F_Paste, B_Paste, F_SilkS, B_SilkS, F_Mask, B_Mask, Dwgs_User, Cmts_User, Eco1_User, Eco2_User, Edge_Cuts }; bool enable = !settings->GetSketchMode( layers[0] ); for( LAYER_NUM layer : layers ) settings->SetSketchMode( layer, enable ); for( MODULE* module = getModel<BOARD>()->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item ->Next() ) { if( item->Type() == PCB_MODULE_EDGE_T ) getView()->Update( item, KIGFX::GEOMETRY ); } } m_frame->GetGalCanvas()->Refresh(); return 0; }
int MODULE_TOOLS::ModuleTextOutlines( const TOOL_EVENT& aEvent ) { KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() ); const LAYER_NUM layers[] = { ITEM_GAL_LAYER( MOD_TEXT_BK_VISIBLE ), ITEM_GAL_LAYER( MOD_TEXT_FR_VISIBLE ), ITEM_GAL_LAYER( MOD_TEXT_INVISIBLE ), ITEM_GAL_LAYER( MOD_REFERENCES_VISIBLE ), ITEM_GAL_LAYER( MOD_VALUES_VISIBLE ) }; bool enable = !settings->GetSketchMode( layers[0] ); for( LAYER_NUM layer : layers ) settings->SetSketchMode( layer, enable ); for( MODULE* module = getModel<BOARD>()->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item ->Next() ) { if( item->Type() == PCB_MODULE_TEXT_T ) getView()->Update( item, KIGFX::GEOMETRY ); } getView()->Update( &module->Reference(), KIGFX::GEOMETRY ); getView()->Update( &module->Value(), KIGFX::GEOMETRY ); } m_frame->GetGalCanvas()->Refresh(); return 0; }
void FOOTPRINT_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg ) { PCB_SCREEN* screen = GetScreen(); if( !GetBoard() || !screen ) return; GRSetDrawMode( DC, GR_COPY ); m_canvas->DrawBackGround( DC ); DrawWorkSheet( DC, screen, 0, IU_PER_MILS, wxEmptyString ); // Redraw the footprints for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) module->Draw( m_canvas, DC, GR_OR | GR_ALLOW_HIGHCONTRAST ); #ifdef USE_WX_OVERLAY if( IsShown() ) { m_overlay.Reset(); wxDCOverlay overlaydc( m_overlay, (wxWindowDC*) DC ); overlaydc.Clear(); } #endif if( m_canvas->IsMouseCaptured() ) m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // Redraw the cursor m_canvas->DrawCrossHair( DC ); }
/* Creates the section $DEVICES * This is a list of footprints properties * ( Shapes are in section $SHAPE ) */ static void CreateDevicesSection( FILE* aFile, BOARD* aPcb ) { MODULE* module; fputs( "$DEVICES\n", aFile ); for( module = aPcb->m_Modules; module; module = module->Next() ) { fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) ); fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) ); fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() ); // The TYPE attribute is almost freeform const char* ty = "TH"; if( module->GetAttributes() & MOD_CMS ) ty = "SMD"; if( module->GetAttributes() & MOD_VIRTUAL ) ty = "VIRTUAL"; fprintf( aFile, "TYPE %s\n", ty ); } fputs( "$ENDDEVICES\n\n", aFile ); }
void PCB_BASE_FRAME::OnTogglePadDrawMode( wxCommandEvent& aEvent ) { DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions(); displ_opts->m_DisplayPadFill = !displ_opts->m_DisplayPadFill; EDA_DRAW_PANEL_GAL* gal = GetGalCanvas(); if( gal ) { // Apply new display options to the GAL canvas KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*> ( gal->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*> ( painter->GetSettings() ); settings->LoadDisplayOptions( displ_opts ); // Update pads BOARD* board = GetBoard(); for( MODULE* module = board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } m_canvas->Refresh(); }
void FOOTPRINT_EDIT_FRAME::PrintPage( wxDC* aDC, LSET aPrintMaskLayer, bool aPrintMirrorMode, void * aData) { const GR_DRAWMODE drawmode = (GR_DRAWMODE) 0; int defaultPenSize = Millimeter2iu( 0.2 ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions(); DISPLAY_OPTIONS save_opt; PRINT_PARAMETERS * printParameters = (PRINT_PARAMETERS*) aData; // can be null PRINT_PARAMETERS::DrillShapeOptT drillShapeOpt = PRINT_PARAMETERS::FULL_DRILL_SHAPE; if( printParameters ) defaultPenSize = printParameters->m_PenDefaultSize; save_opt = *displ_opts; displ_opts->m_ContrastModeDisplay = false; displ_opts->m_DisplayPadFill = true; displ_opts->m_DisplayViaFill = true; displ_opts->m_DisplayPadNum = false; bool nctmp = GetBoard()->IsElementVisible(NO_CONNECTS_VISIBLE); GetBoard()->SetElementVisibility(NO_CONNECTS_VISIBLE, false); displ_opts->m_DisplayPadIsol = false; displ_opts->m_DisplayModEdgeFill = FILLED; displ_opts->m_DisplayModTextFill = FILLED; displ_opts->m_DisplayPcbTrackFill = true; displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE; displ_opts->m_DisplayDrawItemsFill = FILLED; displ_opts->m_DisplayZonesMode = 0; displ_opts->m_DisplayNetNamesMode = 0; m_canvas->SetPrintMirrored( aPrintMirrorMode ); // Draw footprints, this is done at last in order to print the pad holes in // white after the tracks and zones int tmp = D_PAD::m_PadSketchModePenSize; D_PAD::m_PadSketchModePenSize = defaultPenSize; wxSize pageSizeIU = GetPageSizeIU() / 2; wxPoint offset( pageSizeIU.x, pageSizeIU.y ); for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) { module->Move( offset ); Print_Module( m_canvas, aDC, module, drawmode, aPrintMaskLayer, drillShapeOpt ); module->Move( -offset ); } D_PAD::m_PadSketchModePenSize = tmp; m_canvas->SetPrintMirrored( false ); *displ_opts = save_opt; GetBoard()->SetElementVisibility( NO_CONNECTS_VISIBLE, nctmp ); }
PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER* aRouter ) : m_router( aRouter ), m_board( aBoard ) { PNS::NODE* world = m_router->GetWorld(); PNS::TOPOLOGY topo( world ); m_netClearanceCache.resize( m_board->GetNetCount() ); // Build clearance cache for net classes for( unsigned int i = 0; i < m_board->GetNetCount(); i++ ) { NETINFO_ITEM* ni = m_board->FindNet( i ); if( ni == NULL ) continue; CLEARANCE_ENT ent; ent.coupledNet = DpCoupledNet( i ); wxString netClassName = ni->GetClassName(); NETCLASSPTR nc = m_board->GetDesignSettings().m_NetClasses.Find( netClassName ); int clearance = nc->GetClearance(); ent.clearance = clearance; m_netClearanceCache[i] = ent; wxLogTrace( "PNS", "Add net %u netclass %s clearance %d", i, netClassName.mb_str(), clearance ); } // Build clearance cache for pads for( MODULE* mod = m_board->m_Modules; mod ; mod = mod->Next() ) { auto moduleClearance = mod->GetLocalClearance(); for( D_PAD* pad = mod->PadsList(); pad; pad = pad->Next() ) { int padClearance = pad->GetLocalClearance(); if( padClearance > 0 ) m_localClearanceCache[ pad ] = padClearance; else if( moduleClearance > 0 ) m_localClearanceCache[ pad ] = moduleClearance; } } //printf("DefaultCL : %d\n", m_board->GetDesignSettings().m_NetClasses.Find ("Default clearance")->GetClearance()); m_overrideEnabled = false; m_defaultClearance = Millimeter2iu( 0.254 ); // m_board->m_NetClasses.Find ("Default clearance")->GetClearance(); m_overrideNetA = 0; m_overrideNetB = 0; m_overrideClearance = 0; m_useDpGap = false; }
/* Creates the footprint shape list. * Since module shape is customizable after the placement we cannot share them; * instead we opt for the one-module-one-shape-one-component-one-device approach */ static void CreateShapesSection( FILE* aFile, BOARD* aPcb ) { MODULE* module; D_PAD* pad; const char* layer; wxString pinname; const char* mirror = "0"; fputs( "$SHAPES\n", aFile ); const LSET all_cu = LSET::AllCuMask(); for( module = aPcb->m_Modules; module; module = module->Next() ) { FootprintWriteShape( aFile, module ); for( pad = module->Pads(); pad; pad = pad->Next() ) { /* Funny thing: GenCAD requires the pad side even if you use * padstacks (which are theorically optional but gerbtools *requires* them). Now the trouble thing is that 'BOTTOM' * is interpreted by someone as a padstack flip even * if the spec explicitly says it's not... */ layer = "ALL"; if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) ) { layer = module->GetFlag() ? "TOP" : "BOTTOM"; } else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) ) { layer = module->GetFlag() ? "BOTTOM" : "TOP"; } pad->StringPadName( pinname ); if( pinname.IsEmpty() ) pinname = wxT( "none" ); double orient = pad->GetOrientation() - module->GetOrientation(); NORMALIZE_ANGLE_POS( orient ); // Bottom side modules use the flipped padstack fprintf( aFile, (module->GetFlag()) ? "PIN %s PAD%dF %g %g %s %g %s\n" : "PIN %s PAD%d %g %g %s %g %s\n", TO_UTF8( pinname ), pad->GetSubRatsnest(), pad->GetPos0().x / SCALE_FACTOR, -pad->GetPos0().y / SCALE_FACTOR, layer, orient / 10.0, mirror ); } } fputs( "$ENDSHAPES\n\n", aFile ); }
MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName() { if( GetBoard()->m_Modules == NULL ) { DisplayError( this, _( "No footprints" ) ); return 0; } wxArrayString listnames; MODULE* module; for( module = GetBoard()->m_Modules; module; module = module->Next() ) listnames.Add( module->GetReference() ); wxArrayString headers; headers.Add( wxT( "Module" ) ); std::vector<wxArrayString> itemsToDisplay; // Conversion from wxArrayString to vector of ArrayString for( unsigned i = 0; i < listnames.GetCount(); i++ ) { wxArrayString item; item.Add( listnames[i] ); itemsToDisplay.push_back( item ); } EDA_LIST_DIALOG dlg( this, _( "Components" ), headers, itemsToDisplay, wxEmptyString ); if( dlg.ShowModal() != wxID_OK ) return NULL; wxString ref = dlg.GetTextSelection(); for( module = GetBoard()->m_Modules; module; module = module->Next() ) { if( module->GetReference() == ref ) break; } return module; }
void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard ) { m_view->Clear(); // Load zones for( int i = 0; i < aBoard->GetAreaCount(); ++i ) m_view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) ); // Load drawings for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() ) m_view->Add( drawing ); // Load tracks for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) m_view->Add( track ); // Load modules and its additional elements for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, m_view, _1 ) ); m_view->Add( module ); } // Segzones (equivalent of ZONE_CONTAINER for legacy boards) for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() ) m_view->Add( zone ); // Ratsnest if( m_ratsnest ) { m_view->Remove( m_ratsnest ); delete m_ratsnest; } m_ratsnest = new KIGFX::RATSNEST_VIEWITEM( aBoard->GetRatsnest() ); m_view->Add( m_ratsnest ); // Display settings UseColorScheme( aBoard->GetColorsSettings() ); PCB_BASE_FRAME* frame = dynamic_cast<PCB_BASE_FRAME*>( GetParent() ); if( frame ) { SetTopLayer( frame->GetActiveLayer() ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*) frame->GetDisplayOptions(); static_cast<KIGFX::PCB_RENDER_SETTINGS*>( m_view->GetPainter()->GetSettings() )->LoadDisplayOptions( displ_opts ); } m_view->RecacheAllItems( true ); }
void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aOutlines ) { // convert tracks and vias: for( TRACK* track = m_Track; track != NULL; track = track->Next() ) { if( !track->IsOnLayer( aLayer ) ) continue; track->TransformShapeWithClearanceToPolygon( aOutlines, 0 ); } // convert pads for( MODULE* module = m_Modules; module != NULL; module = module->Next() ) { module->TransformPadsShapesWithClearanceToPolygon( aLayer, aOutlines, 0 ); // Micro-wave modules may have items on copper layers module->TransformGraphicShapesWithClearanceToPolygonSet( aLayer, aOutlines, 0 ); } // convert copper zones for( int ii = 0; ii < GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = GetArea( ii ); PCB_LAYER_ID zonelayer = zone->GetLayer(); if( zonelayer == aLayer ) zone->TransformSolidAreasShapesToPolygonSet( aOutlines ); } // convert graphic items on copper layers (texts) for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() ) { if( !item->IsOnLayer( aLayer ) ) continue; switch( item->Type() ) { case PCB_LINE_T: ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( aOutlines, 0 ); break; case PCB_TEXT_T: ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( aOutlines, 0 ); break; default: break; } } }
/* Extract the D356 record from the modules (pads) */ static void build_pad_testpoints( BOARD *aPcb, std::vector <D356_RECORD>& aRecords ) { wxPoint origin = aPcb->GetAuxOrigin(); for( MODULE *module = aPcb->m_Modules; module; module = module->Next() ) { for( D_PAD *pad = module->Pads(); pad; pad = pad->Next() ) { D356_RECORD rk; rk.access = compute_pad_access_code( aPcb, pad->GetLayerSet() ); // It could be a mask only pad, we only handle pads with copper here if( rk.access != -1 ) { rk.netname = pad->GetNetname(); rk.refdes = module->GetReference(); pad->StringPadName( rk.pin ); rk.midpoint = false; // XXX MAYBE need to be computed (how?) const wxSize& drill = pad->GetDrillSize(); rk.drill = std::min( drill.x, drill.y ); rk.hole = (rk.drill != 0); rk.smd = pad->GetAttribute() == PAD_ATTRIB_SMD; rk.mechanical = (pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED); rk.x_location = pad->GetPosition().x - origin.x; rk.y_location = origin.y - pad->GetPosition().y; rk.x_size = pad->GetSize().x; // Rule: round pads have y = 0 if( pad->GetShape() == PAD_SHAPE_CIRCLE ) rk.y_size = 0; else rk.y_size = pad->GetSize().y; rk.rotation = -KiROUND( pad->GetOrientation() ) / 10; if( rk.rotation < 0 ) rk.rotation += 360; // the value indicates which sides are *not* accessible rk.soldermask = 3; if( pad->GetLayerSet()[F_Mask] ) rk.soldermask &= ~1; if( pad->GetLayerSet()[B_Mask] ) rk.soldermask &= ~2; aRecords.push_back( rk ); } } } }
/* Emit the netlist (which is actually the thing for which GenCAD is used these * days!); tracks are handled later */ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) { wxString msg; NETINFO_ITEM* net; D_PAD* pad; MODULE* module; int NbNoConn = 1; fputs( "$SIGNALS\n", aFile ); for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ ) { net = aPcb->FindNet( ii ); if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection) { wxString msg; msg << wxT( "NoConnection" ) << NbNoConn++; } if( net->GetNet() <= 0 ) // dummy netlist (no connection) continue; msg = wxT( "SIGNAL " ) + net->GetNetname(); fputs( TO_UTF8( msg ), aFile ); fputs( "\n", aFile ); for( module = aPcb->m_Modules; module; module = module->Next() ) { for( pad = module->Pads(); pad; pad = pad->Next() ) { wxString padname; if( pad->GetNetCode() != net->GetNet() ) continue; pad->StringPadName( padname ); msg.Printf( wxT( "NODE %s %s" ), GetChars( module->GetReference() ), GetChars( padname ) ); fputs( TO_UTF8( msg ), aFile ); fputs( "\n", aFile ); } } } fputs( "$ENDSIGNALS\n\n", aFile ); }
// Plot footprints graphic items (outlines) void BRDITEMS_PLOTTER::Plot_Edges_Modules() { for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() ) { EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item ); if( !edge || !m_layerMask[edge->GetLayer()] ) continue; Plot_1_EdgeModule( edge ); } } }
void BRDITEMS_PLOTTER::PlotDrillMarks() { /* If small drills marks were requested prepare a clamp value to pass to the helper function */ int small_drill = (GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE) ? SMALL_DRILL : 0; /* In the filled trace mode drill marks are drawn white-on-black to scrape the underlying pad. This works only for drivers supporting color change, obviously... it means that: - PS, SVG and PDF output is correct (i.e. you have a 'donut' pad) - In HPGL you can't see them - In gerbers you can't see them, too. This is arguably the right thing to do since having drill marks and high speed drill stations is a sure recipe for broken tools and angry manufacturers. If you *really* want them you could start a layer with negative polarity to scrape the film. - In DXF they go into the 'WHITE' layer. This could be useful. */ if( GetMode() == FILLED ) m_plotter->SetColor( WHITE ); for( TRACK *pts = m_board->m_Track; pts != NULL; pts = pts->Next() ) { const VIA* via = dyn_cast<const VIA*>( pts ); if( via ) plotOneDrillMark( PAD_DRILL_CIRCLE, via->GetStart(), wxSize( via->GetDrillValue(), 0 ), wxSize( via->GetWidth(), 0 ), 0, small_drill ); } for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() ) { for( D_PAD *pad = Module->Pads(); pad != NULL; pad = pad->Next() ) { if( pad->GetDrillSize().x == 0 ) continue; plotOneDrillMark( pad->GetDrillShape(), pad->GetPosition(), pad->GetDrillSize(), pad->GetSize(), pad->GetOrientation(), small_drill ); } } if( GetMode() == FILLED ) m_plotter->SetColor( GetColor() ); }
void PCB_EDIT_FRAME::OnResetModuleTextSizes( wxCommandEvent& event ) { DIALOG_GLOBAL_MODULES_FIELDS_EDITION dlg(this); dlg.ShowModal(); if( IsGalCanvasActive() ) { for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) { module->Value().ViewUpdate(); module->Reference().ViewUpdate(); } } m_canvas->Refresh(); }
void PNS_ROUTER::SyncWorld() { if( !m_board ) { TRACEn( 0, "No board attached, aborting sync." ); return; } ClearWorld(); m_world = new PNS_NODE(); for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { PNS_ITEM* solid = syncPad( pad ); if( solid ) m_world->Add( solid ); } } for( TRACK* t = m_board->m_Track; t; t = t->Next() ) { KICAD_T type = t->Type(); PNS_ITEM* item = NULL; if( type == PCB_TRACE_T ) item = syncTrack( t ); else if( type == PCB_VIA_T ) item = syncVia( static_cast<VIA*>( t ) ); if( item ) m_world->Add( item ); } // TODO: Create resolvers in ctor, call resolver->SetBoard() in this->SetBoard() and delete it in dtor // TBD: Same remark as with m_sizes.SetMinimumTrackWidth in startRouting() int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue(); m_clearanceResolver = new PNS_PCBNEW_CLEARANCE_RESOLVER( this ); m_world->SetClearanceResolver( m_clearanceResolver ); m_world->SetMaxClearance( 4 * worstClearance ); m_pairingResolver = new PCBNEW_PAIRING_RESOLVER( m_board ); m_world->SetPairingResolver( m_pairingResolver ); }
void PNS_KICAD_IFACE::SyncWorld( PNS::NODE *aWorld ) { if( !m_board ) { wxLogTrace( "PNS", "No board attached, aborting sync." ); return; } for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { std::unique_ptr< PNS::SOLID > solid = syncPad( pad ); if( solid ) aWorld->Add( std::move( solid ) ); } } for( TRACK* t = m_board->m_Track; t; t = t->Next() ) { KICAD_T type = t->Type(); if( type == PCB_TRACE_T ) { std::unique_ptr< PNS::SEGMENT > segment = syncTrack( t ); if( segment ) { aWorld->Add( std::move( segment ) ); } } else if( type == PCB_VIA_T ) { std::unique_ptr< PNS::VIA > via = syncVia( static_cast<VIA*>( t ) ); if( via ) { aWorld->Add( std::move( via ) ); } } } int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue(); delete m_ruleResolver; m_ruleResolver = new PNS_PCBNEW_RULE_RESOLVER( m_board, m_router ); aWorld->SetRuleResolver( m_ruleResolver ); aWorld->SetMaxClearance( 4 * worstClearance ); }
void PNS_ROUTER::SyncWorld() { if( !m_board ) { TRACEn( 0, "No board attached, aborting sync." ); return; } ClearWorld(); m_world = new PNS_NODE(); for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { PNS_ITEM* solid = syncPad( pad ); if( solid ) m_world->Add( solid ); } } for( TRACK* t = m_board->m_Track; t; t = t->Next() ) { KICAD_T type = t->Type(); PNS_ITEM* item = NULL; if( type == PCB_TRACE_T ) item = syncTrack( t ); else if( type == PCB_VIA_T ) item = syncVia( static_cast<VIA*>( t ) ); if( item ) m_world->Add( item ); } int worstClearance = m_board->GetDesignSettings().GetBiggestClearanceValue(); m_clearanceFunc = new PNS_PCBNEW_CLEARANCE_FUNC( this ); m_world->SetClearanceFunctor( m_clearanceFunc ); m_world->SetMaxClearance( 4 * worstClearance ); }
/* * Creates a footprint position file * aSide = 0 -> Back (bottom) side) * aSide = 1 -> Front (top) side) * aSide = 2 -> both sides * if aFullFileName is empty, the file is not created, only the * count of footprints to place is returned */ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, bool aForceSmdItems, int aSide, bool aFormatCSV ) { MODULE* footprint; // Minimal text lengths: int lenRefText = 8; int lenValText = 8; int lenPkgText = 16; File_Place_Offset = GetAuxOrigin(); // Calculating the number of useful footprints (CMS attribute, not VIRTUAL) int footprintCount = 0; // Select units: double conv_unit = aUnitsMM ? conv_unit_mm : conv_unit_inch; const char *unit_text = aUnitsMM ? unit_text_mm : unit_text_inch; // Build and sort the list of footprints alphabetically std::vector<LIST_MOD> list; list.reserve( footprintCount ); for( footprint = GetBoard()->m_Modules; footprint; footprint = footprint->Next() ) { if( aSide != PCB_BOTH_SIDES ) { if( footprint->GetLayer() == B_Cu && aSide == PCB_FRONT_SIDE) continue; if( footprint->GetLayer() == F_Cu && aSide == PCB_BACK_SIDE) continue; } if( footprint->GetAttributes() & MOD_VIRTUAL ) { DBG( printf( "skipping footprint %s because it's virtual\n", TO_UTF8( footprint->GetReference() ) );) continue; }
void PCB_DRAW_PANEL_GAL::DisplayBoard( const BOARD* aBoard ) { m_view->Clear(); // Load zones for( int i = 0; i < aBoard->GetAreaCount(); ++i ) m_view->Add( (KIGFX::VIEW_ITEM*) ( aBoard->GetArea( i ) ) ); // Load drawings for( BOARD_ITEM* drawing = aBoard->m_Drawings; drawing; drawing = drawing->Next() ) m_view->Add( drawing ); // Load tracks for( TRACK* track = aBoard->m_Track; track; track = track->Next() ) m_view->Add( track ); // Load modules and its additional elements for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) { module->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, m_view, _1 ) ); m_view->Add( module ); } // Segzones (equivalent of ZONE_CONTAINER for legacy boards) for( SEGZONE* zone = aBoard->m_Zone; zone; zone = zone->Next() ) m_view->Add( zone ); // Ratsnest if( m_ratsnest ) { m_view->Remove( m_ratsnest ); delete m_ratsnest; } m_ratsnest = new KIGFX::RATSNEST_VIEWITEM( aBoard->GetRatsnest() ); m_view->Add( m_ratsnest ); UseColorScheme( aBoard->GetColorsSettings() ); m_view->RecacheAllItems( true ); }
void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode ) { GR_DRAWMODE draw_mode; if( IsHighLightNetON() ) draw_mode = GR_HIGHLIGHT | GR_OR; else draw_mode = GR_AND | GR_HIGHLIGHT; // Redraw zones for( int ii = 0; ii < GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = GetArea( ii ); if( zone->GetNetCode() == aNetCode ) { zone->Draw( am_canvas, DC, draw_mode ); } } // Redraw any pads that have aNetCode for( MODULE* module = m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->PadsList(); pad; pad = pad->Next() ) { if( pad->GetNetCode() == aNetCode ) { pad->Draw( am_canvas, DC, draw_mode ); } } } // Redraw track and vias that have aNetCode for( TRACK* seg = m_Track; seg; seg = seg->Next() ) { if( seg->GetNetCode() == aNetCode ) { seg->Draw( am_canvas, DC, draw_mode ); } } }
void BOARD::DrawHighLight( EDA_DRAW_PANEL* am_canvas, wxDC* DC, int aNetCode ) { GR_DRAWMODE draw_mode; if( IsHighLightNetON() ) draw_mode = GR_HIGHLIGHT | GR_OR; else draw_mode = GR_AND | GR_HIGHLIGHT; // Redraw ZONE_CONTAINERS BOARD::ZONE_CONTAINERS& zones = m_ZoneDescriptorList; for( BOARD::ZONE_CONTAINERS::iterator zc = zones.begin(); zc!=zones.end(); ++zc ) { if( (*zc)->GetNet() == aNetCode ) { (*zc)->Draw( am_canvas, DC, draw_mode ); } } // Redraw any pads that have aNetCode for( MODULE* module = m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { if( pad->GetNet() == aNetCode ) { pad->Draw( am_canvas, DC, draw_mode ); } } } // Redraw track and vias that have aNetCode for( TRACK* seg = m_Track; seg; seg = seg->Next() ) { if( seg->GetNet() == aNetCode ) { seg->Draw( am_canvas, DC, draw_mode ); } } }
bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist ) { wxString msg; MODULE* nextModule; const COMPONENT* component; for( MODULE* module = m_board->m_Modules; module != NULL; module = nextModule ) { nextModule = module->Next(); if( m_lookupByTimestamp ) component = aNetlist.GetComponentByTimeStamp( module->GetPath() ); else component = aNetlist.GetComponentByReference( module->GetReference() ); if( component == NULL ) { if( module->IsLocked() ) { msg.Printf( _( "Component %s is locked, skipping removal.\n" ), GetChars( module->GetReference() ) ); m_reporter->Report( msg, REPORTER::RPT_INFO ); continue; } msg.Printf( _( "Remove component %s." ), GetChars( module->GetReference() ) ); m_reporter->Report( msg, REPORTER::RPT_ACTION ); msg.Printf( _( "Removing unused component \"%s:%s\".\n" ), GetChars( module->GetReference() ), GetChars( module->GetPath() ) ); m_reporter->Report( msg, REPORTER::RPT_INFO ); if( !m_isDryRun ) m_commit.Remove( module ); } } return true; }
int PCBNEW_CONTROL::PadDisplayMode( const TOOL_EVENT& aEvent ) { KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( m_frame->GetGalCanvas()->GetView()->GetPainter() ); KIGFX::PCB_RENDER_SETTINGS* settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( painter->GetSettings() ); DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)m_frame->GetDisplayOptions(); // Apply new display options to the GAL canvas displ_opts->m_DisplayPadFill = !displ_opts->m_DisplayPadFill; settings->LoadDisplayOptions( displ_opts ); for( MODULE* module = getModel<BOARD>()->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) pad->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_frame->GetGalCanvas()->Refresh(); return 0; }
void NETINFO_MAPPING::Update() { // Collect all the used nets std::set<int> nets; // Be sure that the unconnected gets 0 and is mapped as 0 nets.insert( 0 ); // Zones for( int i = 0; i < m_board->GetAreaCount(); ++i ) nets.insert( m_board->GetArea( i )->GetNetCode() ); // Tracks for( TRACK* track = m_board->m_Track; track; track = track->Next() ) nets.insert( track->GetNetCode() ); // Modules/pads for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) { nets.insert( pad->GetNetCode() ); } } // Segzones for( SEGZONE* zone = m_board->m_Zone; zone; zone = zone->Next() ) nets.insert( zone->GetNetCode() ); // Prepare the new mapping m_netMapping.clear(); // Now the nets variable stores all the used net codes (not only for pads) and we are ready to // assign new consecutive net numbers int newNetCode = 0; for( std::set<int>::const_iterator it = nets.begin(), itEnd = nets.end(); it != itEnd; ++it ) m_netMapping[*it] = newNetCode++; }