← Back to team overview

kicad-developers team mailing list archive

proposed patch, bugs 1261583 and 1236583

 

Following discussions on the bugs 1261583 and 1236583 I have attached a possible solution.

1. An optional argument has been added to fillBOUNDARY() to allow the user to specify an acceptable error in the boundary segment points. The default value is '0' and specctra export routines which call fillBOUNDARY() will operate as before and without modification.

2. GetBoardPolygonOutlines() invokes fillBOUNDARY() with the optional argument equal to 1 mil. This closes bugs 1261583 and 1236583.

The patch was tested by importing the DXF provided in bug report 1261583 and the 3D viewer now displays the correct outline while a specctra export throws an exception as it previously did. This should also close bug 1236583 since the error in that case was about .02 mil.

The only remaining question is whether the old specctra behavior should be maintained or if it is sensible to remove the optional argument and agree on a non-zero value for use in the proximity test on the outline. The value need not be specified in mils either; we can use the internal units to specify a smaller allowable error.

- Cirilo
=== modified file 'pcbnew/specctra.h'
--- pcbnew/specctra.h	2013-10-04 08:42:09 +0000
+++ pcbnew/specctra.h	2013-12-18 21:26:24 +0000
@@ -3752,8 +3752,9 @@
      * in the specctra element tree.
      * @param aBoard The BOARD to get information from in order to make the BOUNDARY.
      * @param aBoundary The empty BOUNDARY to fill in.
+     * @param aRadius Radius, in mils, for the outline's point closeness test
      */
-    void fillBOUNDARY( BOARD* aBoard, BOUNDARY* aBoundary ) throw( IO_ERROR );
+    void fillBOUNDARY( BOARD* aBoard, BOUNDARY* aBoundary, int aRadius = 0 ) throw( IO_ERROR );
 
     /**
      * Function makeIMAGE

=== modified file 'pcbnew/specctra_export.cpp'
--- pcbnew/specctra_export.cpp	2013-10-28 20:34:06 +0000
+++ pcbnew/specctra_export.cpp	2013-12-18 21:29:08 +0000
@@ -876,7 +876,7 @@
 }
 
 
-void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) throw( IO_ERROR )
+void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary, int aRadius ) throw( IO_ERROR )
 {
     TYPE_COLLECTOR  items;
     unsigned        prox;       // a proximity BIU metric, not an accurate distance
@@ -1008,7 +1008,9 @@
 
         // Set maximum proximity threshold for point to point nearness metric for
         // board perimeter only, not interior keepouts yet.
-        prox = Mils2iu( 0 );
+        if( aRadius < 0 )
+            aRadius = 0;
+        prox = Mils2iu( aRadius );
 
         // Output the Edge.Cuts perimeter as circle or polygon.
         if( graphic->GetShape() == S_CIRCLE )
@@ -1098,8 +1100,16 @@
                     break;
                 }
 
-                if( close_enough( startPt, prevPt, prox ) )     // the polygon is closed.
+                if( close_enough( startPt, prevPt, prox ) )
+                {
+                    // the polygon is closed.
+                    if( aRadius && path->GetPoints().size() > 1 )
+                    {
+                        path->GetPoints().pop_back();
+                        path->AppendPoint( mapPt( startPt ) );
+                    }
                     break;
+                }
 
                 graphic = findPoint( prevPt, &items, prox );
 
@@ -1283,7 +1293,7 @@
 
     try
     {
-        fillBOUNDARY( aBoard, boundary );
+        fillBOUNDARY( aBoard, boundary, 1 );
         std::vector<double> buffer;
         boundary->GetCorners( buffer );