kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #29171
[FIX BUG] pcbnew: plot dxf draws 2 lines instead 1 with the right width
Hello guys.
Please try my patches that fixes DXF plot bug
https://bugs.launchpad.net/kicad/+bug/1643330 .
Current behaviour:
Pcbnew plots drawings to DXF outline mode only.
After patch:
Pcbnew plots drawings to DXF copper/mask/adhes/paste layers in outline
mode and other layers (for importing in mechanical) with lines with
valid width.
>From 2d38579644eb233f04257bfbad15581a493846c3 Mon Sep 17 00:00:00 2001
From: Eldar Khayrullin <eldar.khayrullin@xxxxxxx>
Date: Sun, 16 Apr 2017 15:02:51 +0300
Subject: [PATCH 3/3] Pcbnew plots to DXF arcs with valid width
---
common/common_plotDXF_functions.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp
index fa58ffbbb..24061a003 100644
--- a/common/common_plotDXF_functions.cpp
+++ b/common/common_plotDXF_functions.cpp
@@ -435,6 +435,8 @@ void DXF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
if( radius <= 0 )
return;
+ SetCurrentLineWidth( width );
+
// In DXF, arcs are drawn CCW.
// In Kicad, arcs are CW or CCW
// If StAngle > EndAngle, it is CW. So transform it to CCW
@@ -445,13 +447,14 @@ void DXF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
DPOINT centre_dev = userToDeviceCoordinates( centre );
double radius_dev = userToDeviceSize( radius );
+ double pen_w = userToDeviceSize( GetCurrentLineWidth() );
// Emit a DXF ARC entity
wxString cname( m_currentColor.ToColour().GetAsString( wxC2S_CSS_SYNTAX ) );
fprintf( outputFile,
- "0\nARC\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n50\n%g\n51\n%g\n",
+ "0\nARC\n8\n%s\n10\n%g\n20\n%g\n39\n%g\n40\n%g\n50\n%g\n51\n%g\n",
TO_UTF8( cname ),
- centre_dev.x, centre_dev.y, radius_dev,
+ centre_dev.x, centre_dev.y, pen_w, radius_dev,
StAngle / 10.0, EndAngle / 10.0 );
}
--
2.11.0
>From ac7fc0520b6b0efcd105b83948b7568051b00236 Mon Sep 17 00:00:00 2001
From: Eldar Khayrullin <eldar.khayrullin@xxxxxxx>
Date: Sun, 16 Apr 2017 14:50:03 +0300
Subject: [PATCH 2/3] Pcbnew plots to DXF circles with valid width
---
common/common_plotDXF_functions.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp
index fe1ce3b25..fa58ffbbb 100644
--- a/common/common_plotDXF_functions.cpp
+++ b/common/common_plotDXF_functions.cpp
@@ -313,6 +313,7 @@ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int
{
wxASSERT( outputFile );
double radius = userToDeviceSize( diameter / 2 );
+ SetCurrentLineWidth( width );
DPOINT centre_dev = userToDeviceCoordinates( centre );
if( radius > 0 )
{
@@ -320,9 +321,10 @@ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int
if( !fill )
{
- fprintf( outputFile, "0\nCIRCLE\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n",
+ double pen_w = userToDeviceSize( GetCurrentLineWidth() );
+ fprintf( outputFile, "0\nCIRCLE\n8\n%s\n10\n%g\n20\n%g\n39\n%g\n40\n%g\n",
TO_UTF8( cname ),
- centre_dev.x, centre_dev.y, radius );
+ centre_dev.x, centre_dev.y, pen_w, radius );
}
if( fill == FILLED_SHAPE )
--
2.11.0
>From c156d30e5cedff26cf00c2ec4d62799c3b83fe32 Mon Sep 17 00:00:00 2001
From: Eldar Khayrullin <eldar.khayrullin@xxxxxxx>
Date: Sun, 16 Apr 2017 14:34:28 +0300
Subject: [PATCH 1/3] Pcbnew plots segments to DXF copper/mask/adhes/paste
layers in outline mode and other layers with lines with width
---
common/common_plotDXF_functions.cpp | 113 ++++++++----------------------------
include/plot_common.h | 5 +-
pcbnew/plot_board_layers.cpp | 15 +----
3 files changed, 27 insertions(+), 106 deletions(-)
diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp
index 088da297d..fe1ce3b25 100644
--- a/common/common_plotDXF_functions.cpp
+++ b/common/common_plotDXF_functions.cpp
@@ -44,7 +44,7 @@ static const double DXF_OBLIQUE_ANGLE = 15;
/**
* Set the scale/position for the DXF plot
- * The DXF engine doesn't support line widths and mirroring. The output
+ * The DXF engine doesn't support mirroring. The output
* coordinate system is in the first quadrant (in mm)
*/
void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
@@ -67,7 +67,7 @@ void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
iuPerDeviceUnit = 1.0 / aIusPerDecimil; // Gives a DXF in decimils
iuPerDeviceUnit *= 0.00254; // ... now in mm
- SetDefaultLineWidth( 0 ); // No line width on DXF
+ SetDefaultLineWidth( 0 );
m_plotMirror = false; // No mirroring on DXF
m_currentColor = COLOR4D::BLACK;
}
@@ -355,99 +355,22 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
if( aCornerList.size() <= 1 )
return;
- unsigned last = aCornerList.size() - 1;
-
- // Plot outlines with lines (thickness = 0) to define the polygon
- if( aWidth <= 0 )
- {
- MoveTo( aCornerList[0] );
-
- for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
- LineTo( aCornerList[ii] );
-
- // Close polygon if 'fill' requested
- if( aFill )
- {
- if( aCornerList[last] != aCornerList[0] )
- LineTo( aCornerList[0] );
- }
-
- PenFinish();
+ SetCurrentLineWidth( aWidth );
- return;
- }
-
-
- // if the polygon outline has thickness, and is not filled
- // (i.e. is a polyline) plot outlines with thick segments
- if( aWidth > 0 && !aFill )
- {
- MoveTo( aCornerList[0] );
-
- for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
- ThickSegment( aCornerList[ii-1], aCornerList[ii],
- aWidth, FILLED, NULL );
-
- return;
- }
-
- // The polygon outline has thickness, and is filled
- // Build and plot the polygon which contains the initial
- // polygon and its thick outline
- SHAPE_POLY_SET bufferOutline;
- SHAPE_POLY_SET bufferPolybase;
- const int circleToSegmentsCount = 16;
+ unsigned last = aCornerList.size() - 1;
- bufferPolybase.NewOutline();
+ MoveTo( aCornerList[0] );
- // enter outline as polygon:
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
- {
- TransformRoundedEndsSegmentToPolygon( bufferOutline,
- aCornerList[ii-1], aCornerList[ii], circleToSegmentsCount, aWidth );
- }
+ LineTo( aCornerList[ii] );
- // enter the initial polygon:
- for( unsigned ii = 0; ii < aCornerList.size(); ii++ )
+ // Close polygon if 'fill' requested
+ if( aFill )
{
- bufferPolybase.Append( aCornerList[ii] );
+ if( aCornerList[last] != aCornerList[0] )
+ LineTo( aCornerList[0] );
}
- // Merge polygons to build the polygon which contains the initial
- // polygon and its thick outline
-
- // create the outline which contains thick outline:
- bufferPolybase.BooleanAdd( bufferOutline, SHAPE_POLY_SET::PM_FAST );
- bufferPolybase.Fracture( SHAPE_POLY_SET::PM_FAST );
-
- if( bufferPolybase.OutlineCount() < 1 ) // should not happen
- return;
-
- const SHAPE_LINE_CHAIN& path = bufferPolybase.COutline( 0 );
-
- if( path.PointCount() < 2 ) // should not happen
- return;
-
- // Now, output the final polygon to DXF file:
- last = path.PointCount() - 1;
- VECTOR2I point = path.CPoint( 0 );
-
- wxPoint startPoint( point.x, point.y );
- MoveTo( startPoint );
-
- for( int ii = 1; ii < path.PointCount(); ii++ )
- {
- point = path.CPoint( ii );
- LineTo( wxPoint( point.x, point.y ) );
- }
-
- // Close polygon, if needed
- point = path.CPoint( last );
- wxPoint endPoint( point.x, point.y );
-
- if( endPoint != startPoint )
- LineTo( startPoint );
-
PenFinish();
}
@@ -464,11 +387,12 @@ void DXF_PLOTTER::PenTo( const wxPoint& pos, char plume )
if( penLastpos != pos && plume == 'D' )
{
+ double pen_w = userToDeviceSize( GetCurrentLineWidth() );
// DXF LINE
wxString cname( m_currentColor.ToColour().GetAsString( wxC2S_CSS_SYNTAX ) );
- fprintf( outputFile, "0\nLINE\n8\n%s\n10\n%g\n20\n%g\n11\n%g\n21\n%g\n",
+ fprintf( outputFile, "0\nLINE\n8\n%s\n10\n%g\n20\n%g\n11\n%g\n21\n%g\n39\n%g\n",
TO_UTF8( cname ),
- pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y );
+ pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y, pen_w );
}
penLastpos = pos;
}
@@ -482,11 +406,20 @@ void DXF_PLOTTER::SetDash( bool dashed )
// NOP for now
}
+void DXF_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
+{
+ if( aWidth >= 0 )
+ currentPenWidth = aWidth;
+ else
+ currentPenWidth = defaultPenWidth;
+}
void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth,
EDA_DRAW_MODE_T aPlotMode, void* aData )
{
- segmentAsOval( aStart, aEnd, aWidth, aPlotMode );
+ SetCurrentLineWidth( aWidth );
+ MoveTo( aStart );
+ FinishTo( aEnd );
}
/* Plot an arc in DXF format
diff --git a/include/plot_common.h b/include/plot_common.h
index 4fc54a537..8478b773d 100644
--- a/include/plot_common.h
+++ b/include/plot_common.h
@@ -1235,10 +1235,7 @@ public:
virtual bool EndPlot() override;
// For now we don't use 'thick' primitives, so no line width
- virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override
- {
- currentPenWidth = 0;
- }
+ virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
virtual void SetDefaultLineWidth( int width ) override
{
diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp
index 57137c168..7cbfa2912 100644
--- a/pcbnew/plot_board_layers.cpp
+++ b/pcbnew/plot_board_layers.cpp
@@ -223,10 +223,7 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
case F_SilkS:
case B_SilkS:
- if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
- PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
- else
- PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
+ PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
// Gerber: Subtract soldermask from silkscreen if enabled
if( aPlotter->GetPlotterType() == PLOT_FORMAT_GERBER
@@ -264,20 +261,14 @@ void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
plotOpt.SetSkipPlotNPTH_Pads( false );
plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
- if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
- PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
- else
- PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
+ PlotSilkScreen( aBoard, aPlotter, layer_mask, plotOpt );
break;
default:
plotOpt.SetSkipPlotNPTH_Pads( false );
plotOpt.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
- if( plotOpt.GetFormat() == PLOT_FORMAT_DXF )
- PlotLayerOutlines( aBoard, aPlotter, layer_mask, plotOpt );
- else
- PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
+ PlotStandardLayer( aBoard, aPlotter, layer_mask, plotOpt );
break;
}
}
--
2.11.0