← Back to team overview

kicad-developers team mailing list archive

bugfix patch for IDF exporter

 

The attached patch is a maintenance patch which fixes the following bugs:

1. *.emp file had the wrong information in the HEADER section (string was "BOARD_FILE" rather than "LIBRARY_FILE")

2. some missing entries + some duplicate entries in the *.emn file due to a bug in a logic test

3. for modules with no reference designator or "~", a unique designator is created to keep the MCAD happy.

4. some types of silent failures now throw an exception so the user knows something went wrong.

5. fixed IDF_BOARD::~IDF_BOARD() so there is no possibility of throwing an exception

- Cirilo
=== modified file 'pcbnew/exporters/export_idf.cpp'
--- pcbnew/exporters/export_idf.cpp	2014-01-25 12:23:29 +0000
+++ pcbnew/exporters/export_idf.cpp	2014-01-28 05:29:15 +0000
@@ -325,6 +325,14 @@
         if( !modfile->Is3DType( S3D_MASTER::FILE3D_IDF ) )
             continue;
 
+        if( refdes.empty() )
+        {
+            refdes = TO_UTF8( aModule->GetReference() );
+
+            if( refdes.empty() || !refdes.compare( "~" ) )
+                refdes = aIDFBoard.GetRefDes();
+        }
+
         double rotz = modfile->m_MatRotation.z + aModule->GetOrientation()/10.0;
         double locx = modfile->m_MatPosition.x;
         double locy = modfile->m_MatPosition.y;
@@ -332,8 +340,6 @@
 
         bool top = ( aModule->GetLayer() == LAYER_N_BACK ) ? false : true;
 
-        refdes = TO_UTF8( aModule->GetReference() );
-
         if( top )
         {
             locy = -locy;
@@ -357,7 +363,7 @@
         locx += aModule->GetPosition().x * scale + dx;
         locy += -aModule->GetPosition().y * scale + dy;
 
-        aIDFBoard.PlaceComponent(modfile->GetShape3DName(), refdes, locx, locy, locz, rotz, top);
+        aIDFBoard.PlaceComponent( modfile->GetShape3DName(), refdes, locx, locy, locz, rotz, top );
     }
 
     return;
@@ -375,22 +381,30 @@
 
     SetLocaleTo_C_standard();
 
-    idfBoard.Setup( aPcb->GetFileName(), aFullFileName, aUseThou,
-            aPcb->GetDesignSettings().GetBoardThickness() );
-
-    // set up the global offsets
-    EDA_RECT bbox = aPcb->ComputeBoundingBox( true );
-    idfBoard.SetOffset( -bbox.Centre().x * idfBoard.GetScale(),
-                         bbox.Centre().y * idfBoard.GetScale() );
-
-    // Export the board outline
-    idf_export_outline( aPcb, idfBoard );
-
-    // Output the drill holes and module (library) data.
-    for( MODULE* module = aPcb->m_Modules; module != 0; module = module->Next() )
-        idf_export_module( aPcb, module, idfBoard );
-
-    idfBoard.Finish();
+    try
+    {
+        idfBoard.Setup( aPcb->GetFileName(), aFullFileName, aUseThou,
+                        aPcb->GetDesignSettings().GetBoardThickness() );
+
+        // set up the global offsets
+        EDA_RECT bbox = aPcb->ComputeBoundingBox( true );
+        idfBoard.SetOffset( -bbox.Centre().x * idfBoard.GetScale(),
+                            bbox.Centre().y * idfBoard.GetScale() );
+
+        // Export the board outline
+        idf_export_outline( aPcb, idfBoard );
+
+        // Output the drill holes and module (library) data.
+        for( MODULE* module = aPcb->m_Modules; module != 0; module = module->Next() )
+            idf_export_module( aPcb, module, idfBoard );
+
+        idfBoard.Finish();
+    }
+    catch( IO_ERROR ioe )
+    {
+        wxLogDebug( wxT( "An error occurred attemping export to IDFv3.\n\nError: %s" ),
+                    GetChars( ioe.errorText ) );
+    }
 
     SetLocaleTo_Default();
 

=== modified file 'pcbnew/exporters/idf.cpp'
--- pcbnew/exporters/idf.cpp	2014-01-25 12:23:29 +0000
+++ pcbnew/exporters/idf.cpp	2014-01-28 05:18:45 +0000
@@ -3,7 +3,7 @@
  *
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2013  Cirilo Bernardo
+ * Copyright (C) 2013-2014  Cirilo Bernardo
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -43,6 +43,7 @@
 #include <wx/file.h>
 #include <wx/filename.h>
 #include <macros.h>
+#include <richio.h>
 #include <idf.h>
 #include <build_version.h>
 
@@ -311,6 +312,39 @@
 }
 
 
+void IDF_OUTLINE::push( IDF_SEGMENT* item )
+{
+    if( !outline.empty() )
+    {
+        if( item->IsCircle() )
+        {
+            // not allowed
+            wxString msg = wxT( "INVALID GEOMETRY: a circle is being added to a non-empty outline" );
+            THROW_IO_ERROR( msg );
+        }
+        else
+        {
+            if( outline.back()->IsCircle() )
+            {
+                // we can't add lines to a circle
+                wxString msg = wxT( "INVALID GEOMETRY: a line is being added to a circular outline" );
+                THROW_IO_ERROR( msg );
+            }
+            else if( !item->MatchesStart( outline.back()->endPoint ) )
+            {
+                // startPoint[N] != endPoint[N -1]
+                wxString msg = wxT( "INVALID GEOMETRY: disjoint segments" );
+                THROW_IO_ERROR( msg );
+            }
+        }
+    }
+
+    outline.push_back( item );
+    dir += ( outline.back()->endPoint.x - outline.back()->startPoint.x )
+           * ( outline.back()->endPoint.y + outline.back()->startPoint.y );
+}
+
+
 IDF_DRILL_DATA::IDF_DRILL_DATA( double aDrillDia, double aPosX, double aPosY,
         IDF3::KEY_PLATING aPlating,
         const std::string aRefDes,
@@ -452,6 +486,7 @@
 
 IDF_BOARD::IDF_BOARD()
 {
+    refdesIndex = 0;
     outlineIndex = 0;
     scale = 1e-6;
     boardThickness = 1.6;       // default to 1.6mm thick boards
@@ -466,7 +501,20 @@
 
 IDF_BOARD::~IDF_BOARD()
 {
-    Finish();
+    // simply close files if they are open; do not attempt
+    // anything else since a previous exception may have left
+    // data in a bad state.
+    if( layoutFile != NULL )
+    {
+        fclose( layoutFile );
+        layoutFile = NULL;
+    }
+
+    if( libFile != NULL )
+    {
+        fclose( libFile );
+        libFile = NULL;
+    }
 }
 
 
@@ -525,7 +573,7 @@
             TO_UTF8( brdname.GetFullName() ), useThou ? "THOU" : "MM" );
 
     fprintf( libFile, ".HEADER\n"
-                      "BOARD_FILE 3.0 \"Created by KiCad %s\" %.4d/%.2d/%.2d.%.2d:%.2d:%.2d 1\n"
+                      "LIBRARY_FILE 3.0 \"Created by KiCad %s\" %.4d/%.2d/%.2d.%.2d:%.2d:%.2d 1\n"
                       ".END_HEADER\n\n",
             TO_UTF8( GetBuildVersion() ),
             tdate.GetYear(), tdate.GetMonth() + 1, tdate.GetDay(),
@@ -775,6 +823,16 @@
 }
 
 
+std::string IDF_BOARD::GetRefDes( void )
+{
+    std::ostringstream ostr;
+
+    ostr << "NOREFDES_" << refdesIndex++;
+
+    return ostr.str();
+}
+
+
 bool IDF_BOARD::WriteDrills( void )
 {
     if( !layoutFile )
@@ -1500,9 +1558,11 @@
         return false;
     }
 
-    teststr.str( "" );
+    teststr.clear();
     teststr << geometry << "_" << partno;
-    isNewItem = parent->RegisterOutline( teststr.str() );
+
+    if( !parent->RegisterOutline( teststr.str() ) )
+        isNewItem = true;
 
     return true;
 }

=== modified file 'pcbnew/exporters/idf.h'
--- pcbnew/exporters/idf.h	2014-01-25 12:23:29 +0000
+++ pcbnew/exporters/idf.h	2014-01-28 04:23:41 +0000
@@ -5,7 +5,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2013  Cirilo Bernardo
+ * Copyright (C) 2013-2014  Cirilo Bernardo
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -292,15 +292,7 @@
     }
 
     // push a segment onto the internal list
-    void push( IDF_SEGMENT* item )
-    {
-        // XXX - check that startPoint[N] == endPoint[N -1], otherwise THROW
-        // XXX - a Circle must stand alone; if we add to a circle or add a
-        // circle to an existing list, we should throw an exception.
-        outline.push_back( item );
-        dir += ( outline.back()->endPoint.x - outline.back()->startPoint.x )
-               * ( outline.back()->endPoint.y + outline.back()->startPoint.y );
-    }
+    void push( IDF_SEGMENT* item );
 };
 
 
@@ -459,6 +451,7 @@
     double scale;                           ///< scale from KiCad IU to IDF output units
     double boardThickness;                  ///< total thickness of the PCB
     bool hasBrdOutlineHdr;                  ///< true when a board outline header has been written
+    int refdesIndex;                        ///< index to generate REFDES for modules which have none
 
     double offsetX;                         ///< offset to roughly center the board on the world origin
     double offsetY;
@@ -538,6 +531,8 @@
     bool PlaceComponent( const wxString aComponentFile, const std::string aRefDes,
                          double aXLoc, double aYLoc, double aZLoc,
                          double aRotation, bool isOnTop );
+
+    std::string GetRefDes( void );
 };
 
 


Follow ups