Plot on all layers prep work.
We only need one bottom to top layer sequence definition. Plot a sequence of layer IDs (LSEQ) in the order of the sequence. Add helper method to layer set (LSET) to create a sequence of layer IDs using another sequence for ordering.
This commit is contained in:
parent
91ea0903d0
commit
c0d8657d97
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2014-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include <core/arraydim.h>
|
||||
#include <math/util.h> // for Clamp
|
||||
#include <layer_ids.h> // for LSET, PCB_LAYER_ID, LSEQ
|
||||
#include <layer_ids.h> // for LSET, PCB_LAYER_ID, LSEQ
|
||||
#include <macros.h> // for arrayDim
|
||||
#include <wx/debug.h> // for wxASSERT, wxASSERT_MSG
|
||||
#include <wx/string.h>
|
||||
|
@ -442,6 +442,20 @@ LSEQ LSET::Seq( const PCB_LAYER_ID* aWishListSequence, unsigned aCount ) const
|
|||
}
|
||||
|
||||
|
||||
LSEQ LSET::Seq( const LSEQ& aSequence ) const
|
||||
{
|
||||
LSEQ ret;
|
||||
|
||||
for( LSEQ seq = aSequence; seq; ++seq )
|
||||
{
|
||||
if( test( *seq ) )
|
||||
ret.push_back( *seq );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
LSEQ LSET::Seq() const
|
||||
{
|
||||
LSEQ ret;
|
||||
|
|
|
@ -731,6 +731,8 @@ public:
|
|||
*/
|
||||
LSEQ Seq( const PCB_LAYER_ID* aWishListSequence, unsigned aCount ) const;
|
||||
|
||||
LSEQ Seq( const LSEQ& aSequence ) const;
|
||||
|
||||
/**
|
||||
* Return a LSEQ from this LSET in ascending PCB_LAYER_ID order. Each LSEQ
|
||||
* element will be in the same sequence as in PCB_LAYER_ID and only present
|
||||
|
|
|
@ -218,7 +218,8 @@ void DIALOG_EXPORT_SVG::OnOutputDirectoryBrowseClicked( wxCommandEvent& event )
|
|||
boardFilePath = wxPathOnly( boardFilePath );
|
||||
|
||||
if( !dirName.MakeRelativeTo( boardFilePath ) )
|
||||
wxMessageBox( _( "Cannot make path relative (target volume different from board file volume)!" ),
|
||||
wxMessageBox( _( "Cannot make path relative (target volume different from board "
|
||||
"file volume)!" ),
|
||||
_( "Plot Output Directory" ), wxOK | wxICON_ERROR );
|
||||
}
|
||||
|
||||
|
@ -360,10 +361,7 @@ bool DIALOG_EXPORT_SVG::CreateSVGFile( const wxString& aFullFileName )
|
|||
if( plotter )
|
||||
{
|
||||
plotter->SetColorMode( !m_printBW );
|
||||
|
||||
for( LSEQ seq = m_printMaskLayer.SeqStackupBottom2Top(); seq; ++seq )
|
||||
PlotOneBoardLayer( m_board, plotter, *seq, plot_opts );
|
||||
|
||||
PlotBoardLayers( m_board, plotter, m_printMaskLayer.SeqStackupBottom2Top(), plot_opts );
|
||||
plotter->EndPlot();
|
||||
}
|
||||
|
||||
|
|
|
@ -415,8 +415,6 @@ PLOT_FORMAT DIALOG_PLOT::getPlotFormat()
|
|||
}
|
||||
|
||||
|
||||
// Enable or disable widgets according to the plot format selected
|
||||
// and clear also some optional values
|
||||
void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
|
||||
{
|
||||
// this option exist only in DXF format:
|
||||
|
@ -745,6 +743,7 @@ void DIALOG_PLOT::applyPlotSettings()
|
|||
|
||||
// Get a list of copper layers that aren't being used by inverting enabled layers.
|
||||
LSET disabledCopperLayers = LSET::AllCuMask() & ~m_parent->GetBoard()->GetEnabledLayers();
|
||||
|
||||
// Enable all of the disabled copper layers.
|
||||
// If someone enables more copper layers they will be selected by default.
|
||||
selectedLayers = selectedLayers | disabledCopperLayers;
|
||||
|
@ -871,6 +870,14 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
|
|||
|
||||
for( LSEQ seq = m_plotOpts.GetLayerSelection().UIOrder(); seq; ++seq )
|
||||
{
|
||||
LSEQ plotSequence;
|
||||
|
||||
// Base layer always gets plotted first.
|
||||
plotSequence.push_back( *seq );
|
||||
|
||||
if( ( *seq != Edge_Cuts ) && !m_plotOpts.GetExcludeEdgeLayer() )
|
||||
plotSequence.push_back( Edge_Cuts );
|
||||
|
||||
PCB_LAYER_ID layer = *seq;
|
||||
|
||||
// All copper layers that are disabled are actually selected
|
||||
|
@ -896,14 +903,15 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
|
|||
|
||||
LOCALE_IO toggle;
|
||||
|
||||
PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
|
||||
PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(),
|
||||
wxEmptyString );
|
||||
|
||||
// Print diags in messages box:
|
||||
wxString msg;
|
||||
|
||||
if( plotter )
|
||||
{
|
||||
PlotOneBoardLayer( board, plotter, layer, m_plotOpts );
|
||||
PlotBoardLayers( board, plotter, plotSequence, m_plotOpts );
|
||||
plotter->EndPlot();
|
||||
delete plotter->RenderSettings();
|
||||
delete plotter;
|
||||
|
@ -924,6 +932,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
|
|||
{
|
||||
// Pick the basename from the board file
|
||||
wxFileName fn( boardFilename );
|
||||
|
||||
// Build gerber job file from basename
|
||||
BuildPlotFileName( &fn, outputDir.GetPath(), wxT( "job" ), GerberJobFileExtension );
|
||||
jobfile_writer.CreateJobFile( fn.GetFullPath() );
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -145,6 +145,17 @@ private:
|
|||
PLOTTER* StartPlotBoard( BOARD* aBoard, const PCB_PLOT_PARAMS* aPlotOpts, int aLayer,
|
||||
const wxString& aFullFileName, const wxString& aSheetDesc );
|
||||
|
||||
/**
|
||||
* Plot a sequence of board layer IDs.
|
||||
*
|
||||
* @param aBoard is the board to plot.
|
||||
* @param aPlotter is the plotter to use.
|
||||
* @param aLayerSequence is the sequence of layer IDs to plot.
|
||||
* @param aPlotOptions are the plot options (files, sketch). Has meaning for some formats only.
|
||||
*/
|
||||
void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayerSequence,
|
||||
const PCB_PLOT_PARAMS& aPlotOptions );
|
||||
|
||||
/**
|
||||
* Plot one copper or technical layer.
|
||||
*
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
|
||||
#include <eda_item.h>
|
||||
#include <layer_ids.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <geometry/shape_segment.h>
|
||||
#include <pcb_base_frame.h>
|
||||
|
@ -65,6 +66,16 @@ static void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMa
|
|||
const PCB_PLOT_PARAMS& aPlotOpt, int aMinThickness );
|
||||
|
||||
|
||||
void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayers,
|
||||
const PCB_PLOT_PARAMS& aPlotOptions )
|
||||
{
|
||||
wxCHECK( aBoard && aPlotter && aLayers.size(), /* void */ );
|
||||
|
||||
for( LSEQ seq = aLayers; seq; ++seq )
|
||||
PlotOneBoardLayer( aBoard, aPlotter, *seq, aPlotOptions );
|
||||
}
|
||||
|
||||
|
||||
void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
||||
const PCB_PLOT_PARAMS& aPlotOpt )
|
||||
{
|
||||
|
@ -79,9 +90,6 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
|||
// contents of the currently specified layer.
|
||||
LSET layer_mask( aLayer );
|
||||
|
||||
if( !aPlotOpt.GetExcludeEdgeLayer() )
|
||||
layer_mask.set( Edge_Cuts );
|
||||
|
||||
if( IsCopperLayer( aLayer ) )
|
||||
{
|
||||
// Skip NPTH pads on copper layers ( only if hole size == pad size ):
|
||||
|
@ -104,6 +112,7 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
|||
case B_Mask:
|
||||
case F_Mask:
|
||||
plotOpt.SetSkipPlotNPTH_Pads( false );
|
||||
|
||||
// Disable plot pad holes
|
||||
plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
|
||||
|
||||
|
@ -128,6 +137,7 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
|||
case B_Paste:
|
||||
case F_Paste:
|
||||
plotOpt.SetSkipPlotNPTH_Pads( false );
|
||||
|
||||
// Disable plot pad holes
|
||||
plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
|
||||
|
||||
|
@ -304,9 +314,9 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
|
||||
// Store these parameters that can be modified to plot inflated/deflated pads shape
|
||||
PAD_SHAPE padShape = pad->GetShape();
|
||||
VECTOR2I padSize = pad->GetSize();
|
||||
VECTOR2I padSize = pad->GetSize();
|
||||
VECTOR2I padDelta = pad->GetDelta(); // has meaning only for trapezoidal pads
|
||||
double padCornerRadius = pad->GetRoundRectCornerRadius();
|
||||
double padCornerRadius = pad->GetRoundRectCornerRadius();
|
||||
|
||||
// Don't draw a 0 sized pad.
|
||||
// Note: a custom pad can have its pad anchor with size = 0
|
||||
|
@ -645,74 +655,6 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
}
|
||||
|
||||
|
||||
// Seems like we want to plot from back to front?
|
||||
static const PCB_LAYER_ID plot_seq[] = {
|
||||
|
||||
User_9,
|
||||
User_8,
|
||||
User_7,
|
||||
User_6,
|
||||
User_5,
|
||||
User_4,
|
||||
User_3,
|
||||
User_2,
|
||||
User_1,
|
||||
B_Adhes,
|
||||
F_Adhes,
|
||||
B_Paste,
|
||||
F_Paste,
|
||||
B_SilkS,
|
||||
B_Mask,
|
||||
F_Mask,
|
||||
Dwgs_User,
|
||||
Cmts_User,
|
||||
Eco1_User,
|
||||
Eco2_User,
|
||||
Edge_Cuts,
|
||||
Margin,
|
||||
|
||||
F_CrtYd, // CrtYd & Body are footprint only
|
||||
B_CrtYd,
|
||||
F_Fab,
|
||||
B_Fab,
|
||||
|
||||
B_Cu,
|
||||
In30_Cu,
|
||||
In29_Cu,
|
||||
In28_Cu,
|
||||
In27_Cu,
|
||||
In26_Cu,
|
||||
In25_Cu,
|
||||
In24_Cu,
|
||||
In23_Cu,
|
||||
In22_Cu,
|
||||
In21_Cu,
|
||||
In20_Cu,
|
||||
In19_Cu,
|
||||
In18_Cu,
|
||||
In17_Cu,
|
||||
In16_Cu,
|
||||
In15_Cu,
|
||||
In14_Cu,
|
||||
In13_Cu,
|
||||
In12_Cu,
|
||||
In11_Cu,
|
||||
In10_Cu,
|
||||
In9_Cu,
|
||||
In8_Cu,
|
||||
In7_Cu,
|
||||
In6_Cu,
|
||||
In5_Cu,
|
||||
In4_Cu,
|
||||
In3_Cu,
|
||||
In2_Cu,
|
||||
In1_Cu,
|
||||
F_Cu,
|
||||
|
||||
F_SilkS,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Plot outlines of copper layer.
|
||||
*/
|
||||
|
@ -724,7 +666,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
|
||||
SHAPE_POLY_SET outlines;
|
||||
|
||||
for( LSEQ seq = aLayerMask.Seq( plot_seq, arrayDim( plot_seq ) ); seq; ++seq )
|
||||
for( LSEQ seq = aLayerMask.Seq( aLayerMask.SeqStackupBottom2Top() ); seq; ++seq )
|
||||
{
|
||||
PCB_LAYER_ID layer = *seq;
|
||||
|
||||
|
@ -752,8 +694,9 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
// Plot pad holes
|
||||
if( aPlotOpt.GetDrillMarksType() != PCB_PLOT_PARAMS::NO_DRILL_SHAPE )
|
||||
{
|
||||
int smallDrill = (aPlotOpt.GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE)
|
||||
? Millimeter2iu( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize ) : INT_MAX;
|
||||
int smallDrill = ( aPlotOpt.GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE )
|
||||
? Millimeter2iu( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize ) :
|
||||
INT_MAX;
|
||||
|
||||
for( FOOTPRINT* footprint : aBoard->Footprints() )
|
||||
{
|
||||
|
@ -838,7 +781,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
|
||||
// We remove 1nm as we expand both sides of the shapes, so allowing for a strictly greater
|
||||
// than or equal comparison in the shape separation (boolean add)
|
||||
int inflate = aMinThickness/2 - 1;
|
||||
int inflate = aMinThickness / 2 - 1;
|
||||
|
||||
BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
|
||||
itemplotter.SetLayerSet( aLayerMask );
|
||||
|
@ -882,6 +825,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
// add shapes with their exact mask layer size in initialPolys
|
||||
item->TransformShapeWithClearanceToPolygon( initialPolys, layer, 0, maxError,
|
||||
ERROR_OUTSIDE );
|
||||
|
||||
// add shapes inflated by aMinThickness/2 in areas
|
||||
item->TransformShapeWithClearanceToPolygon( areas, layer, inflate, maxError,
|
||||
ERROR_OUTSIDE );
|
||||
|
@ -907,6 +851,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
// add shapes with their exact mask layer size in initialPolys
|
||||
via->TransformShapeWithClearanceToPolygon( initialPolys, layer, clearance, maxError,
|
||||
ERROR_OUTSIDE );
|
||||
|
||||
// add shapes inflated by aMinThickness/2 in areas
|
||||
via->TransformShapeWithClearanceToPolygon( areas, layer, clearance + inflate, maxError,
|
||||
ERROR_OUTSIDE );
|
||||
|
|
Loading…
Reference in New Issue