Added: DXF Multilayer plotting

DXF layers and appropriate layer colors added.  Option mimics the PDF
multilayer option

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2526
This commit is contained in:
Seth Hillbrand
2025-12-02 09:37:40 -08:00
parent 71a1df2f58
commit 99fdf2b9be
12 changed files with 1265 additions and 233 deletions
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -76,11 +76,12 @@ enum EDA_COLOR_T
ORANGE,
LIGHTORANGE,
PUREORANGE,
NBCOLORS, ///< Number of colors
HIGHLIGHT_FLAG = ( 1<<19 ),
MASKCOLOR = 31 ///< mask for color index into colorRefs()[]
NBCOLORS, ///< Number of colors
HIGHLIGHT_FLAG = ( 1 << 19 ),
MASKCOLOR = 31 ///< mask for color index into colorRefs()[]
};
struct KICOMMON_API StructColors
{
unsigned char m_Blue;
+50 -1
View File
@@ -111,6 +111,21 @@ public:
};
/**
* @enum DXF_LAYER_OUTPUT_MODE
* @brief Specifies the output mode for the DXF layer.
*
* This enumeration is used to define the mode of output for the DXF layer.
* It allows the user to choose between retrieving the layer name or the color name.
*/
enum class DXF_LAYER_OUTPUT_MODE
{
Layer_Name,
Layer_Color_Name,
Current_Layer_Name,
Current_Layer_Color_Name
};
/**
* Base plotter engine class. General rule: all the interface with the caller
* is done in IU, the IU size is specified with SetViewport. Internal and
@@ -206,8 +221,39 @@ public:
virtual void SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
double aScale, bool aMirror ) = 0;
/**
* Sets the list of layers to export to the specified vector.
*
* This function updates the member variable m_layersToExport with the
* vector provided in aLayersToExport.
*
* @param aLayersToExport The vector containing the names of layers to export.
* This updates the internal list of layers that will
* be processed for export.
*/
void SetLayersToExport( const std::vector<std::pair<PCB_LAYER_ID, wxString>>& aLayersToExport ) { m_layersToExport = aLayersToExport; }
/**
* @brief Gets the ID of the current layer.
*
* This function returns the ID of the layer that the current item is on.
*
* @return PCB_LAYER_ID The ID of the current layer.
*/
PCB_LAYER_ID GetLayer() const { return m_layer; }
/**
* @brief Sets the ID of the current layer.
*
* This function sets the ID of the layer for the current item.
*
* @param aLayer The ID of the layer to be set.
*/
void SetLayer( PCB_LAYER_ID aLayer ) { m_layer = aLayer; }
/**
* Open or create the plot file \a aFullFilename.
* .
*
* @param aFullFilename is the full file name of the file to create.
* @return true if success, false if the file cannot be created/opened.
@@ -646,7 +692,7 @@ protected: // variables used in most of plotters:
* because in Eeschema there are 0.1 IUs in a decimil (Eeschema
* always works in mils internally) while PcbNew can work in decimil
* or nanometers, so this value would be >= 1 */
double m_IUsPerDecimil;
double m_IUsPerDecimil;
double m_iuPerDeviceUnit; // Device scale (from IUs to plotter device units;
// usually decimils)
@@ -679,6 +725,9 @@ protected: // variables used in most of plotters:
RENDER_SETTINGS* m_renderSettings;
const PROJECT* m_project;
std::vector<std::pair<PCB_LAYER_ID, wxString>> m_layersToExport;
PCB_LAYER_ID m_layer;
};
+262
View File
@@ -21,6 +21,262 @@
#include "plotter.h"
/**
* Legacy colors for DXF file.
*/
enum class DXF_COLOR_T
{
BLACK = 0,
RED,
YELLOW,
GREEN,
CYAN,
BLUE,
MAGENTA,
WHITE,
BROWN,
ORANGE,
LIGHTRED,
LIGHTYELLOW,
LIGHTGREEN,
LIGHTCYAN,
LIGHTBLUE,
LIGHTMAGENTA,
LIGHTORANGE,
LIGHTGRAY,
DARKRED,
DARKYELLOW,
DARKGREEN,
DARKCYAN,
DARKBLUE,
DARKMAGENTA,
DARKBROWN,
DARKORANGE,
DARKGRAY,
PURERED,
PUREYELLOW,
PUREGREEN,
PURECYAN,
PUREBLUE,
PUREMAGENTA,
PUREORANGE,
PUREGRAY,
REDONE,
REDTWO,
REDTHREE,
REDFOUR,
REDFIVE,
REDSIX,
ORANGEONE,
ORANGETWO,
ORANGETHREE,
ORANGEFOUR,
ORANGEFIVE,
REDSEVEN,
REDEIGHT,
ORANGESIX,
REDNINE,
ORANGESEVEN,
ORANGEEIGHT,
ORANGENINE,
ORANGETEN,
ORANGEELEVEN,
ORANGETWELVE,
ORANGETHIRTEEN,
ORANGEFOURTEEN,
YELLOWONE,
YELLOWTWO,
YELLOWTHREE,
YELLOWFOUR,
YELLOWFIVE,
YELLOWSIX,
YELLOWSEVEN,
YELLOWEIGHT,
YELLOWNINE,
YELLOWTEN,
YELLOWELEVEN,
YELLOWTWELVE,
YELLOWTHIRTEEN,
YELLOWFOURTEEN,
GREENONE,
GREENTWO,
GREENTHREE,
GREENFOUR,
GREENFIVE,
GREENSIX,
GREENSEVEN,
GREENEIGHT,
GREENNINE,
GREENTEN,
GREENELEVEN,
GREENTWELVE,
GREENTHIRTEEN,
GREENFOURTEEN,
GREENFIFTEEN,
GREENSIXTEEN,
GREENSEVENTEEN,
GREENEIGHTEEN,
GREENNINETEEN,
GREENTWENTY,
GREENTWENTYONE,
GREENTWENTYTWO,
GREENTWENTYTHREE,
GREENTWENTYFOUR,
GREENTWENTYFIVE,
GREENTWENTYSIX,
GREENTWENTYSEVEN,
GREENTWENTYEIGHT,
GREENTWENTYNINE,
GREENTHIRTY,
GREENTHIRTYONE,
GREENTHIRTYTWO,
GREENTHIRTYTHREE,
GREENTHIRTYFOUR,
GREENTHIRTYFIVE,
GREENTHIRTYSIX,
GREENTHIRTYSEVEN,
GREENTHIRTYEIGHT,
GREENTHIRTYNINE,
GREENFORTY,
GREENFORTYONE,
GREENFORTYTWO,
GREENFORTYTHREE,
GREENFORTYFOUR,
GREENFORTYFIVE,
GREENFORTYSIX,
GREENFORTYSEVEN,
GREENFORTYEIGHT,
GREENFORTYNINE,
GREENFIFTY,
GREENFIFTYONE,
GREENFIFTYTWO,
GREENFIFTYTHREE,
GREENFIFTYFOUR,
GREENFIFTYFIVE,
GREENFIFTYSIX,
GREENFIFTYSEVEN,
GREENFIFTYEIGHT,
GREENFIFTYNINE,
GREENSIXTY,
GREENSIXTYONE,
GREENSIXTYTWO,
GREENSIXTYTHREE,
GREENSIXTYFOUR,
GREENSIXTYFIVE,
CYANONE,
CYANTWO,
CYANTHREE,
CYANFOUR,
CYANFIVE,
CYANSIX,
CYANSEVEN,
BLUEONE,
BLUETWO,
BLUETHREE,
BLUEFOUR,
BLUEFIVE,
BLUESIX,
BLUESEVEN,
BLUEEIGHT,
BLUENINE,
BLUETEN,
BLUEELEVEN,
BLUETWELVE,
BLUETHIRTEEN,
BLUEFOURTEEN,
BLUEFIFTEEN,
BLUESIXTEEN,
BLUESEVENTEEN,
BLUEEIGHTEEN,
BLUENINETEEN,
BLUETWENTY,
BLUETWENTYONE,
BLUETWENTYTWO,
BLUETWENTYTHREE,
BLUETWENTYFOUR,
BLUETWENTYFIVE,
BLUETWENTYSIX,
BLUETWENTYSEVEN,
BLUETWENTYEIGHT,
BLUETWENTYNINE,
BLUETHIRTY,
BLUETHIRTYONE,
BLUETHIRTYTWO,
BLUETHIRTYETHREE,
BLUETHIRTYFOUR,
VIOLETONE,
VIOLETTWO,
VIOLETTHREE,
VIOLETFOUR,
VIOLETFIVE,
VIOLETSIX,
VIOLETSEVEN,
VIOLETEIGHT,
VIOLETNINE,
VIOLETTEN,
VIOLETELEVEN,
VIOLETTWELVE,
VIOLETTHIRTEEN,
VIOLETFOURTEEN,
VIOLETFIFTEEN,
VIOLETSIXTEEN,
VIOLETSEVENTEEN,
VIOLETEIGHTEEN,
VIOLETNINETEEN,
VIOLETTWENTY,
VIOLETTWENTYONE,
VIOLETTWENTYTWO,
VIOLETTWENTYTHREE,
VIOLETTWENTYFOUR,
VIOLETTWENTYFIVE,
VIOLETTWENTYSIX,
VIOLETTWENTYSEVEN,
VIOLETTWENTYEIGHT,
VIOLETTWENTYNINE,
VIOLETTHIRTY,
MAGENTAONE,
MAGENTATWO,
MAGENTATHREE,
MAGENTAFOUR,
MAGENTAFIVE,
MAGENTASIX,
MAGENTASEVEN,
MAGENTAEIGHT,
MAGENTANINE,
MAGENTATEN,
MAGENTAELEVEN,
MAGENTATWELVE,
MAGENTATHIRTEEN,
MAGENTAFOURTEEN,
REDTEN,
REDELEVEN,
VIOLETTHIRTYONE,
REDTWELVE,
REDTHIRTEEN,
REDFOURTEEN,
REDFIFTEEN,
REDSIXTEEN,
REDSEVENTEEN,
REDEIGHTEEN,
REDNINETEEN,
REDTWENTY,
REDTWENTYONE,
REDTWENTYTWO,
REDTWENTYTHREE,
REDTWENTYFOUR,
REDTWENTYFIVE,
REDTWENTYSIX,
REDTWENTYSEVEN,
REDTWENTYEIGHT,
REDTWENTYNINE,
REDTHIRTY,
REDTHIRTYONE,
GRAYONE,
GRAYTWO,
GRAYTHREE,
GRAYFOUR,
NBCOLORS ///< Number of colors
};
class DXF_PLOTTER : public PLOTTER
{
@@ -220,6 +476,12 @@ public:
return m_measurementDirective;
}
// Finds the nearest legacy color to the given RGB values (aR, aG, aB).
int FindNearestLegacyColor( int aR, int aG, int aB );
// Retrieves the current layer name based on the output mode and optional layer ID.
wxString GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE aMode, std::optional<PCB_LAYER_ID> aLayerId = std::nullopt );
protected:
void plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText,
const TEXT_ATTRIBUTES& aAttrs );
+14 -11
View File
@@ -207,28 +207,28 @@ DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aEditFrame, wxWindow* aParent, JOB_EXP
m_plotAllLayersList->SetClientObject( list_idx, new PCB_LAYER_ID_CLIENT_DATA( layer_id ) );
}
sbSizer->Add( m_plotAllLayersList, 1, wxALL | wxEXPAND | wxFIXED_MINSIZE, 3 );
sbSizer->Add( m_plotAllLayersList, 1, wxALL | wxEXPAND | wxFIXED_MINSIZE, 3 );
wxBoxSizer* bButtonSizer;
bButtonSizer = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bButtonSizer;
bButtonSizer = new wxBoxSizer( wxHORIZONTAL );
m_bpMoveUp = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap,
m_bpMoveUp = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap,
wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0 );
m_bpMoveUp->SetToolTip( _( "Move current selection up" ) );
m_bpMoveUp->SetToolTip( _( "Move current selection up" ) );
m_bpMoveUp->SetBitmap( KiBitmapBundle( BITMAPS::small_up ) );
bButtonSizer->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3 );
bButtonSizer->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 3 );
m_bpMoveDown = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap,
m_bpMoveDown = new STD_BITMAP_BUTTON( sbSizer->GetStaticBox(), wxID_ANY, wxNullBitmap,
wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW | 0 );
m_bpMoveDown->SetToolTip( _( "Move current selection down" ) );
m_bpMoveDown->SetToolTip( _( "Move current selection down" ) );
m_bpMoveDown->SetBitmap( KiBitmapBundle( BITMAPS::small_down ) );
bButtonSizer->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
bButtonSizer->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 5 );
sbSizer->Add( bButtonSizer, 0, wxALL | wxEXPAND, 3 );
bmiddleSizer->Insert( 1, sbSizer, 1, wxALL | wxEXPAND, 5 );
bmiddleSizer->Insert( 1, sbSizer, 1, wxALL | wxEXPAND, 5 );
m_browseButton->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
m_openDirButton->SetBitmap( KiBitmapBundle( BITMAPS::small_new_window ) );
@@ -450,7 +450,8 @@ void DIALOG_PLOT::transferPlotParamsToJob()
: JOB_EXPORT_PCB_DXF::DXF_UNITS::MM;
dxfJob->m_plotGraphicItemsUsingContours = m_plotOpts.GetDXFPlotMode() == DXF_OUTLINE_MODE::SKETCH;
dxfJob->m_polygonMode = m_plotOpts.GetDXFPlotPolygonMode();
dxfJob->m_genMode = JOB_EXPORT_PCB_DXF::GEN_MODE::MULTI;
dxfJob->m_genMode = m_plotOpts.GetDXFMultiLayeredExportOption() ? JOB_EXPORT_PCB_DXF::GEN_MODE::SINGLE
: JOB_EXPORT_PCB_DXF::GEN_MODE::MULTI;
}
if( m_job->m_plotFormat == JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::POST )
@@ -1005,6 +1006,8 @@ void DIALOG_PLOT::applyPlotSettings()
tempOptions.SetTextMode( m_DXF_plotTextStrokeFontOpt->GetValue() ? PLOT_TEXT_MODE::DEFAULT :
PLOT_TEXT_MODE::NATIVE );
tempOptions.SetDXFMultiLayeredExportOption( m_DXF_exportAsMultiLayeredFile->GetValue() );
if( getPlotFormat() == PLOT_FORMAT::SVG )
{
tempOptions.SetBlackAndWhite( m_SVGColorChoice->GetSelection() == 1 );
+9 -3
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -304,17 +304,18 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
m_DXF_plotModeOpt = new wxCheckBox( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Plot graphic items using their contours"), wxDefaultPosition, wxDefaultSize, 0 );
m_DXF_plotModeOpt->SetValue(true);
m_DXF_plotModeOpt->SetToolTip( _("Uncheck to plot graphic items using their center lines") );
m_DXF_plotModeOpt->SetMinSize( wxSize( 300,-1 ) );
gbSizer5->Add( m_DXF_plotModeOpt, wxGBPosition( 0, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
DXF_exportUnitsLabel = new wxStaticText( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Export units:"), wxDefaultPosition, wxDefaultSize, 0 );
DXF_exportUnitsLabel->Wrap( -1 );
gbSizer5->Add( DXF_exportUnitsLabel, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 40 );
gbSizer5->Add( DXF_exportUnitsLabel, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
wxString m_DXF_plotUnitsChoices[] = { _("Inches"), _("Millimeters") };
int m_DXF_plotUnitsNChoices = sizeof( m_DXF_plotUnitsChoices ) / sizeof( wxString );
m_DXF_plotUnits = new wxChoice( m_SizerDXF_options->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_DXF_plotUnitsNChoices, m_DXF_plotUnitsChoices, 0 );
m_DXF_plotUnits->SetSelection( 0 );
m_DXF_plotUnits->SetSelection( 1 );
m_DXF_plotUnits->SetToolTip( _("The units to use for the exported DXF file") );
gbSizer5->Add( m_DXF_plotUnits, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
@@ -324,6 +325,11 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
gbSizer5->Add( m_DXF_plotTextStrokeFontOpt, wxGBPosition( 1, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_DXF_exportAsMultiLayeredFile = new wxCheckBox( m_SizerDXF_options->GetStaticBox(), wxID_ANY, _("Single document"), wxDefaultPosition, wxDefaultSize, 0 );
m_DXF_exportAsMultiLayeredFile->SetToolTip( _("Export selected layers into a single DXF") );
gbSizer5->Add( m_DXF_exportAsMultiLayeredFile, wxGBPosition( 2, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_SizerDXF_options->Add( gbSizer5, 1, wxEXPAND|wxBOTTOM, 5 );
+72 -4
View File
@@ -3060,7 +3060,7 @@
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="minimum_size">300,-1</property>
<property name="moveable">1</property>
<property name="name">m_DXF_plotModeOpt</property>
<property name="pane_border">1</property>
@@ -3087,7 +3087,7 @@
</object>
</object>
<object class="gbsizeritem" expanded="true">
<property name="border">40</property>
<property name="border">5</property>
<property name="colspan">1</property>
<property name="column">2</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
@@ -3203,7 +3203,7 @@
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="selection">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
@@ -3262,7 +3262,7 @@
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_DXF_plotTextStrokeFontOpt</property>
<property name="pane_border">1</property>
@@ -3287,6 +3287,74 @@
<property name="window_style"></property>
</object>
</object>
<object class="gbsizeritem" expanded="true">
<property name="border">5</property>
<property name="colspan">2</property>
<property name="column">0</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="row">2</property>
<property name="rowspan">1</property>
<object class="wxCheckBox" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Single document</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_DXF_exportAsMultiLayeredFile</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Export selected layers into a single DXF</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
</object>
</object>
</object>
+2 -1
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -106,6 +106,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM
wxStaticText* DXF_exportUnitsLabel;
wxChoice* m_DXF_plotUnits;
wxCheckBox* m_DXF_plotTextStrokeFontOpt;
wxCheckBox* m_DXF_exportAsMultiLayeredFile;
wxStaticBoxSizer* m_svgOptionsSizer;
wxStaticText* svgPrecisionLabel;
wxSpinCtrl* m_svgPrecsision;
+5
View File
@@ -116,6 +116,8 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
m_colors = m_default_colors.get();
m_blackAndWhite = true;
m_DXFExportAsMultiLayeredFile = false;
}
@@ -340,6 +342,9 @@ bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams ) const
if( !m_outputDirectory.IsSameAs( aPcbPlotParams.m_outputDirectory ) )
return false;
if( m_DXFExportAsMultiLayeredFile != aPcbPlotParams.m_DXFExportAsMultiLayeredFile )
return false;
return true;
}
+18
View File
@@ -184,6 +184,18 @@ public:
void SetDashedLineGapRatio( double aVal ) { m_dashedLineGapRatio = aVal; }
double GetDashedLineGapRatio() const { return m_dashedLineGapRatio; }
void SetDXFMultiLayeredExportOption( bool aFlag ) { m_DXFExportAsMultiLayeredFile = aFlag; }
bool GetDXFMultiLayeredExportOption() const { return m_DXFExportAsMultiLayeredFile; }
void SetLayersToExport( std::vector<std::pair<PCB_LAYER_ID, wxString>> & aVal ) { m_layersToExport = aVal; }
std::vector<std::pair<PCB_LAYER_ID, wxString>> GetLayersToExport() const { return m_layersToExport; }
/**
* Return the layer this item is on.
*/
PCB_LAYER_ID GetLayer() const { return m_layer; }
void SetLayer( PCB_LAYER_ID aLayer ) { m_layer = aLayer; }
void SetPDFBackgroundColor( const COLOR4D& aColor ) { m_PDFBackgroundColor = aColor; }
COLOR4D GetPDFBackgroundColor() const { return m_PDFBackgroundColor; }
@@ -291,6 +303,12 @@ private:
/// Dummy colors object that can be created if there is no Pgm context
std::shared_ptr<COLOR_SETTINGS> m_default_colors;
bool m_DXFExportAsMultiLayeredFile;
std::vector<std::pair<PCB_LAYER_ID, wxString>> m_layersToExport;
PCB_LAYER_ID m_layer;
};
+19 -8
View File
@@ -101,7 +101,7 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
LSEQ layersToPlot;
LSEQ commonLayers;
if( aOutputPathIsSingle )
if( aOutputPathIsSingle && !m_plotOpts.GetDXFMultiLayeredExportOption() )
{
layersToPlot.push_back( aLayersToPlot[0] );
@@ -115,13 +115,17 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
}
int finalPageCount = 0;
std::vector<std::pair<PCB_LAYER_ID, wxString>> layersToExport;
// Skip the disabled copper layers and build the layer ID -> layer name mapping for plotter
// DXF plotter will use this information to name its layers
for( PCB_LAYER_ID layer : layersToPlot )
{
if( copperLayerShouldBeSkipped( layer ) )
continue;
finalPageCount++;
layersToExport.emplace_back( layer, m_board->GetLayerName( layer ) );
}
std::unique_ptr<GERBER_JOBFILE_WRITER> jobfile_writer;
@@ -129,6 +133,7 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && !aOutputPathIsSingle )
jobfile_writer = std::make_unique<GERBER_JOBFILE_WRITER>( m_board, m_reporter );
PLOT_FORMAT plot_format = m_plotOpts.GetFormat();
wxString fileExt( GetDefaultPlotExtension( m_plotOpts.GetFormat() ) );
wxString sheetPath;
wxString msg;
@@ -161,8 +166,10 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
if( m_plotOpts.GetFormat() == PLOT_FORMAT::GERBER && aUseGerberFileExtensions )
fileExt = GetGerberProtelExtension( layer );
if( m_plotOpts.GetFormat() == PLOT_FORMAT::PDF && m_plotOpts.m_PDFSingle )
if( plot_format == PLOT_FORMAT::PDF && m_plotOpts.m_PDFSingle )
fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::PDF ) );
else if ( plot_format == PLOT_FORMAT::DXF && m_plotOpts.GetDXFMultiLayeredExportOption() )
fn.SetExt( GetDefaultPlotExtension( PLOT_FORMAT::DXF ) );
else
BuildPlotFileName( &fn, aOutputPath, layerName, fileExt );
}
@@ -173,10 +180,11 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
jobfile_writer->AddGbrFile( layer, fullname );
}
if( m_plotOpts.GetFormat() != PLOT_FORMAT::PDF
|| !m_plotOpts.m_PDFSingle
|| ( pageNum == 1 && m_plotOpts.GetFormat() == PLOT_FORMAT::PDF
&& m_plotOpts.m_PDFSingle ) )
if( ( plot_format != PLOT_FORMAT::PDF && plot_format != PLOT_FORMAT::DXF )
|| ( !m_plotOpts.m_PDFSingle && !m_plotOpts.GetDXFMultiLayeredExportOption() )
|| ( pageNum == 1
&& ( ( plot_format == PLOT_FORMAT::PDF && m_plotOpts.m_PDFSingle )
|| ( plot_format == PLOT_FORMAT::DXF && m_plotOpts.GetDXFMultiLayeredExportOption() ) ) ) )
{
// this will only be used by pdf
wxString pageNumber = wxString::Format( "%d", pageNum );
@@ -195,12 +203,14 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
if( aSheetPath.has_value() )
sheetPath = aSheetPath.value();
m_plotOpts.SetLayersToExport( layersToExport );
plotter = StartPlotBoard( m_board, &m_plotOpts, layer, layerName, fn.GetFullPath(),
sheetName, sheetPath, pageName, pageNumber, finalPageCount );
}
if( plotter )
{
plotter->SetLayer( layer );
plotter->SetTitle( ExpandTextVars( m_board->GetTitleBlock().GetTitle(), &textResolver ) );
if( m_plotOpts.m_PDFMetadata )
@@ -253,8 +263,8 @@ bool PCB_PLOTTER::Plot( const wxString& aOutputPath, const LSEQ& aLayersToPlot,
}
// last page
if( m_plotOpts.GetFormat() != PLOT_FORMAT::PDF
|| !m_plotOpts.m_PDFSingle
if( (plot_format != PLOT_FORMAT::PDF && plot_format != PLOT_FORMAT::DXF)
|| (!m_plotOpts.m_PDFSingle && !m_plotOpts.GetDXFMultiLayeredExportOption())
|| i == aLayersToPlot.size() - 1
|| pageNum == finalPageCount )
{
@@ -415,6 +425,7 @@ void PCB_PLOTTER::PlotJobToPlotOpts( PCB_PLOT_PARAMS& aOpts, JOB_EXPORT_PCB_PLOT
aOpts.SetDXFPlotMode( dxfJob->m_plotGraphicItemsUsingContours ? DXF_OUTLINE_MODE::SKETCH
: DXF_OUTLINE_MODE::FILLED );
aOpts.SetDXFPlotPolygonMode( dxfJob->m_polygonMode );
aOpts.SetDXFMultiLayeredExportOption( dxfJob->m_genMode == JOB_EXPORT_PCB_DXF::GEN_MODE::SINGLE );
}
if( aJob->m_plotFormat == JOB_EXPORT_PCB_PLOT::PLOT_FORMAT::PDF )
+4 -1
View File
@@ -337,7 +337,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, const LSET& aLayerMask
bool onBackFab = ( LSET( { B_Fab } ) & aLayerMask ).any();
bool sketchPads = ( onFrontFab || onBackFab ) && aPlotOpt.GetSketchPadsOnFabLayers();
// Plot edge layer and graphic items
// Plot edge layer and graphic items
for( const BOARD_ITEM* item : aBoard->Drawings() )
itemplotter.PlotBoardGraphicItem( item );
@@ -1240,6 +1240,9 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, const PCB_PLOT_PARAMS *aPlotOpts, int aL
DXF_plotter->SetUnits( aPlotOpts->GetDXFPlotUnits() );
plotter = DXF_plotter;
if( !aPlotOpts->GetLayersToExport().empty() )
plotter->SetLayersToExport( aPlotOpts->GetLayersToExport() );
break;
case PLOT_FORMAT::POST: