← Back to team overview

kicad-developers team mailing list archive

DXF Import: new patch (fixes 2 problems)

 

The attached patch is pretty much the same as the previous
(dxf_polylines_20171001.patch) except for the addition of
a LOCALE_IO to switch to "C" locale before opening a DXF
file. Some people have reported problems importing DXF when
using language settings other than "English".

The fixes in this patch should also be applied to the stable branch
(though I haven't checked out 'stable' to see if these patches can be
applied without changes).

- Cirilo
From 8b97ac8ecc55659bcf132b09511058c9795d28be Mon Sep 17 00:00:00 2001
From: Cirilo Bernardo <cirilo.bernardo@xxxxxxxxx>
Date: Fri, 26 May 2017 01:44:46 +0000
Subject: [PATCH 1/3] Fixed line width bug for non-mm DXF units

---
 pcbnew/import_dxf/dxf2brd_items.cpp | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/pcbnew/import_dxf/dxf2brd_items.cpp b/pcbnew/import_dxf/dxf2brd_items.cpp
index dfd8272c9..0bba71106 100644
--- a/pcbnew/import_dxf/dxf2brd_items.cpp
+++ b/pcbnew/import_dxf/dxf2brd_items.cpp
@@ -120,7 +120,8 @@ void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData )
     segm->SetStart( start );
     wxPoint end( mapX( aData.secPoint.x ), mapY( aData.secPoint.y ) );
     segm->SetEnd( end );
-    segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) );
+    segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+                            : aData.thickness ) );
     m_newItemsList.push_back( segm );
 }
 
@@ -153,7 +154,7 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData )
         segm->SetStart( segment_startpoint );
         wxPoint segment_endpoint( mapX( vertex->basePoint.x ), mapY( vertex->basePoint.y ) );
         segm->SetEnd( segment_endpoint );
-        segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness
+        segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
                                 : aData.thickness ) );
         m_newItemsList.push_back( segm );
         segment_startpoint = segment_endpoint;
@@ -169,7 +170,7 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData )
         closing_segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
         closing_segm->SetStart( segment_startpoint );
         closing_segm->SetEnd( polyline_startpoint );
-        closing_segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness
+        closing_segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
                                 : aData.thickness ) );
         m_newItemsList.push_back( closing_segm );
     }
@@ -186,7 +187,7 @@ void DXF2BRD_CONVERTER::addLWPolyline(const DRW_LWPolyline& aData )
     wxRealPoint seg_start;
     wxRealPoint poly_start;
     double bulge = 0.0;
-    int lineWidth = mapDim( aData.thickness == 0 ? m_defaultThickness
+    int lineWidth = mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
                             : aData.thickness );
 
     for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ )
@@ -235,7 +236,8 @@ void DXF2BRD_CONVERTER::addCircle( const DRW_Circle& aData )
     segm->SetCenter( center );
     wxPoint circle_start( mapX( aData.basePoint.x + aData.radious ), mapY( aData.basePoint.y ) );
     segm->SetArcStart( circle_start );
-    segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) );
+    segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+                            : aData.thickness ) );
     m_newItemsList.push_back( segm );
 }
 
@@ -274,7 +276,8 @@ void DXF2BRD_CONVERTER::addArc( const DRW_Arc& data )
 
     segm->SetAngle( angle );
 
-    segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness : data.thickness ) );
+    segm->SetWidth( mapDim( data.thickness == 0 ? m_defaultThickness / m_DXF2mm
+                            : data.thickness ) );
     m_newItemsList.push_back( segm );
 }
 
@@ -384,7 +387,8 @@ void DXF2BRD_CONVERTER::addText( const DRW_Text& aData )
     // The 0.8 factor gives a better height/width ratio with our font
     textItem->SetTextWidth( mapDim( aData.height * 0.8 ) );
     textItem->SetTextHeight( mapDim( aData.height ) );
-    textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) );
+    textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+                                    : aData.thickness ) );
     textItem->SetText( text );
 
     m_newItemsList.push_back( static_cast< BOARD_ITEM* >( brdItem ) );
@@ -446,7 +450,8 @@ void DXF2BRD_CONVERTER::addMText( const DRW_MText& aData )
     // The 0.8 factor gives a better height/width ratio with our font
     textItem->SetTextWidth( mapDim( aData.height * 0.8 ) );
     textItem->SetTextHeight( mapDim( aData.height ) );
-    textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness : aData.thickness ) );
+    textItem->SetThickness( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+                                    : aData.thickness ) );
     textItem->SetText( text );
 
     // Initialize text justifications:
-- 
2.11.0


From ce74e16c234d961e2d057e8787406fe2c8f4e11f Mon Sep 17 00:00:00 2001
From: Cirilo Bernardo <cirilo.bernardo@xxxxxxxxx>
Date: Sun, 1 Oct 2017 08:53:40 +0000
Subject: [PATCH 2/3] DXF: fix import of Polyline with bulge

---
 pcbnew/import_dxf/dxf2brd_items.cpp | 61 ++++++++++++++++++-------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/pcbnew/import_dxf/dxf2brd_items.cpp b/pcbnew/import_dxf/dxf2brd_items.cpp
index 0bba71106..c24bbd62e 100644
--- a/pcbnew/import_dxf/dxf2brd_items.cpp
+++ b/pcbnew/import_dxf/dxf2brd_items.cpp
@@ -127,12 +127,18 @@ void DXF2BRD_CONVERTER::addLine( const DRW_Line& aData )
 
 void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData )
 {
-    // Currently, Pcbnew does not know polylines, for boards.
-    // So we have to convert a polyline to a set of segments.
-    // Obviously, the z coordinate is ignored
+    // Convert DXF Polylines into a series of KiCad Lines and Arcs.
+    // A Polyline (as opposed to a LWPolyline) may be a 3D line or
+    // even a 3D Mesh. The only type of Polyline which is guaranteed
+    // to import correctly is a 2D Polyline in X and Y, which is what
+    // we assume of all Polylines. The width used is the width of the
+    // Polyline; per-vertex line widths, if present, are ignored.
 
-    wxPoint polyline_startpoint;
-    wxPoint segment_startpoint;
+    wxRealPoint seg_start;
+    wxRealPoint poly_start;
+    double bulge = 0.0;
+    int lineWidth = mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
+                                                 : aData.thickness );
 
     for( unsigned ii = 0; ii < aData.vertlist.size(); ii++ )
     {
@@ -140,39 +146,32 @@ void DXF2BRD_CONVERTER::addPolyline(const DRW_Polyline& aData )
 
         if( ii == 0 )
         {
-            segment_startpoint.x = mapX( vertex->basePoint.x );
-            segment_startpoint.y = mapY( vertex->basePoint.y );
-            polyline_startpoint  = segment_startpoint;
+            seg_start.x = m_xOffset + vertex->basePoint.x * m_DXF2mm;
+            seg_start.y = m_yOffset - vertex->basePoint.y * m_DXF2mm;
+            bulge = vertex->bulge;
+            poly_start = seg_start;
             continue;
         }
 
-        DRAWSEGMENT* segm = ( m_useModuleItems ) ?
-                            static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) :
-                            new DRAWSEGMENT;
-
-        segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
-        segm->SetStart( segment_startpoint );
-        wxPoint segment_endpoint( mapX( vertex->basePoint.x ), mapY( vertex->basePoint.y ) );
-        segm->SetEnd( segment_endpoint );
-        segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
-                                : aData.thickness ) );
-        m_newItemsList.push_back( segm );
-        segment_startpoint = segment_endpoint;
+        wxRealPoint seg_end( m_xOffset + vertex->basePoint.x * m_DXF2mm,
+                             m_yOffset - vertex->basePoint.y * m_DXF2mm );
+
+        if( std::abs( bulge ) < MIN_BULGE )
+            insertLine( seg_start, seg_end, lineWidth );
+        else
+            insertArc( seg_start, seg_end, bulge, lineWidth );
+
+        bulge = vertex->bulge;
+        seg_start = seg_end;
     }
 
-    // Polyline flags bit 0 indicates closed (1) or open (0) polyline
+    // LWPolyline flags bit 0 indicates closed (1) or open (0) polyline
     if( aData.flags & 1 )
     {
-        DRAWSEGMENT* closing_segm = ( m_useModuleItems ) ?
-                                    static_cast< DRAWSEGMENT* >( new EDGE_MODULE( NULL ) ) :
-                                    new DRAWSEGMENT;
-
-        closing_segm->SetLayer( ToLAYER_ID( m_brdLayer ) );
-        closing_segm->SetStart( segment_startpoint );
-        closing_segm->SetEnd( polyline_startpoint );
-        closing_segm->SetWidth( mapDim( aData.thickness == 0 ? m_defaultThickness / m_DXF2mm
-                                : aData.thickness ) );
-        m_newItemsList.push_back( closing_segm );
+        if( std::abs( bulge ) < MIN_BULGE )
+            insertLine( seg_start, poly_start, lineWidth );
+        else
+            insertArc( seg_start, poly_start, bulge, lineWidth );
     }
 }
 
-- 
2.11.0


From 12ad98934915453e7c67c933a418cc38767be9cc Mon Sep 17 00:00:00 2001
From: Cirilo Bernardo <cirilo.bernardo@xxxxxxxxx>
Date: Mon, 2 Oct 2017 00:09:09 +0000
Subject: [PATCH 3/3] DXF: ensure "C" language environment.

---
 pcbnew/import_dxf/dxf2brd_items.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/pcbnew/import_dxf/dxf2brd_items.cpp b/pcbnew/import_dxf/dxf2brd_items.cpp
index 9101bef4a..6b175ee9f 100644
--- a/pcbnew/import_dxf/dxf2brd_items.cpp
+++ b/pcbnew/import_dxf/dxf2brd_items.cpp
@@ -47,6 +47,7 @@
 #include <class_edge_mod.h>
 #include <class_pcb_text.h>
 #include <class_text_mod.h>
+#include "common.h"
 #include <drw_base.h>
 
 // minimum bulge value before resorting to a line segment;
@@ -91,6 +92,7 @@ int DXF2BRD_CONVERTER::mapDim( double aDxfValue )
 
 bool DXF2BRD_CONVERTER::ImportDxfFile( const wxString& aFile )
 {
+    LOCALE_IO locale;
     dxfRW* dxf = new dxfRW( aFile.ToUTF8() );
     bool success = dxf->read( this, true );
 
-- 
2.11.0


Follow ups