63
64
static const wxString traceFootprintLibrary( wxT( "KicadFootprintLib" ) );
65
// Helper function to print a float number without using scientific notation
67
// We want to avoid scientific notation in S-expr files (not easy to read)
68
// for floating numbers.
69
// So we cannot always just use the %g or the %f format to print a fp number
70
// this helper function uses the %f format when needed, or %g when %f is
71
// not well working and then removes trailing 0
73
std::string double2str( double aValue )
78
if( aValue != 0.0 && fabs( aValue ) <= 0.0001 )
80
// For these small values, %f works fine,
81
// and %g gives an exponent
82
len = sprintf( buf, "%.16f", aValue );
84
while( --len > 0 && buf[len] == '0' )
94
// For these values, %g works fine, and sometimes %f
95
// gives a bad value (try aValue = 1.222222222222, with %.16f format!)
96
len = sprintf( buf, "%.16g", aValue );
99
return std::string( buf, len );;
104
68
* Class FP_CACHE_ITEM
157
121
FP_CACHE( PCB_IO* aOwner, const wxString& aLibraryPath );
159
wxString GetPath() const { return m_lib_path.GetPath(); }
160
wxDateTime GetLastModificationTime() const { return m_mod_time; }
161
bool IsWritable() const { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
123
wxString GetPath() const { return m_lib_path.GetPath(); }
124
wxDateTime GetLastModificationTime() const { return m_mod_time; }
125
bool IsWritable() const { return m_lib_path.IsOk() && m_lib_path.IsDirWritable(); }
162
126
MODULE_MAP& GetModules() { return m_modules; }
164
128
// Most all functions in this class throw IO_ERROR exceptions. There are no
217
181
// Allow file output stream to go out of scope to close the file stream before
218
182
// renaming the file.
220
wxLogTrace( traceFootprintLibrary, wxT( "Creating temporary library file %s" ),
221
GetChars( tempFileName ) );
184
// wxLogTrace( traceFootprintLibrary, wxT( "Creating temporary library file %s" ), GetChars( tempFileName ) );
223
186
FILE_OUTPUTFORMATTER formatter( tempFileName );
254
217
wxString fpFileName;
255
218
wxString wildcard = wxT( "*." ) + KiCadFootprintFileExtension;
257
if( !dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
220
if( dir.GetFirst( &fpFileName, wildcard, wxDIR_FILES ) )
262
// reader now owns fp, will close on exception or return
263
FILE_LINE_READER reader( fpFileName );
265
m_owner->m_parser->SetLineReader( &reader );
267
std::string name = TO_UTF8( fpFileName );
269
m_modules.insert( name, new FP_CACHE_ITEM( (MODULE*) m_owner->m_parser->Parse(), fpFileName ) );
271
} while( dir.GetNext( &fpFileName ) );
273
// Remember the file modification time of library file when the
274
// cache snapshot was made, so that in a networked environment we will
275
// reload the cache as needed.
276
m_mod_time = GetLibModificationTime();
224
// prepend the libpath into fullPath
225
wxFileName fullPath( m_lib_path.GetPath(), fpFileName );
227
FILE_LINE_READER reader( fullPath.GetFullPath() );
229
m_owner->m_parser->SetLineReader( &reader );
231
std::string name = TO_UTF8( fpFileName );
233
m_modules.insert( name, new FP_CACHE_ITEM( (MODULE*) m_owner->m_parser->Parse(), fpFileName ) );
235
} while( dir.GetNext( &fpFileName ) );
237
// Remember the file modification time of library file when the
238
// cache snapshot was made, so that in a networked environment we will
239
// reload the cache as needed.
240
m_mod_time = GetLibModificationTime();
590
555
if( aBoard->GetDesignSettings().m_SolderPasteMarginRatio != 0 )
591
556
m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n",
592
double2str( aBoard->GetDesignSettings().m_SolderPasteMarginRatio ).c_str() );
557
Double2Str( aBoard->GetDesignSettings().m_SolderPasteMarginRatio ).c_str() );
594
559
m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n",
595
FMTIU( aBoard->GetOriginAxisPosition().x ).c_str(),
596
FMTIU( aBoard->GetOriginAxisPosition().y ).c_str() );
560
FMTIU( aBoard->GetAuxOrigin().x ).c_str(),
561
FMTIU( aBoard->GetAuxOrigin().y ).c_str() );
563
if( aBoard->GetGridOrigin().x || aBoard->GetGridOrigin().y )
564
m_out->Print( aNestLevel+1, "(grid_origin %s %s)\n",
565
FMTIU( aBoard->GetGridOrigin().x ).c_str(),
566
FMTIU( aBoard->GetGridOrigin().y ).c_str() );
598
568
m_out->Print( aNestLevel+1, "(visible_elements %X)\n",
599
569
aBoard->GetDesignSettings().GetVisibleElements() );
899
869
m_out->Print( aNestLevel, "(module %s", m_out->Quotew( aModule->GetLibRef() ).c_str() );
901
871
if( aModule->IsLocked() )
902
m_out->Print( aNestLevel, " locked" );
872
m_out->Print( 0, " locked" );
904
874
if( aModule->IsPlaced() )
905
m_out->Print( aNestLevel, " placed" );
875
m_out->Print( 0, " placed" );
907
877
formatLayer( aModule );
950
920
if( aModule->GetLocalSolderPasteMarginRatio() != 0 )
951
921
m_out->Print( aNestLevel+1, "(solder_paste_ratio %s)\n",
952
double2str( aModule->GetLocalSolderPasteMarginRatio() ).c_str() );
922
Double2Str( aModule->GetLocalSolderPasteMarginRatio() ).c_str() );
954
924
if( aModule->GetLocalClearance() != 0 )
955
925
m_out->Print( aNestLevel+1, "(clearance %s)\n",
1000
970
m_out->Quotew( t3D->m_Shape3DName ).c_str() );
1002
972
m_out->Print( aNestLevel+2, "(at (xyz %s %s %s))\n",
1003
double2str( t3D->m_MatPosition.x ).c_str(),
1004
double2str( t3D->m_MatPosition.y ).c_str(),
1005
double2str( t3D->m_MatPosition.z ).c_str() );
973
Double2Str( t3D->m_MatPosition.x ).c_str(),
974
Double2Str( t3D->m_MatPosition.y ).c_str(),
975
Double2Str( t3D->m_MatPosition.z ).c_str() );
1007
977
m_out->Print( aNestLevel+2, "(scale (xyz %s %s %s))\n",
1008
double2str( t3D->m_MatScale.x ).c_str(),
1009
double2str( t3D->m_MatScale.y ).c_str(),
1010
double2str( t3D->m_MatScale.z ).c_str() );
978
Double2Str( t3D->m_MatScale.x ).c_str(),
979
Double2Str( t3D->m_MatScale.y ).c_str(),
980
Double2Str( t3D->m_MatScale.z ).c_str() );
1012
982
m_out->Print( aNestLevel+2, "(rotate (xyz %s %s %s))\n",
1013
double2str( t3D->m_MatRotation.x ).c_str(),
1014
double2str( t3D->m_MatRotation.y ).c_str(),
1015
double2str( t3D->m_MatRotation.z ).c_str() );
983
Double2Str( t3D->m_MatRotation.x ).c_str(),
984
Double2Str( t3D->m_MatRotation.y ).c_str(),
985
Double2Str( t3D->m_MatRotation.z ).c_str() );
1017
987
m_out->Print( aNestLevel+1, ")\n" );
1187
1157
if( aPad->GetLocalSolderPasteMarginRatio() != 0 )
1188
1158
m_out->Print( aNestLevel+1, "(solder_paste_margin_ratio %s)\n",
1189
double2str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() );
1159
Double2Str( aPad->GetLocalSolderPasteMarginRatio() ).c_str() );
1191
1161
if( aPad->GetLocalClearance() != 0 )
1192
1162
m_out->Print( aNestLevel+1, "(clearance %s)\n",