diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index 82bda90762..b3832e72fe 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -595,9 +595,11 @@ void BOARD_ADAPTER::createArcSegments( const VECTOR2I& aCentre, const VECTOR2I& void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aContainer, const BOARD_ITEM* aOwner, PCB_LAYER_ID aLayer ) { - // The full width of the lines to create - int linewidth = aShape->GetWidth(); - int margin = 0; + LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle(); + int linewidth = aShape->GetWidth(); + int margin = 0; + bool isSolidFill = aShape->IsSolidFill(); + bool isHatchedFill = aShape->IsHatchedFill(); if( IsSolderMaskLayer( aLayer ) && aShape->HasSolderMask() @@ -605,10 +607,16 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta { margin = aShape->GetSolderMaskExpansion(); linewidth += margin * 2; + lineStyle = LINE_STYLE::SOLID; + + if( isHatchedFill ) + { + isSolidFill = true; + isHatchedFill = false; + } } - float linewidth3DU = TO_3DU( linewidth ); - LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle(); + float linewidth3DU = TO_3DU( linewidth ); if( lineStyle <= LINE_STYLE::FIRST_TYPE ) { @@ -620,7 +628,7 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta float innerR3DU = TO_3DU( aShape->GetRadius() ) - linewidth3DU / 2.0; float outerR3DU = TO_3DU( aShape->GetRadius() ) + linewidth3DU / 2.0; - if( aShape->IsSolidFill() || innerR3DU <= 0.0 ) + if( isSolidFill || innerR3DU <= 0.0 ) addFILLED_CIRCLE_2D( aContainer, center3DU, outerR3DU, *aOwner ); else addRING_2D( aContainer, center3DU, innerR3DU, outerR3DU, *aOwner ); @@ -629,7 +637,7 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta } case SHAPE_T::RECTANGLE: - if( aShape->IsSolidFill() ) + if( isSolidFill ) { SHAPE_POLY_SET polyList; @@ -733,7 +741,7 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta delete shape; } - if( aShape->IsHatchedFill() ) + if( isHatchedFill ) ConvertPolygonToTriangles( aShape->GetHatching(), *aContainer, m_biuTo3Dunits, *aOwner ); } diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index f55f95ced1..0c9d33b619 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -578,7 +578,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) addFootprintShapes( fp, layerContainer, layer, visibilityFlags ); // Add copper item to the plated copper polygon list if required - if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) ) + if( cfg.DifferentiatePlatedCopper() && IsExternalCopperLayer( layer ) ) { SHAPE_POLY_SET* layerPoly = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys; @@ -646,7 +646,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) } // Add copper item to the plated copper polygon list if required - if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) ) + if( cfg.DifferentiatePlatedCopper() && IsExternalCopperLayer( layer ) ) { SHAPE_POLY_SET* copperPolys = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys; @@ -758,7 +758,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) zones.emplace_back( std::make_pair( zone, layer ) ); layer_lock.emplace( layer, std::make_unique() ); - if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) ) + if( cfg.DifferentiatePlatedCopper() && IsExternalCopperLayer( layer ) ) { SHAPE_POLY_SET* copperPolys = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys; @@ -959,7 +959,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) continue; // Only vias on a external copper layer can have a solder mask - PCB_LAYER_ID copper_layer = layer == F_Mask ? F_Cu : B_Cu; + PCB_LAYER_ID copper_layer = ( layer == F_Mask ) ? F_Cu : B_Cu; if( track->Type() == PCB_VIA_T ) { diff --git a/pcbnew/exporters/place_file_exporter.cpp b/pcbnew/exporters/place_file_exporter.cpp index c241209fbf..7ba8dc7fd1 100644 --- a/pcbnew/exporters/place_file_exporter.cpp +++ b/pcbnew/exporters/place_file_exporter.cpp @@ -184,7 +184,7 @@ std::string PLACE_FILE_EXPORTER::GenPositionData() footprint_pos -= m_place_Offset; int layer = list[ii].m_Footprint->GetLayer(); - wxASSERT( layer == F_Cu || layer == B_Cu ); + wxASSERT( IsExternalCopperLayer( layer ) ); if( layer == B_Cu && m_negateBottomX ) footprint_pos.x = - footprint_pos.x; @@ -253,7 +253,7 @@ std::string PLACE_FILE_EXPORTER::GenPositionData() footprint_pos -= m_place_Offset; int layer = list[ii].m_Footprint->GetLayer(); - wxASSERT( layer == F_Cu || layer == B_Cu ); + wxASSERT( IsExternalCopperLayer( layer ) ); if( layer == B_Cu && m_negateBottomX ) footprint_pos.x = - footprint_pos.x; diff --git a/pcbnew/exporters/step/exporter_step.cpp b/pcbnew/exporters/step/exporter_step.cpp index 3721d015c8..c02cf0794b 100644 --- a/pcbnew/exporters/step/exporter_step.cpp +++ b/pcbnew/exporters/step/exporter_step.cpp @@ -419,23 +419,16 @@ bool EXPORTER_STEP::buildTrack3DShape( PCB_TRACK* aTrack, VECTOR2D aOrigin ) int maxError = m_board->GetDesignSettings().m_MaxError; - if( m_params.m_ExportSoldermask ) + if( m_params.m_ExportSoldermask && aTrack->IsOnLayer( F_Mask ) ) { - if( aTrack->IsOnLayer( F_Mask ) ) - { - SHAPE_POLY_SET poly; - aTrack->TransformShapeToPolygon( poly, F_Mask, 0, maxError, ERROR_INSIDE ); + aTrack->TransformShapeToPolygon( m_poly_shapes[F_Mask][wxEmptyString], F_Mask, + aTrack->GetSolderMaskExpansion(), maxError, ERROR_INSIDE ); + } - m_poly_shapes[F_Mask][wxEmptyString].Append( poly ); - } - - if( aTrack->IsOnLayer( B_Mask ) ) - { - SHAPE_POLY_SET poly; - aTrack->TransformShapeToPolygon( poly, B_Mask, 0, maxError, ERROR_INSIDE ); - - m_poly_shapes[B_Mask][wxEmptyString].Append( poly ); - } + if( m_params.m_ExportSoldermask && aTrack->IsOnLayer( B_Mask ) ) + { + aTrack->TransformShapeToPolygon( m_poly_shapes[B_Mask][wxEmptyString], B_Mask, + aTrack->GetSolderMaskExpansion(), maxError, ERROR_INSIDE ); } if( aTrack->Type() == PCB_VIA_T ) @@ -466,8 +459,7 @@ bool EXPORTER_STEP::buildTrack3DShape( PCB_TRACK* aTrack, VECTOR2D aOrigin ) m_poly_holes[pcblayer].Append( holePoly ); } - m_pcbModel->AddBarrel( *holeShape, top_layer, bot_layer, true, aOrigin, - via->GetNetname() ); + m_pcbModel->AddBarrel( *holeShape, top_layer, bot_layer, true, aOrigin, via->GetNetname() ); } //// Cut holes in silkscreen (buggy: insufficient polyset self-intersection checking) @@ -570,13 +562,12 @@ bool EXPORTER_STEP::buildGraphic3DShape( BOARD_ITEM* aItem, VECTOR2D aOrigin ) for( SHAPE* shape : shapes ) { STROKE_PARAMS::Stroke( shape, lineStyle, graphic->GetWidth(), &renderSettings, - [&]( const VECTOR2I& a, const VECTOR2I& b ) - { - SHAPE_SEGMENT seg( a, b, graphic->GetWidth() ); - seg.TransformToPolygon( - m_poly_shapes[pcblayer][graphic->GetNetname()], - maxError, ERROR_INSIDE ); - } ); + [&]( const VECTOR2I& a, const VECTOR2I& b ) + { + SHAPE_SEGMENT seg( a, b, graphic->GetWidth() ); + seg.TransformToPolygon( m_poly_shapes[pcblayer][graphic->GetNetname()], + maxError, ERROR_INSIDE ); + } ); } for( SHAPE* shape : shapes ) @@ -586,6 +577,18 @@ bool EXPORTER_STEP::buildGraphic3DShape( BOARD_ITEM* aItem, VECTOR2D aOrigin ) if( graphic->IsHatchedFill() ) m_poly_shapes[pcblayer][graphic->GetNetname()].Append( graphic->GetHatching() ); + if( m_params.m_ExportSoldermask && graphic->IsOnLayer( F_Mask ) ) + { + graphic->TransformShapeToPolygon( m_poly_shapes[F_Mask][wxEmptyString], F_Mask, + graphic->GetSolderMaskExpansion(), maxError, ERROR_INSIDE ); + } + + if( m_params.m_ExportSoldermask && graphic->IsOnLayer( B_Mask ) ) + { + graphic->TransformShapeToPolygon( m_poly_shapes[B_Mask][wxEmptyString], B_Mask, + graphic->GetSolderMaskExpansion(), maxError, ERROR_INSIDE ); + } + break; } diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp index cf884f037e..65cbaba037 100644 --- a/pcbnew/pad.cpp +++ b/pcbnew/pad.cpp @@ -402,7 +402,7 @@ bool PAD::FlashLayer( int aLayer, bool aOnlyCheckIfPermitted ) const // Plated through hole pads need copper on the top/bottom layers for proper soldering // Unless the user has removed them in the pad dialog if( mode == PADSTACK::UNCONNECTED_LAYER_MODE::REMOVE_EXCEPT_START_AND_END - && ( aLayer == F_Cu || aLayer == B_Cu ) ) + && IsExternalCopperLayer( aLayer ) ) { return true; } diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp index a72e1b7461..a3cee60b9c 100644 --- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp +++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp @@ -2499,7 +2499,7 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TRACK* aTrack ) const if( aTrack->HasSolderMask() && aTrack->GetLocalSolderMaskMargin().has_value() - && ( aTrack->IsOnLayer( F_Cu ) || aTrack->IsOnLayer( B_Cu ) ) ) + && IsExternalCopperLayer( aTrack->GetLayer() ) ) { m_out->Print( "(solder_mask_margin %s)", formatInternalUnits( aTrack->GetLocalSolderMaskMargin().value() ).c_str() ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index c97f2dfab8..7d81f41d97 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -1831,6 +1831,8 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) bool outline_mode = !viewer_settings()->m_ViewersDisplay.m_DisplayGraphicsFill; int thickness = getLineThickness( aShape->GetWidth() ); LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle(); + bool isSolidFill = aShape->IsSolidFill(); + bool isHatchedFill = aShape->IsHatchedFill(); if( lineStyle == LINE_STYLE::DEFAULT ) lineStyle = LINE_STYLE::SOLID; @@ -1841,6 +1843,12 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) { lineStyle = LINE_STYLE::SOLID; thickness += aShape->GetSolderMaskExpansion() * 2; + + if( isHatchedFill ) + { + isSolidFill = true; + isHatchedFill = false; + } } if( IsNetnameLayer( aLayer ) ) @@ -1966,7 +1974,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) m_gal->DrawSegment( pts[3], pts[0], thickness ); } - if( aShape->IsSolidFill() ) + if( isSolidFill ) { SHAPE_POLY_SET poly; poly.NewOutline(); @@ -1975,10 +1983,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) poly.Append( pt ); if( thickness < 0 ) - { - poly.Inflate( thickness / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS, - m_maxError ); - } + poly.Inflate( thickness / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS, m_maxError ); m_gal->DrawPolygon( poly ); } @@ -2027,7 +2032,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) { m_gal->DrawCircle( aShape->GetStart(), radius ); } - else if( aShape->IsSolidFill() ) + else if( isSolidFill ) { if( thickness < 0 ) { @@ -2063,7 +2068,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) m_gal->DrawSegmentChain( shape.Outline( ii ), thickness ); } - if( aShape->IsSolidFill() ) + if( isSolidFill ) { if( thickness < 0 ) { @@ -2155,7 +2160,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer ) delete shape; } - if( aShape->IsHatchedFill() ) + if( isHatchedFill ) { m_gal->SetIsStroke( false ); m_gal->SetIsFill( true ); diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index 1cd0a4c257..665828ca9b 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -2367,8 +2367,8 @@ static struct TRACK_VIA_DESC auto isExternalLayerTrack = []( INSPECTABLE* aItem ) { - if( auto track = dynamic_cast( aItem ) ) - return track->GetLayer() == F_Cu || track->GetLayer() == B_Cu; + if( PCB_TRACK* track = dynamic_cast( aItem ) ) + return IsExternalCopperLayer( track->GetLayer() ); return false; }; diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 2bfd75a654..e894c7d4db 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -874,19 +874,27 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) if( !( m_layerMask & aShape->GetLayerSet() ).any() ) return; - OUTLINE_MODE plotMode = GetPlotMode(); + OUTLINE_MODE plotMode = GetPlotMode(); int thickness = aShape->GetWidth(); - int margin = thickness; // unclamped thickness (can be negative) + int margin = thickness; // unclamped thickness (can be negative) LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle(); - bool onCopperLayer = ( LSET::AllCuMask() & m_layerMask ).any(); - bool onSolderMaskLayer = ( LSET( { F_Mask, B_Mask } ) & m_layerMask ).any(); + bool onCopperLayer = ( LSET::AllCuMask() & m_layerMask ).any(); + bool onSolderMaskLayer = ( LSET( { F_Mask, B_Mask } ) & m_layerMask ).any(); + bool isSolidFill = aShape->IsSolidFill(); + bool isHatchedFill = aShape->IsHatchedFill(); if( onSolderMaskLayer && aShape->HasSolderMask() && IsExternalCopperLayer( aShape->GetLayer() ) ) { - margin += 2 * aShape->GetSolderMaskExpansion(); + margin += 2 * aShape->GetSolderMaskExpansion(); thickness = std::max( margin, 0 ); + + if( isHatchedFill ) + { + isSolidFill = true; + isHatchedFill = false; + } } m_plotter->SetColor( getColor( aShape->GetLayer() ) ); @@ -943,7 +951,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) break; case SHAPE_T::CIRCLE: - if( aShape->IsSolidFill() ) + if( isSolidFill ) { int diameter = aShape->GetRadius() * 2 + thickness; @@ -1014,7 +1022,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) m_board->GetDesignSettings().m_MaxError ); } - FILL_T fill = aShape->IsSolidFill() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; + FILL_T fill = isSolidFill ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) { @@ -1065,7 +1073,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) m_board->GetDesignSettings().m_MaxError ); } - FILL_T fill_mode = aShape->IsSolidFill() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; + FILL_T fill_mode = isSolidFill ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; if( poly.OutlineCount() > 0 ) { @@ -1077,8 +1085,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) } else { - m_plotter->PlotPoly( poly.COutline( 0 ), fill_mode, thickness, - &gbr_metadata ); + m_plotter->PlotPoly( poly.COutline( 0 ), fill_mode, thickness, &gbr_metadata ); } } } @@ -1109,7 +1116,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape ) delete shape; } - if( aShape->IsHatchedFill() ) + if( isHatchedFill ) { for( int ii = 0; ii < aShape->GetHatching().OutlineCount(); ++ii ) { diff --git a/pcbnew/teardrop/teardrop.cpp b/pcbnew/teardrop/teardrop.cpp index 5299968208..b6427c4ab2 100644 --- a/pcbnew/teardrop/teardrop.cpp +++ b/pcbnew/teardrop/teardrop.cpp @@ -256,7 +256,7 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit, aCommit.Added( new_teardrop ); - if( track->HasSolderMask() && ( track->GetLayer() == F_Cu || track->GetLayer() == B_Cu ) ) + if( track->HasSolderMask() && IsExternalCopperLayer( track->GetLayer() ) ) { ZONE* new_teardrop_mask = createTeardropMask( TD_TYPE_PADVIA, points, track ); m_board->Add( new_teardrop_mask, ADD_MODE::BULK_INSERT ); @@ -299,7 +299,7 @@ void TEARDROP_MANAGER::UpdateTeardrops( BOARD_COMMIT& aCommit, aCommit.Added( new_teardrop ); - if( track->HasSolderMask() && ( track->GetLayer() == F_Cu || track->GetLayer() == B_Cu ) ) + if( track->HasSolderMask() && IsExternalCopperLayer( track->GetLayer() ) ) { ZONE* new_teardrop_mask = createTeardropMask( TD_TYPE_PADVIA, points, track ); m_board->Add( new_teardrop_mask, ADD_MODE::BULK_INSERT ); @@ -481,7 +481,7 @@ void TEARDROP_MANAGER::AddTeardropsOnTracks( BOARD_COMMIT& aCommit, aCommit.Added( new_teardrop ); - if( track->HasSolderMask() && ( track->GetLayer() == F_Cu || track->GetLayer() == B_Cu ) ) + if( track->HasSolderMask() && IsExternalCopperLayer( track->GetLayer() ) ) { ZONE* new_teardrop_mask = createTeardropMask( TD_TYPE_TRACKEND, points, track ); m_board->Add( new_teardrop_mask, ADD_MODE::BULK_INSERT );