Commit 0d3fc601 authored by charras's avatar charras
Browse files

Found why remove unused thermal stubs fails sometimes.Solved

parent 9f8e1d9d
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -5,7 +5,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.

2009-Jan-11 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
2009-Jan-17 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++pcbnew:
    Found why remove unused thermal stubs fails sometimes:
    Only the first filled area in a zone was tested.
    Solved.

2009-Jan-18 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
================================================================================
++All
  * Replace Kicad file history implementation with wxFileHistory.
+0 −11
Original line number Diff line number Diff line
@@ -48,17 +48,6 @@ enum main_id {
	ID_LOAD_PROJECT,
	ID_LOAD_ONE_SHEET,
	ID_NEW_PROJECT,
	ID_LOAD_FILE_1,
	ID_LOAD_FILE_2,
	ID_LOAD_FILE_3,
	ID_LOAD_FILE_4,
	ID_LOAD_FILE_5,
	ID_LOAD_FILE_6,
	ID_LOAD_FILE_7,
	ID_LOAD_FILE_8,
	ID_LOAD_FILE_9,
	ID_LOAD_FILE_10,

	ID_SAVE_PROJECT,
	ID_SAVE_ONE_SHEET,
	ID_SAVE_ONE_SHEET_AS,
+2 −2
Original line number Diff line number Diff line
@@ -48,9 +48,9 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
    EVT_MENU( ID_MENU_SAVE_BOARD, WinEDA_PcbFrame::Files_io )
    EVT_MENU( ID_MENU_APPEND_FILE, WinEDA_PcbFrame::Files_io )
    EVT_MENU( ID_MENU_SAVE_BOARD_AS, WinEDA_PcbFrame::Files_io )
    EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, WinEDA_PcbFrame::OnFileHistory )

    EVT_MENU( ID_GEN_PLOT, WinEDA_PcbFrame::ToPlotter )
    EVT_MENU_RANGE( ID_LOAD_FILE_1, ID_LOAD_FILE_10,
                    WinEDA_PcbFrame::Files_io )

    EVT_MENU( ID_GEN_EXPORT_SPECCTRA, WinEDA_PcbFrame::ExportToSpecctra )
    EVT_MENU( ID_GEN_EXPORT_FILE_GENCADFORMAT, WinEDA_PcbFrame::ExportToGenCAD )
+124 −87
Original line number Diff line number Diff line
@@ -295,16 +295,31 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
        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
#define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
#ifdef REMOVE_UNUSED_THERMAL_STUBS
    // first compute endindex for TestPointInsidePolygon

    /* First, Create the list of filled areas begin and end indexes.
     *  Because a zone creates more than one filled sub area,
     *  we must handle all start and end points of all sub areas
     *  for TestPointInsidePolygon, to search if a point is in a filled area in zone
     */
    std::vector <int> filled_areas_begin_end_index_list;
    unsigned int      indexstart = 0, indexend;
    for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ )
    {
        if( m_FilledPolysList[indexend].end_contour )       // end of a filled sub-area found
        {
            break;
            filled_areas_begin_end_index_list.push_back( indexstart );
            filled_areas_begin_end_index_list.push_back( indexend );
            indexstart = indexend + 1;
        }
    }

@@ -328,25 +343,21 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
        for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
        {
            // check
            if( pad->IsOnLayer( GetLayer() )
                && pad->GetNet() == GetNet()
                && m_PadOption == THERMAL_PAD )
            {
            if( !pad->IsOnLayer( GetLayer() ) )
                continue;
            if( pad->GetNet() != GetNet() )
                continue;

            item_boundingbox = pad->GetBoundingBox();
            item_boundingbox.Inflate( m_ThermalReliefGapValue, m_ThermalReliefGapValue );
            if( !( item_boundingbox.Intersects( zone_boundingbox ) ) )
                continue;

            // test point
                int dx = (pad->m_Size.x / 2) + m_ThermalReliefGapValue + 3;
                int dy = (pad->m_Size.y / 2) + m_ThermalReliefGapValue + 3;

                // compute north, south, west and east points for zone connection.
                wxPoint ptTest[4];
                ptTest[0] = wxPoint(0,  dy+m_ZoneMinThickness/2);
                ptTest[1] = wxPoint(0, -(dy+m_ZoneMinThickness/2));
                ptTest[2] = wxPoint( dx+m_ZoneMinThickness/2, 0);
                ptTest[3] = wxPoint(-(dx+m_ZoneMinThickness/2), 0);
            int dx =
                ( pad->m_Size.x / 2 ) + m_ThermalReliefGapValue;
            int dy =
                ( pad->m_Size.y / 2 ) + m_ThermalReliefGapValue;

            // This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
            int fAngle = pad->m_Orient;
@@ -357,38 +368,65 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
                fAngle = 450;
            }

            // compute north, south, west and east points for zone connection.
            // Add a small value to ensure point is inside zone, not on an edge
            wxPoint ptTest[4];
            ptTest[0] = wxPoint( 0, 3 + dy + m_ZoneMinThickness / 2 );
            ptTest[1] = wxPoint( 0, -(3 + dy + m_ZoneMinThickness / 2) );
            ptTest[2] = wxPoint( 3 + dx + m_ZoneMinThickness / 2, 0 );
            ptTest[3] = wxPoint( -(3 + dx + m_ZoneMinThickness / 2), 0 );


            // Test all sides
                for (int i=0; i<4; i++) {
            for( int i = 0; i<4; i++ )
            {
                // rotate point
                RotatePoint( &ptTest[i], fAngle );

                // translate point
                ptTest[i] += pad->ReturnShapePos();
                    if ( TestPointInsidePolygon( m_FilledPolysList, indexstart,
                            indexend, ptTest[i].x, ptTest[i].y ) == false)
                bool inside = false;
                for( unsigned idx = 0;
                     idx < filled_areas_begin_end_index_list.size() && inside == false;
                     idx += 2 )
                {
                    indexstart = filled_areas_begin_end_index_list[idx];
                    indexend   = filled_areas_begin_end_index_list[idx + 1];
                    inside     = TestPointInsidePolygon( m_FilledPolysList, indexstart,
                                                         indexend, ptTest[i].x, ptTest[i].y );
                }

                if( inside == false )
                {
                    // polygon buffer
                    std::vector<wxPoint> corners_buffer;

                    // polygons are rectangles with width of copper bridge value
                    const int            iDTRC = m_ThermalReliefCopperBridgeValue / 2;
                        switch (i) {

                    switch( i )
                    {
                    case 0:
                        corners_buffer.push_back( wxPoint( -iDTRC, dy ) );
                        corners_buffer.push_back( wxPoint( +iDTRC, dy ) );
                        corners_buffer.push_back( wxPoint( +iDTRC, iDTRC ) );
                        corners_buffer.push_back( wxPoint( -iDTRC, iDTRC ) );
                        break;

                    case 1:
                        corners_buffer.push_back( wxPoint( -iDTRC, -dy ) );
                        corners_buffer.push_back( wxPoint( +iDTRC, -dy ) );
                        corners_buffer.push_back( wxPoint( +iDTRC, -iDTRC ) );
                        corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) );
                        break;

                    case 2:
                        corners_buffer.push_back( wxPoint( dx, -iDTRC ) );
                        corners_buffer.push_back( wxPoint( dx, iDTRC ) );
                        corners_buffer.push_back( wxPoint( +iDTRC, iDTRC ) );
                        corners_buffer.push_back( wxPoint( +iDTRC, -iDTRC ) );
                        break;

                    case 3:
                        corners_buffer.push_back( wxPoint( -dx, -iDTRC ) );
                        corners_buffer.push_back( wxPoint( -dx, iDTRC ) );
@@ -396,6 +434,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
                        corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) );
                        break;
                    }

                    // add computed polygon to group_B
                    if( booleng->StartPolygonAdd( GROUP_B ) )
                    {
@@ -413,7 +452,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
            }
        }
    }
    }

    /* compute copper areas */
    booleng->Do_Operation( BOOL_A_SUB_B );
@@ -423,11 +461,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
    CopyPolygonsFromBoolengineToFilledPolysList( booleng );
    delete booleng;

#endif

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