示例#1
0
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 );
    }
}
示例#2
0
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;
        }
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
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 );
}
示例#11
0
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 );
}
示例#13
0
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;
        }
    }
}
示例#16
0
/* 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();
}
示例#21
0
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 );
}
示例#22
0
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 );
}
示例#23
0
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 );
}
示例#26
0
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 );
        }
    }
}
示例#27
0
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++;
}