Commit 17dc3090 authored by charras's avatar charras
Browse files

fixed: 2 bugs that crashes pcbnew (see changelog)

parent cdbd1b29
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -5,6 +5,20 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.


2009-mar-16 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++pcbnew:
    Fixed:
        bug that crashes pcbnew when removing all footprints
        (in connection calculations, pointers to pads not reset)

        bug that crashes pcbnew when filling a zone
            if a module has a trapezoidal pad
            (trapezoidal pads are not yet implemented in zone filling,
            they are now calculated as rect shape (todo: a better handling) )


2009-mar-12 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++eeschema:
+42 −32
Original line number Diff line number Diff line
@@ -539,7 +539,6 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* aPcb, LISTE_PAD* pt_liste,
}



/**
 * Function SortPadsByXCoord
 * is used to Sort a pad list by x coordinate value.
@@ -553,7 +552,6 @@ static int SortPadsByXCoord( const void* pt_ref, const void* pt_comp )
}



/*****************************************************************************/
void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector<D_PAD*>* aVector )
/*****************************************************************************/
@@ -579,13 +577,25 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
    TRACK*              pt_next;
    int                 a_color;
    char                new_passe_request = 1, flag;

    std::vector<D_PAD*> sortedPads;
    BOARD_ITEM*         PtStruct;
    int                 masque_layer;
    wxString            msg;

    if( m_Pcb->m_Pads.size() == 0 )
    if( m_Pcb->m_Pads.size() == 0 )     // If no pad, reset pointers and netcode, and do nothing else
    {
        pt_piste = m_Pcb->m_Track;
        for( ; pt_piste != NULL; pt_piste = pt_piste->Next() )
        {
            pt_piste->start = NULL;
            pt_piste->SetState( BEGIN_ONPAD | END_ONPAD, OFF );
            pt_piste->SetNet( 0 );
            pt_piste->end = NULL;
        }

        return;
    }

    a_color = CYAN;

+13 −5
Original line number Diff line number Diff line
@@ -34,11 +34,14 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
/***********************************************************************/
{
    int        track_mask;
    bool       redraw = FALSE;
    bool       redraw = false;
    bool       gen_rastnest = false;
    wxClientDC dc( m_Parent->DrawPanel );

    m_Parent->DrawPanel->PrepareGraphicContext( &dc );

    m_Parent->SetCurItem( NULL );

    if( m_DelAlls->GetValue() )
    {
        m_Parent->Clear_Pcb( TRUE );
@@ -49,6 +52,7 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
        if( m_DelZones->GetValue() )
        {
            m_Parent->Erase_Zones( TRUE );
            gen_rastnest = true;
            redraw = TRUE;
        }

@@ -73,11 +77,11 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
        if( m_DelModules->GetValue() )
        {
            m_Parent->Erase_Modules( TRUE );
            gen_rastnest = true;
            redraw = TRUE;
        }
        
        if( m_DelTracks->GetValue() )
        {
        {
                track_mask = 0;
                if( !m_TrackFilterLocked->GetValue() )
@@ -87,7 +91,7 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )

                m_Parent->Erase_Pistes( &dc, track_mask, TRUE );
                redraw = TRUE;
            }
                gen_rastnest = true;
        }

        if( m_DelMarkers->GetValue() )
@@ -95,11 +99,14 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
            m_Parent->Erase_Marqueurs();
            redraw = TRUE;
        }

        if ( gen_rastnest )
            m_Parent->Compile_Ratsnest( &dc, true );

    }

    if( redraw )
    {
        m_Parent->SetCurItem( NULL );
        m_Parent->DrawPanel->Refresh();
    }

@@ -278,6 +285,7 @@ void WinEDA_PcbFrame::Erase_Modules( bool query )
    GetBoard()->m_NbNodes     = 0;
    GetBoard()->m_NbLinks     = 0;
    GetBoard()->m_NbNoconnect = 0;
    m_Pcb->m_Pads.clear();          // empty the pad list pointers

    GetScreen()->SetModify();
}
+7 −6
Original line number Diff line number Diff line
@@ -446,6 +446,11 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
    m_Pcb->m_NbNoconnect = 0;
    m_Pcb->m_NbLinks = 0;

    if( m_Pcb->m_Ratsnest )
        MyFree( m_Pcb->m_Ratsnest );
    m_Pcb->m_Ratsnest = NULL;


    if( m_Pcb->m_Pads.size() == 0 )
        return;

@@ -464,13 +469,9 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )

    /* Allocate memory for buffer ratsnest: there are nb_nodes - 1 ratsnest
     *  maximum ( 1 node = 1 active pad ).
     * Meory is allocated for nb_nodes ratsnests... (+ a bit more, just in case)
     * Memory is allocated for nb_nodes ratsnests... (+ a bit more, just in case)
     *  The real ratsnests count nb_links < nb_nodes
     */
    if( m_Pcb->m_Ratsnest )
        MyFree( m_Pcb->m_Ratsnest );
    m_Pcb->m_Ratsnest = NULL;

    if( m_Pcb->m_NbNodes == 0 )
        return; /* pas de connexions utiles */

+58 −21
Original line number Diff line number Diff line
@@ -110,6 +110,8 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
 */
void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
{
    bool have_poly_to_substract = false;

    // Set the number of segments in arc approximations
    if( m_ArcToSegmentsCount == 32  )
        s_CircleToSegmentsCount = 32;
@@ -149,6 +151,9 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
    CopyPolygonsFromBoolengineToFilledPolysList( booleng );
    delete booleng;

    if ( m_FilledPolysList.size() == 0 )
        return;

    /* Second, Add the main (corrected) polygon (i.e. the filled area using only one outline)
     * in GroupA in Bool_Engine to do a BOOL_A_SUB_B operation
     * All areas to remove will be put in GroupB in Bool_Engine
@@ -178,6 +183,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
     * First : Add pads. Note: pads having the same net as zone are left in zone.
     * Thermal shapes will be created later if necessary
     */
    have_poly_to_substract = false;
    for( MODULE* module = aPcb->m_Modules;  module;  module = module->Next() )
    {
        for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
@@ -189,7 +195,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
            {
                item_boundingbox = pad->GetBoundingBox();
                if( item_boundingbox.Intersects( zone_boundingbox ) )
                {
                    AddPadWithClearancePolygon( booleng, *pad, clearance );
                    have_poly_to_substract = true;
                }
                continue;
            }

@@ -197,7 +206,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
            {
                item_boundingbox = pad->GetBoundingBox();
                if( item_boundingbox.Intersects( zone_boundingbox ) )
                {
                    AddPadWithClearancePolygon( booleng, *pad, clearance );
                    have_poly_to_substract = true;
                }

            }
        }
    }
@@ -214,7 +227,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
            continue;
        item_boundingbox = track->GetBoundingBox();
        if( item_boundingbox.Intersects( zone_boundingbox ) )
        {
            AddTrackWithClearancePolygon( booleng, *track, clearance );
            have_poly_to_substract = true;
        }
     }

    // Draw graphic items (copper texts) and board edges
@@ -234,6 +250,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
                AddRingPolygon( booleng, ( (DRAWSEGMENT*) item )->m_Start,  // Circle centre
                               ( (DRAWSEGMENT*) item )->m_End, 3600,
                               ( (DRAWSEGMENT*) item )->m_Width + (2 * m_ZoneClearance) );
                have_poly_to_substract = true;
                break;

            case S_ARC:
@@ -241,6 +258,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
                                ( (DRAWSEGMENT*) item )->m_End,
                                ( (DRAWSEGMENT*) item )->m_Angle,
                               ( (DRAWSEGMENT*) item )->m_Width + (2 * m_ZoneClearance) );
                have_poly_to_substract = true;
                break;

            default:
@@ -250,6 +268,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
                                             ( (DRAWSEGMENT*) item )->m_End,
                                             ( (DRAWSEGMENT*) item )->m_Width +
                                             (2 * m_ZoneClearance) );
                have_poly_to_substract = true;
                break;
            }

@@ -259,6 +278,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
            if( ( (TEXTE_PCB*) item )->GetLength() == 0 )
                break;
            AddTextBoxWithClearancePolygon( booleng, (TEXTE_PCB*) item, m_ZoneClearance );
            have_poly_to_substract = true;
            break;

        default:
@@ -267,23 +287,32 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
    }

/* calculates copper areas */
    if ( have_poly_to_substract )
    {
        booleng->Do_Operation( BOOL_A_SUB_B );

        /* put these areas in m_FilledPolysList */
        m_FilledPolysList.clear();
        CopyPolygonsFromBoolengineToFilledPolysList( booleng );
    }
    delete booleng;

// Remove insulated islands:
    if( GetNet() > 0 )
        Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );

    // remove thermal gaps if required:
    if( m_PadOption != THERMAL_PAD || aPcb->m_Modules == NULL )
        return;

// Remove thermal symbols
    have_poly_to_substract = false;

    if( m_PadOption == THERMAL_PAD )
    {
        booleng = new Bool_Engine();
        ArmBoolEng( booleng, true );
        bool have_poly_to_substract = false;
        have_poly_to_substract = false;

        for( MODULE* module = aPcb->m_Modules;  module;  module = module->Next() )
        {
@@ -320,14 +349,12 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
            CopyPolygonsFromBoolengineToFilledPolysList( booleng );
        }
        delete booleng;
    }

        // Remove insulated islands:
        if( GetNet() > 0 )
            Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );

    if( m_PadOption != THERMAL_PAD )
        return;
    }

// Now we remove all unused thermal stubs.
//define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
@@ -348,6 +375,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
/*
 * Test and add polygons to remove thermal stubs.
 */
    have_poly_to_substract = false;
    for( MODULE* module = aPcb->m_Modules;  module;  module = module->Next() )
    {
        for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
@@ -446,6 +474,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
                            RotatePoint( &cpos, fAngle );                           // Rotate according to module orientation
                            cpos += pad->ReturnShapePos();                          // Shift origin to position
                            booleng->AddPoint( cpos.x, cpos.y );
                            have_poly_to_substract = true;
                        }

                        booleng->EndPolygonAdd();
@@ -456,16 +485,19 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
    }

/* compute copper areas */
    if ( have_poly_to_substract )
    {
        booleng->Do_Operation( BOOL_A_SUB_B );

    /* put these areas in m_FilledPolysList */
        m_FilledPolysList.clear();
        CopyPolygonsFromBoolengineToFilledPolysList( booleng );
    delete booleng;

    // Remove insulated islands, if any:
        if( GetNet() > 0 )
            Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
    }

    delete booleng;
//#endif
}

@@ -569,7 +601,12 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng,
            break;
        }

    case PAD_RECT:                                                                  // Easy implementation for rectangular cutouts with rounded corners
    case PAD_TRAPEZOID:
    default:        /* @todo: the others shapes must be calculated: see trapezoidal shape
                    * but before this is made, the rect shape is used insteed.
                    * A polygon *must* be created because we have started a polygon in kbool engine
                    */
    case PAD_RECT:          // Easy implementation for rectangular cutouts with rounded corners                                                                  // Easy implementation for rectangular cutouts with rounded corners
        angle = aPad.m_Orient;
        int rounding_radius = (int) ( aClearanceValue * s_Correction );             // Corner rounding radius
        int angle_pg;                                                               // Polygon increment angle