Commit 962b8b0e authored by charras's avatar charras
Browse files

Added: patch from Rok Markovic, and some changes in printing functions

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


2009-Jan-15 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++Pcbnew:
    Added: patch from Rok Markovic (rok@kanardia.eu) to remove unused stubs in thermal pads
    Modified: print boards when printing in color mode layers on one sheet:
        now printed in OR mode like drawings on screen
        Also in SVG mode, but OR mode seems not work inSVG mode.



2009-Jan-11 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
++Pcbnew:
+1 −1
Original line number Diff line number Diff line
@@ -328,7 +328,7 @@ void D_PAD::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
        {
            blackpenstate = GetGRForceBlackPenState();
            GRForceBlackPen( false );
            color = WHITE;
            color = g_DrawBgColor;
        }
        else
            color = BLACK; // or DARKGRAY;
+4 −1
Original line number Diff line number Diff line
@@ -629,6 +629,9 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
            m_End.x, m_End.y, m_Width, color );
    }

    if( g_IsPrinting )
        return;

    // Show clearance for tracks, not for zone segments
    if( ShowClearance( this ) )
    {
@@ -643,7 +646,7 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
     *  - only  tracks with a length > 10 * thickness are eligible
     * and, of course, if we are not printing the board
     */
    if( Type() == TYPE_ZONE || g_IsPrinting )
    if( Type() == TYPE_ZONE )
        return;

    #define THRESHOLD 10
+29 −14
Original line number Diff line number Diff line
@@ -51,7 +51,21 @@ void WinEDA_DrawPanel::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMa

    m_PrintIsMirrored = aPrintMirrorMode;
    
    if( ( g_DrawBgColor == BLACK ) && (GetGRForceBlackPenState( ) == false) )
    {   // One can use the OR mode in this case, and we draw a black background to draw board in OR mode, like on screen
        // But because black background are very expensive to draw, we draw in black only the minimun area.
        drawmode = GR_OR;

        EDA_Rect rect = frame->GetBoard()->m_BoundaryBox;
        rect.Inflate( 2000, 2000 );  // Margin in 1/10000 inch around the board to draw the black background.
        GRSetDrawMode( aDC, GR_COPY );
        // draw in black the minimum page area:
        GRFilledRect( &m_ClipBox, aDC, rect.GetX(), rect.GetY(),
            rect.GetEnd().x, rect.GetEnd().y, g_DrawBgColor, g_DrawBgColor );
    }

    /* Print the pcb graphic items (texts, ...) */
    GRSetDrawMode( aDC, drawmode );
    for( BOARD_ITEM* item = Pcb->m_Drawings;  item;  item = item->Next() )
    {
        switch( item->Type() )
@@ -106,35 +120,36 @@ void WinEDA_DrawPanel::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMa
        Print_Module( this, aDC, Module, drawmode, aPrintMaskLayer );
    }

    /* Print via holes in white color*/

    /* Draw filled areas (i.e. zones) */
    for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
    {
        ZONE_CONTAINER* zone = Pcb->GetArea(ii);
        if( ( aPrintMaskLayer & (1 << zone->GetLayer()) ) == 0 )
            continue;

        zone->DrawFilledArea( this, aDC, drawmode );
    }

    /* Print via holes in bg color: Not sure it is good for buried or blind vias */
    pt_piste = Pcb->m_Track;
    int rayon = g_DesignSettings.m_ViaDrill / 2;
    int color = WHITE;
    int color = g_DrawBgColor;
    bool blackpenstate = GetGRForceBlackPenState( );
    GRForceBlackPen( false );
    GRSetDrawMode( aDC, GR_COPY );
    for( ; pt_piste != NULL; pt_piste = pt_piste->Next() )
    {
        if( ( aPrintMaskLayer & pt_piste->ReturnMaskLayer() ) == 0 )
            continue;
        if( pt_piste->Type() == TYPE_VIA ) /* VIA rencontree */
        {
            GRSetDrawMode( aDC, drawmode );
            int rayon = g_DesignSettings.m_ViaDrill / 2;
            GRFilledCircle( &m_ClipBox, aDC, pt_piste->m_Start.x, pt_piste->m_Start.y,
                            rayon, 0, color, color );
        }
    }
    GRForceBlackPen( blackpenstate );

    /* Draw filled areas (i.e. zones) */
    for( int ii = 0; ii < Pcb->GetAreaCount(); ii++ )
    {
        ZONE_CONTAINER* zone = Pcb->GetArea(ii);
        if( ( aPrintMaskLayer & (1 << zone->GetLayer()) ) == 0 )
            continue;

        zone->DrawFilledArea( this, aDC, drawmode );
    }

    if( aPrint_Sheet_Ref )
        m_Parent->TraceWorkSheet( aDC, GetScreen(), g_PlotLine_Width );

+126 −0
Original line number Diff line number Diff line
@@ -295,6 +295,132 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
        delete booleng;
    }

// Now we remove all unused thermal stubs.
#define REMOVE_UNUSED_THERMAL_STUBS     // Can be commented to skip unused thermal stubs calculations
#ifdef REMOVE_UNUSED_THERMAL_STUBS
    // first compute endindex for TestPointInsidePolygon
    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;
        }
    }

    /* 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
     */
    booleng = new Bool_Engine();
    ArmBoolEng( booleng, true );

    /* Add the main corrected polygon (i.e. the filled area using only one outline)
     * in GroupA in Bool_Engine
     */
    CopyPolygonsFromFilledPolysListToBoolengine( booleng, GROUP_A );

    /*
     * Test and add polygons to remove thermal stubs.
     */
    for( MODULE* module = aPcb->m_Modules;  module;  module = module->Next() )
    {
        for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
        {
            // check
            if( pad->IsOnLayer( GetLayer() )
                && pad->GetNet() == GetNet()
                && m_PadOption == THERMAL_PAD )
            {
                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;
                int dy = (pad->m_Size.y / 2) + m_ThermalReliefGapValue;

                // 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);

                // This is CIRCLE pad tweak (for circle pads the thermal stubs are at 45 deg)
                float fAngle = 0.0;
                if ( pad->m_PadShape == PAD_CIRCLE)
                    fAngle = 450.0;

                // Test all sides
                for (int i=0; i<4; i++) {
                    // rotate point
                    RotatePoint( &ptTest[i], pad->m_Orient + fAngle );
                    // translate point
                    ptTest[i] += pad->ReturnShapePos();
                    if ( TestPointInsidePolygon( m_FilledPolysList, indexstart,
                            indexend, ptTest[i].x, ptTest[i].y ) == 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) {
                            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 ) );
                                corners_buffer.push_back( wxPoint( -iDTRC, iDTRC ) );
                                corners_buffer.push_back( wxPoint( -iDTRC, -iDTRC ) );
                                break;
                        }
                        // add computed polygon to group_B
                        if( booleng->StartPolygonAdd( GROUP_B ) )
                        {
                            for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
                            {
                                wxPoint cpos = corners_buffer[ic];
                                RotatePoint( &cpos, pad->m_Orient + fAngle );      // Rotate according to module orientation
                                cpos += pad->ReturnShapePos();                     // Shift origin to position
                                booleng->AddPoint( cpos.x, cpos.y );
                            }

                            booleng->EndPolygonAdd();
                        }
                    }
                }
            }
        }
    }

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

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

#endif

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