From d5f680ecd23a8d70face0c120c2d7e001b6452e8 Mon Sep 17 00:00:00 2001 From: Ian McInerney Date: Thu, 13 Jun 2019 01:28:22 +0100 Subject: [PATCH] Allow DXF to be exported in either inches or millimeters Fixes: lp:1832188 * https://bugs.launchpad.net/kicad/+bug/1832188 --- common/plotters/DXF_plotter.cpp | 245 +++++++++++++++++--------------- include/plotter.h | 51 +++++++ pcbnew/dialogs/dialog_plot.cpp | 2 + pcbnew/pcb_plot_params.cpp | 5 +- pcbnew/pcb_plot_params.h | 22 +++ pcbnew/plot_board_layers.cpp | 6 +- 6 files changed, 217 insertions(+), 114 deletions(-) diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index 5f455d2a59..0a08f3b103 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -121,6 +121,26 @@ static wxString getDXFColorName( COLOR4D aColor ) return cname; } + +void DXF_PLOTTER::SetUnits( Units aUnit ) +{ + m_plotUnits = aUnit; + + switch( aUnit ) + { + case MILIMETERS: + m_unitScalingFactor = 0.00254; + m_measurementDirective = 1; + break; + + case INCHES: + default: + m_unitScalingFactor = 0.0001; + m_measurementDirective = 0; + } +} + + /** * Set the scale/position for the DXF plot * The DXF engine doesn't support line widths and mirroring. The output @@ -143,7 +163,7 @@ void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, * english units */ m_IUsPerDecimil = aIusPerDecimil; iuPerDeviceUnit = 1.0 / aIusPerDecimil; // Gives a DXF in decimils - iuPerDeviceUnit *= 0.0001; // ... now in inches + iuPerDeviceUnit *= GetUnitScaling(); // Get the scaling factor for the current units SetDefaultLineWidth( 0 ); // No line width on DXF m_plotMirror = false; // No mirroring on DXF @@ -160,117 +180,118 @@ bool DXF_PLOTTER::StartPlot() // DXF HEADER - Boilerplate // Defines the minimum for drawing i.e. the angle system and the // 4 linetypes (CONTINUOUS, DOTDASH, DASHED and DOTTED) - fputs( " 0\n" - "SECTION\n" - " 2\n" - "HEADER\n" - " 9\n" - "$ANGBASE\n" - " 50\n" - "0.0\n" - " 9\n" - "$ANGDIR\n" - " 70\n" - " 1\n" - " 9\n" - "$MEASUREMENT\n" - " 70\n" - "0\n" - " 0\n" // This means 'english units' - "ENDSEC\n" - " 0\n" - "SECTION\n" - " 2\n" - "TABLES\n" - " 0\n" - "TABLE\n" - " 2\n" - "LTYPE\n" - " 70\n" - "4\n" - " 0\n" - "LTYPE\n" - " 5\n" - "40F\n" - " 2\n" - "CONTINUOUS\n" - " 70\n" - "0\n" - " 3\n" - "Solid line\n" - " 72\n" - "65\n" - " 73\n" - "0\n" - " 40\n" - "0.0\n" - " 0\n" - "LTYPE\n" - " 5\n" - "410\n" - " 2\n" - "DASHDOT\n" - " 70\n" - "0\n" - " 3\n" - "Dash Dot ____ _ ____ _\n" - " 72\n" - "65\n" - " 73\n" - "4\n" - " 40\n" - "2.0\n" - " 49\n" - "1.25\n" - " 49\n" - "-0.25\n" - " 49\n" - "0.25\n" - " 49\n" - "-0.25\n" - " 0\n" - "LTYPE\n" - " 5\n" - "411\n" - " 2\n" - "DASHED\n" - " 70\n" - "0\n" - " 3\n" - "Dashed __ __ __ __ __\n" - " 72\n" - "65\n" - " 73\n" - "2\n" - " 40\n" - "0.75\n" - " 49\n" - "0.5\n" - " 49\n" - "-0.25\n" - " 0\n" - "LTYPE\n" - " 5\n" - "43B\n" - " 2\n" - "DOTTED\n" - " 70\n" - "0\n" - " 3\n" - "Dotted . . . .\n" - " 72\n" - "65\n" - " 73\n" - "2\n" - " 40\n" - "0.2\n" - " 49\n" - "0.0\n" - " 49\n" - "-0.2\n" - " 0\n" - "ENDTAB\n", - outputFile ); + fprintf( outputFile, + " 0\n" + "SECTION\n" + " 2\n" + "HEADER\n" + " 9\n" + "$ANGBASE\n" + " 50\n" + "0.0\n" + " 9\n" + "$ANGDIR\n" + " 70\n" + "1\n" + " 9\n" + "$MEASUREMENT\n" + " 70\n" + "%u\n" + " 0\n" + "ENDSEC\n" + " 0\n" + "SECTION\n" + " 2\n" + "TABLES\n" + " 0\n" + "TABLE\n" + " 2\n" + "LTYPE\n" + " 70\n" + "4\n" + " 0\n" + "LTYPE\n" + " 5\n" + "40F\n" + " 2\n" + "CONTINUOUS\n" + " 70\n" + "0\n" + " 3\n" + "Solid line\n" + " 72\n" + "65\n" + " 73\n" + "0\n" + " 40\n" + "0.0\n" + " 0\n" + "LTYPE\n" + " 5\n" + "410\n" + " 2\n" + "DASHDOT\n" + " 70\n" + "0\n" + " 3\n" + "Dash Dot ____ _ ____ _\n" + " 72\n" + "65\n" + " 73\n" + "4\n" + " 40\n" + "2.0\n" + " 49\n" + "1.25\n" + " 49\n" + "-0.25\n" + " 49\n" + "0.25\n" + " 49\n" + "-0.25\n" + " 0\n" + "LTYPE\n" + " 5\n" + "411\n" + " 2\n" + "DASHED\n" + " 70\n" + "0\n" + " 3\n" + "Dashed __ __ __ __ __\n" + " 72\n" + "65\n" + " 73\n" + "2\n" + " 40\n" + "0.75\n" + " 49\n" + "0.5\n" + " 49\n" + "-0.25\n" + " 0\n" + "LTYPE\n" + " 5\n" + "43B\n" + " 2\n" + "DOTTED\n" + " 70\n" + "0\n" + " 3\n" + "Dotted . . . .\n" + " 72\n" + "65\n" + " 73\n" + "2\n" + " 40\n" + "0.2\n" + " 49\n" + "0.0\n" + " 49\n" + "-0.2\n" + " 0\n" + "ENDTAB\n", + GetMeasurementDirective() ); // Text styles table // Defines 4 text styles, one for each bold/italic combination diff --git a/include/plotter.h b/include/plotter.h index e74c9f2d02..7cdec2e1a0 100644 --- a/include/plotter.h +++ b/include/plotter.h @@ -1259,6 +1259,7 @@ public: textAsLines = true; m_currentColor = COLOR4D::BLACK; m_currentLineType = 0; + SetUnits( DXF_PLOTTER::INCHES ); } virtual PlotFormat GetPlotterType() const override @@ -1341,10 +1342,60 @@ public: bool aMultilineAllowed = false, void* aData = NULL ) override; + + // Should be the same order as in the PCB_PLOT_PARAMS class + enum Units + { + INCHES = 0, + MILIMETERS = 1 + }; + + /** + * Set the units to use for plotting the DXF file. + * + * @param aUnit - The units to use + */ + void SetUnits( Units aUnit ); + + /** + * The units currently enabled for plotting + * + * @return The currently configured units + */ + Units GetUnits() const + { + return m_plotUnits; + } + + /** + * Get the scale factor to apply to convert the device units to be in the + * currently set units. + * + * @return Scaling factor to apply for unit conversion + */ + double GetUnitScaling() const + { + return m_unitScalingFactor; + } + + /** + * Get the correct value for the $MEASUREMENT field given the current units + * + * @return the $MEASUREMENT directive field value + */ + unsigned int GetMeasurementDirective() const + { + return m_measurementDirective; + } + protected: bool textAsLines; COLOR4D m_currentColor; int m_currentLineType; + + Units m_plotUnits; + double m_unitScalingFactor; + unsigned int m_measurementDirective; }; class TITLE_BLOCK; diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index da5c29d392..d4798681ba 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -573,6 +573,8 @@ void DIALOG_PLOT::applyPlotSettings() tempOptions.SetMirror( m_plotMirrorOpt->GetValue() ); tempOptions.SetPlotMode( m_plotModeOpt->GetSelection() == 1 ? SKETCH : FILLED ); tempOptions.SetDXFPlotPolygonMode( m_DXF_plotModeOpt->GetValue() ); + tempOptions.SetDXFPlotUnits( + static_cast( m_DXF_plotUnits->GetSelection() ) ); tempOptions.SetPlotViaOnMaskLayer( m_plotNoViaOnMaskOpt->GetValue() ); if( !m_DXF_plotTextStrokeFontOpt->IsEnabled() ) // Currently, only DXF supports this option diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index 3d7856cf99..0779352593 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -103,6 +103,7 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS() m_plotViaOnMaskLayer = false; m_plotMode = FILLED; m_DXFplotPolygonMode = true; + m_DXFplotUnits = INCHES; m_useAuxOrigin = false; m_HPGLPenNum = 1; m_HPGLPenSpeed = 20; // this param is always in cm/s @@ -260,7 +261,9 @@ bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCom if( !aCompareOnlySavedPrms ) { if( m_DXFplotPolygonMode != aPcbPlotParams.m_DXFplotPolygonMode ) - return false; + return false; + if( m_DXFplotUnits != aPcbPlotParams.m_DXFplotUnits ) + return false; } if( m_useAuxOrigin != aPcbPlotParams.m_useAuxOrigin ) return false; diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h index f9ab3c21c1..cd92a80810 100644 --- a/pcbnew/pcb_plot_params.h +++ b/pcbnew/pcb_plot_params.h @@ -44,6 +44,13 @@ public: FULL_DRILL_SHAPE = 2 }; + // Must be in the same order as the drop-down list in the plot dialog + enum Units + { + INCHES = 0, + MILIMETERS = 1, + }; + private: // If true, do not plot NPTH pads // (mainly used to disable NPTH pads plotting on copper layers) @@ -60,6 +67,11 @@ private: */ bool m_DXFplotPolygonMode; + /** + * DXF format: Units to use when plotting the DXF + */ + Units m_DXFplotUnits; + /// Plot format type (chooses the driver to be used) PlotFormat m_format; @@ -196,6 +208,16 @@ public: void SetDXFPlotPolygonMode( bool aFlag ) { m_DXFplotPolygonMode = aFlag; } bool GetDXFPlotPolygonMode() const { return m_DXFplotPolygonMode; } + void SetDXFPlotUnits( Units aUnit ) + { + m_DXFplotUnits = aUnit; + } + + Units GetDXFPlotUnits() const + { + return m_DXFplotUnits; + } + void SetDrillMarksType( DrillMarksType aVal ) { m_drillMarks = aVal; } DrillMarksType GetDrillMarksType() const { return m_drillMarks; } diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 42394fca4b..2dafbb5208 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -1026,7 +1026,11 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, switch( aPlotOpts->GetFormat() ) { case PLOT_FORMAT_DXF: - plotter = new DXF_PLOTTER(); + DXF_PLOTTER* DXF_plotter; + DXF_plotter = new DXF_PLOTTER(); + DXF_plotter->SetUnits( static_cast( aPlotOpts->GetDXFPlotUnits() ) ); + + plotter = DXF_plotter; break; case PLOT_FORMAT_POST: