kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #12055
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