From 962b8b0ead9bcb7e575ff9ee5630edc3a2e0ad5b Mon Sep 17 00:00:00 2001 From: charras Date: Thu, 15 Jan 2009 14:32:29 +0000 Subject: [PATCH] Added: patch from Rok Markovic, and some changes in printing functions --- CHANGELOG.txt | 11 ++ pcbnew/class_pad_draw_functions.cpp | 2 +- pcbnew/class_track.cpp | 5 +- pcbnew/print_board_functions.cpp | 51 ++++--- .../zones_convert_brd_items_to_polygons.cpp | 126 ++++++++++++++++++ share/dialog_print.cpp | 2 +- share/wxprint.cpp | 24 ++-- 7 files changed, 191 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6290885a3d..364f5e109f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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 +================================================================================ +++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 ================================================================================ ++Pcbnew: diff --git a/pcbnew/class_pad_draw_functions.cpp b/pcbnew/class_pad_draw_functions.cpp index e794ada6bd..8822753ed4 100644 --- a/pcbnew/class_pad_draw_functions.cpp +++ b/pcbnew/class_pad_draw_functions.cpp @@ -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; diff --git a/pcbnew/class_track.cpp b/pcbnew/class_track.cpp index 44f9a03e5f..50b64ddb17 100644 --- a/pcbnew/class_track.cpp +++ b/pcbnew/class_track.cpp @@ -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 diff --git a/pcbnew/print_board_functions.cpp b/pcbnew/print_board_functions.cpp index ff9084ec89..26f8d11c4a 100644 --- a/pcbnew/print_board_functions.cpp +++ b/pcbnew/print_board_functions.cpp @@ -50,8 +50,22 @@ void WinEDA_DrawPanel::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMa DisplayOpt.DisplayZonesMode = 0; 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,24 +120,6 @@ 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*/ - pt_piste = Pcb->m_Track; - int rayon = g_DesignSettings.m_ViaDrill / 2; - int color = WHITE; - bool blackpenstate = GetGRForceBlackPenState( ); - GRForceBlackPen( false ); - 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 ); - 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++ ) @@ -135,6 +131,25 @@ void WinEDA_DrawPanel::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMa 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 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 */ + { + 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 ); + if( aPrint_Sheet_Ref ) m_Parent->TraceWorkSheet( aDC, GetScreen(), g_PlotLine_Width ); diff --git a/pcbnew/zones_convert_brd_items_to_polygons.cpp b/pcbnew/zones_convert_brd_items_to_polygons.cpp index b469089b72..a2e6097025 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons.cpp @@ -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 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 ); diff --git a/share/dialog_print.cpp b/share/dialog_print.cpp index f0cd4fd427..848347d49b 100644 --- a/share/dialog_print.cpp +++ b/share/dialog_print.cpp @@ -64,7 +64,7 @@ WinEDA_PrintFrame::WinEDA_PrintFrame( WinEDA_DrawFrame* parent, wxWindowID id, c m_Config = wxGetApp().m_EDA_Config; if ( m_Config ) { - m_Config->Read(wxT("PrintPenWidth"), &g_PlotLine_Width); + m_Config->Read(OPTKEY_PLOT_LINEWIDTH_VALUE, &g_PlotLine_Width); } diff --git a/share/wxprint.cpp b/share/wxprint.cpp index cf159f2df4..05c0c28812 100644 --- a/share/wxprint.cpp +++ b/share/wxprint.cpp @@ -268,11 +268,9 @@ void WinEDA_PrintFrame::OnClosePrintDialog() /* called when WinEDA_PrintFrame is closed */ { - wxConfig* Config = wxGetApp().m_EDA_Config; - - if( Config ) + if( m_Config ) { - Config->Write( OPTKEY_PLOT_LINEWIDTH_VALUE, g_PlotLine_Width ); + m_Config->Write( OPTKEY_PLOT_LINEWIDTH_VALUE, g_PlotLine_Width ); } if( m_FineAdjustXscaleOpt ) @@ -282,16 +280,16 @@ void WinEDA_PrintFrame::OnClosePrintDialog() SetPenWidth(); #ifdef PCBNEW - if( Config ) + if( m_Config ) { - Config->Write( OPTKEY_PRINT_X_FINESCALE_ADJ, m_XScaleAdjust ); - Config->Write( OPTKEY_PRINT_Y_FINESCALE_ADJ, m_YScaleAdjust ); - Config->Write( OPTKEY_PRINT_SCALE, s_Scale_Select ); + m_Config->Write( OPTKEY_PRINT_X_FINESCALE_ADJ, m_XScaleAdjust ); + m_Config->Write( OPTKEY_PRINT_Y_FINESCALE_ADJ, m_YScaleAdjust ); + m_Config->Write( OPTKEY_PRINT_SCALE, s_Scale_Select ); wxString layerKey; for( int layer = 0; layerWrite( layerKey, m_BoxSelecLayer[layer]->IsChecked() ); + m_Config->Write( layerKey, m_BoxSelecLayer[layer]->IsChecked() ); } } #endif @@ -765,8 +763,15 @@ void EDA_Printout::DrawPage() panel->m_ClipBox.SetSize( wxSize( 0x7FFFFF0, 0x7FFFFF0 ) ); g_IsPrinting = TRUE; + int bg_color = g_DrawBgColor; #ifdef PCBNEW + + // background color can left BLACK only when drawing the full board at once, in color mode + // Switch it to WHITE in others cases + if ( s_Print_Black_and_White || ( m_PrintFrame->m_PagesOption->GetSelection() != 1 ) ) + g_DrawBgColor = WHITE; + if( m_Print_Sheet_Ref ) m_Parent->TraceWorkSheet( dc, ActiveScreen, 0 ); @@ -816,6 +821,7 @@ void EDA_Printout::DrawPage() panel->PrintPage( dc, m_Print_Sheet_Ref, s_PrintMaskLayer, s_PrintMirror ); #endif + g_DrawBgColor = bg_color; g_IsPrinting = FALSE; panel->m_ClipBox = tmp;