Pcbnew: export IDF fixes

This commit is contained in:
unknown 2014-01-29 17:42:21 +01:00 committed by jean-pierre charras
parent 784e43f2e8
commit 690a001648
3 changed files with 99 additions and 30 deletions

View File

@ -326,6 +326,14 @@ static void idf_export_module( BOARD* aPcb, MODULE* aModule,
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;
@ -333,8 +341,6 @@ static void idf_export_module( BOARD* aPcb, MODULE* aModule,
bool top = ( aModule->GetLayer() == LAYER_N_BACK ) ? false : true;
refdes = TO_UTF8( aModule->GetReference() );
if( top )
{
locy = -locy;
@ -358,7 +364,7 @@ static void idf_export_module( BOARD* aPcb, MODULE* aModule,
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;
@ -376,22 +382,30 @@ bool Export_IDF3( BOARD* aPcb, const wxString& aFullFileName, double aUseThou )
SetLocaleTo_C_standard();
idfBoard.Setup( aPcb->GetFileName(), aFullFileName, aUseThou,
aPcb->GetDesignSettings().GetBoardThickness() );
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() );
// 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 );
// 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 );
// 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();
idfBoard.Finish();
}
catch( IO_ERROR ioe )
{
wxLogDebug( wxT( "An error occurred attemping export to IDFv3.\n\nError: %s" ),
GetChars( ioe.errorText ) );
}
SetLocaleTo_Default();

View File

@ -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_SEGMENT::SwapEnds( void )
}
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 @@ bool IDF_DRILL_DATA::Write( FILE* aLayoutFile )
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()
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 @@ bool IDF_BOARD::Setup( wxString aBoardName,
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 @@ bool IDF_BOARD::PlaceComponent( const wxString aComponentFile, const std::string
}
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 @@ bool IDF_COMP::parseRec2( const std::string aLine, bool& isNewItem )
return false;
}
teststr.str( "" );
teststr.clear();
teststr << geometry << "_" << partno;
isNewItem = parent->RegisterOutline( teststr.str() );
if( !parent->RegisterOutline( teststr.str() ) )
isNewItem = true;
return true;
}

View File

@ -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 @@ public:
}
// 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 @@ private:
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 @@ public:
bool PlaceComponent( const wxString aComponentFile, const std::string aRefDes,
double aXLoc, double aYLoc, double aZLoc,
double aRotation, bool isOnTop );
std::string GetRefDes( void );
};