kicad/pcbnew/gen_modules_placefile.cpp

570 lines
16 KiB
C++
Raw Normal View History

/**
* @file gen_modules_placefile.cpp
*/
/*
2007-08-23 04:28:46 +00:00
* 1 - create ascii files for automatic placement of smd components
* 2 - create a module report (pos and module descr) (ascii file)
*/
#include "fctsys.h"
#include "confirm.h"
#include "kicad_string.h"
#include "gestfich.h"
2009-07-30 11:04:07 +00:00
#include "wxPcbStruct.h"
#include "trigo.h"
#include "appl_wxstruct.h"
#include "build_version.h"
#include "macros.h"
#include "class_board.h"
#include "class_module.h"
#include "class_drawsegment.h"
#include "pcbnew.h"
class LIST_MOD /* Can list the elements of useful modules. */
{
public:
2007-08-23 04:28:46 +00:00
MODULE* m_Module;
const wxChar* m_Reference;
const wxChar* m_Value;
};
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
#if 1
static const double conv_unit = 0.0001; // units = INCHES
#else
static const double conv_unit = 0.000254; // units = mm
#endif
static wxPoint File_Place_Offset; /* Offset coordinates for generated file. */
2007-08-23 04:28:46 +00:00
static void WriteDrawSegmentPcb( DRAWSEGMENT* PtDrawSegment, FILE* rptfile );
/* Sort function use by GenereModulesPosition() */
static int ListeModCmp( const void* o1, const void* o2 )
{
LIST_MOD* ref = (LIST_MOD*) o1;
LIST_MOD* cmp = (LIST_MOD*) o2;
return StrNumCmp( ref->m_Reference, cmp->m_Reference, 16 );
}
#if defined(DEBUG)
/**
* Function HasNonSMDPins
* returns true if the given module has any non smd pins, such as through hole
* and therefore cannot be placed automatically.
*/
static bool HasNonSMDPins( MODULE* aModule )
{
D_PAD* pad;
for( pad = aModule->m_Pads; pad; pad = pad->Next() )
{
if( pad->m_Attribut != PAD_SMD )
return true;
}
return false;
}
#endif
void PCB_EDIT_FRAME::GenModulesPosition( wxCommandEvent& event )
{
bool doBoardBack = false;
MODULE* module;
LIST_MOD* list = NULL;
char line[1024];
wxFileName fnFront;
wxFileName fnBack;
wxString msg;
wxString frontLayerName;
wxString backLayerName;
wxString Title;
FILE* fpFront = 0;
FILE* fpBack = 0;
bool switchedLocale = false;
2007-08-23 04:28:46 +00:00
File_Place_Offset = GetOriginAxisPosition();
2007-08-23 04:28:46 +00:00
/* Calculating the number of useful modules (CMS attribute, not VIRTUAL) */
int moduleCount = 0;
for( module = GetBoard()->m_Modules; module; module = module->Next() )
2007-08-23 04:28:46 +00:00
{
if( module->m_Attributs & MOD_VIRTUAL )
{
D( printf( "skipping module %s because it's virtual\n",
TO_UTF8( module->GetReference() ) );)
2007-08-23 04:28:46 +00:00
continue;
}
if( ( module->m_Attributs & MOD_CMS ) == 0 )
{
#if 1 && defined(DEBUG) // enable this code to fix a bunch of mis-labeled modules:
if( !HasNonSMDPins( module ) )
{
// all module's pins are SMD, mark the part for pick and place
module->m_Attributs |= MOD_CMS;
}
else
{
printf( "skipping %s because its attribute is not CMS and it has non SMD pins\n",
TO_UTF8(module->GetReference()) );
continue;
}
#else
2007-08-23 04:28:46 +00:00
continue;
#endif
}
if( module->GetLayer() == LAYER_N_BACK )
doBoardBack = true;
moduleCount++;
2007-08-23 04:28:46 +00:00
}
if( moduleCount == 0 )
2007-08-23 04:28:46 +00:00
{
DisplayError( this, _( "No modules for automated placement." ) );
return;
2007-08-23 04:28:46 +00:00
}
wxString boardFilePath = ( (wxFileName) GetScreen()->GetFileName()).GetPath();
wxDirDialog dirDialog( this, _( "Select Output Directory" ), boardFilePath );
if( dirDialog.ShowModal() == wxID_CANCEL )
return;
fnFront = GetScreen()->GetFileName();
fnFront.SetPath( dirDialog.GetPath() );
frontLayerName = GetBoard()->GetLayerName( LAYER_N_FRONT );
fnFront.SetName( fnFront.GetName() + wxT( "_" ) + frontLayerName );
fnFront.SetExt( wxT( "pos") );
fpFront = wxFopen( fnFront.GetFullPath(), wxT( "wt" ) );
if( fpFront == 0 )
2007-08-23 04:28:46 +00:00
{
msg = _( "Unable to create " ) + fnFront.GetFullPath();
DisplayError( this, msg );
goto exit;
2007-08-23 04:28:46 +00:00
}
if( doBoardBack )
2007-08-23 04:28:46 +00:00
{
fnBack = GetScreen()->GetFileName();
fnBack.SetPath( dirDialog.GetPath() );
backLayerName = GetBoard()->GetLayerName( LAYER_N_BACK );
fnBack.SetName( fnBack.GetName() + wxT( "_" ) + backLayerName );
fnBack.SetExt( wxT( "pos" ) );
fpBack = wxFopen( fnBack.GetFullPath(), wxT( "wt" ) );
if( fpBack == 0 )
2007-08-23 04:28:46 +00:00
{
msg = _( "Unable to create " ) + fnBack.GetFullPath();
2007-08-23 04:28:46 +00:00
DisplayError( this, msg );
goto exit;
2007-08-23 04:28:46 +00:00
}
}
// Switch the locale to standard C (needed to print floating point
// numbers like 1.3)
2008-06-06 16:39:45 +00:00
SetLocaleTo_C_standard( );
switchedLocale = true;
2007-08-23 04:28:46 +00:00
// Display results
ClearMsgPanel();
AppendMsgPanel( _( "Component side place file:" ), fnFront.GetFullPath(), BLUE );
2007-08-23 04:28:46 +00:00
if( doBoardBack )
AppendMsgPanel( _( "Copper side place file:" ), fnBack.GetFullPath(), BLUE );
2007-08-23 04:28:46 +00:00
msg.Empty(); msg << moduleCount;
AppendMsgPanel( _( "Module count" ), msg, RED );
2007-08-23 04:28:46 +00:00
// Sort the list of modules alphabetically
list = new LIST_MOD[moduleCount];
2007-08-23 04:28:46 +00:00
module = GetBoard()->m_Modules;
for( int ii = 0; module; module = module->Next() )
2007-08-23 04:28:46 +00:00
{
if( module->m_Attributs & MOD_VIRTUAL )
2007-08-23 04:28:46 +00:00
continue;
if( (module->m_Attributs & MOD_CMS) == 0 )
2007-08-23 04:28:46 +00:00
continue;
list[ii].m_Module = module;
list[ii].m_Reference = module->m_Reference->m_Text;
list[ii].m_Value = module->m_Value->m_Text;
2007-08-23 04:28:46 +00:00
ii++;
}
qsort( list, moduleCount, sizeof(LIST_MOD), ListeModCmp );
2007-08-23 04:28:46 +00:00
// Write file header
sprintf( line, "### Module positions - created on %s ###\n", TO_UTF8( DateAndTime() ) );
fputs( line, fpFront );
if( doBoardBack )
fputs( line, fpBack );
2007-08-23 04:28:46 +00:00
Title = wxGetApp().GetAppName() + wxT( " " ) + GetBuildVersion();
sprintf( line, "### Printed by Pcbnew version %s\n", TO_UTF8( Title ) );
fputs( line, fpFront );
if( doBoardBack )
fputs( line, fpBack );
2007-08-23 04:28:46 +00:00
sprintf( line, "## Unit = inches, Angle = deg.\n" );
fputs( line, fpFront );
if( doBoardBack )
fputs( line, fpBack );
2007-08-23 04:28:46 +00:00
sprintf( line, "## Side : %s\n", TO_UTF8( frontLayerName ) );
fputs( line, fpFront );
2007-08-23 04:28:46 +00:00
if( doBoardBack )
2007-08-23 04:28:46 +00:00
{
sprintf( line, "## Side : %s\n", TO_UTF8( backLayerName ) );
fputs( line, fpBack );
2007-08-23 04:28:46 +00:00
}
sprintf( line,
2007-08-23 04:28:46 +00:00
"# Ref Val PosX PosY Rot Side\n" );
fputs( line, fpFront );
if( doBoardBack )
fputs( line, fpBack );
2007-08-23 04:28:46 +00:00
for( int ii = 0; ii < moduleCount; ii++ )
2007-08-23 04:28:46 +00:00
{
wxPoint module_pos;
wxString ref = list[ii].m_Reference;
wxString val = list[ii].m_Value;
sprintf( line, "%-8.8s %-16.16s ", TO_UTF8( ref ), TO_UTF8( val ) );
2007-08-23 04:28:46 +00:00
module_pos = list[ii].m_Module->m_Pos;
2007-08-23 04:28:46 +00:00
module_pos.x -= File_Place_Offset.x;
module_pos.y -= File_Place_Offset.y;
char* text = line + strlen( line );
2007-08-23 04:28:46 +00:00
sprintf( text, " %9.4f %9.4f %8.1f ",
2009-03-15 21:11:12 +00:00
module_pos.x * conv_unit,
module_pos.y * conv_unit,
double(list[ii].m_Module->m_Orient) / 10 );
2007-08-23 04:28:46 +00:00
int layer = list[ii].m_Module->GetLayer();
wxASSERT( layer==LAYER_N_FRONT || layer==LAYER_N_BACK );
if( layer == LAYER_N_FRONT )
2007-08-23 04:28:46 +00:00
{
strcat( line, TO_UTF8( frontLayerName ) );
strcat( line, "\n" );
fputs( line, fpFront );
2007-08-23 04:28:46 +00:00
}
else if( layer == LAYER_N_BACK )
2007-08-23 04:28:46 +00:00
{
strcat( line, TO_UTF8( backLayerName ) );
strcat( line, "\n" );
fputs( line, fpBack );
2007-08-23 04:28:46 +00:00
}
}
// Write EOF
fputs( "## End\n", fpFront );
if( doBoardBack )
fputs( "## End\n", fpBack );
msg = _( "Module position files created:" );
msg.Append( wxT( "\n\n" ) + frontLayerName + wxT( ":\n" ) );
msg.Append( fnFront.GetFullPath() );
if( doBoardBack )
{
msg.Append( wxT( "\n\n" ) + backLayerName + wxT( ":\n" ) );
msg.Append( fnBack.GetFullPath() );
}
wxMessageBox( msg, _( "Module Position File" ), wxICON_INFORMATION );
exit: // the only safe way out of here, no returns please.
if( list )
delete[] list;
if( switchedLocale )
SetLocaleTo_Default( ); // revert to the current locale
if( fpFront )
fclose( fpFront );
if( fpBack )
fclose( fpBack );
}
/* Print a module report.
2007-08-23 04:28:46 +00:00
*/
void PCB_EDIT_FRAME::GenModuleReport( wxCommandEvent& event )
{
2007-08-23 04:28:46 +00:00
MODULE* Module;
D_PAD* pad;
char line[1024];
wxFileName fn;
wxString fnFront, msg;
2007-08-23 04:28:46 +00:00
FILE* rptfile;
wxPoint module_pos;
File_Place_Offset = wxPoint( 0, 0 );
wxString boardFilePath = ( (wxFileName) GetScreen()->GetFileName()).GetPath();
wxDirDialog dirDialog( this, _( "Select Output Directory" ), boardFilePath );
if( dirDialog.ShowModal() == wxID_CANCEL )
return;
fn = GetScreen()->GetFileName();
fn.SetPath( dirDialog.GetPath() );
fn.SetExt( wxT( "rpt" ) );
2007-08-23 04:28:46 +00:00
rptfile = wxFopen( fn.GetFullPath(), wxT( "wt" ) );
2007-08-23 04:28:46 +00:00
if( rptfile == NULL )
{
msg = _( "Unable to create " ) + fn.GetFullPath();
DisplayError( this, msg );
return;
2007-08-23 04:28:46 +00:00
}
// Switch the locale to standard C (needed to print floating point
// numbers like 1.3)
SetLocaleTo_C_standard();
2007-08-23 04:28:46 +00:00
/* Generate header file comments.) */
sprintf( line, "## Module report - date %s\n", TO_UTF8( DateAndTime() ) );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
wxString Title = wxGetApp().GetAppName() + wxT( " " ) + GetBuildVersion();
sprintf( line, "## Created by Pcbnew version %s\n", TO_UTF8( Title ) );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
fputs( "## Unit = inches, Angle = deg.\n", rptfile );
fputs( "##\n", rptfile );
fputs( "\n$BeginDESCRIPTION\n", rptfile );
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
EDA_RECT bbbox = GetBoard()->ComputeBoundingBox();
2007-08-23 04:28:46 +00:00
fputs( "\n$BOARD\n", rptfile );
fputs( "unit INCH\n", rptfile );
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
sprintf( line, "upper_left_corner %9.6f %9.6f\n",
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
bbbox.GetX() * conv_unit,
bbbox.GetY() * conv_unit );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
sprintf( line, "lower_right_corner %9.6f %9.6f\n",
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
bbbox.GetRight() * conv_unit,
bbbox.GetBottom() * conv_unit );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
fputs( "$EndBOARD\n\n", rptfile );
Module = (MODULE*) GetBoard()->m_Modules;
2007-08-23 04:28:46 +00:00
for( ; Module != NULL; Module = Module->Next() )
{
2011-03-25 20:07:27 +00:00
sprintf( line, "$MODULE %s\n", EscapedUTF8( Module->m_Reference->m_Text ).c_str() );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
2011-03-25 20:07:27 +00:00
sprintf( line, "reference %s\n", EscapedUTF8( Module->m_Reference->m_Text ).c_str() );
fputs( line, rptfile );
2011-03-25 20:07:27 +00:00
sprintf( line, "value %s\n", EscapedUTF8( Module->m_Value->m_Text ).c_str() );
fputs( line, rptfile );
2011-03-25 20:07:27 +00:00
sprintf( line, "footprint %s\n", EscapedUTF8( Module->m_LibRef ).c_str() );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
msg = wxT( "attribut" );
2007-08-23 04:28:46 +00:00
if( Module->m_Attributs & MOD_VIRTUAL )
msg += wxT( " virtual" );
2007-08-23 04:28:46 +00:00
if( Module->m_Attributs & MOD_CMS )
msg += wxT( " smd" );
2007-08-23 04:28:46 +00:00
if( ( Module->m_Attributs & (MOD_VIRTUAL | MOD_CMS) ) == 0 )
msg += wxT( " none" );
2007-08-23 04:28:46 +00:00
msg += wxT( "\n" );
fputs( TO_UTF8( msg ), rptfile );
2007-08-23 04:28:46 +00:00
module_pos = Module->m_Pos;
module_pos.x -= File_Place_Offset.x;
module_pos.y -= File_Place_Offset.y;
2009-03-15 21:11:12 +00:00
sprintf( line, "position %9.6f %9.6f\n",
2009-03-15 21:11:12 +00:00
module_pos.x * conv_unit,
module_pos.y * conv_unit );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
2009-03-15 21:11:12 +00:00
sprintf( line, "orientation %.2f\n", (double) Module->m_Orient / 10 );
if( Module->GetLayer() == LAYER_N_FRONT )
strcat( line, "layer component\n" );
else if( Module->GetLayer() == LAYER_N_BACK )
strcat( line, "layer copper\n" );
2007-08-23 04:28:46 +00:00
else
strcat( line, "layer other\n" );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
Module->Write_3D_Descr( rptfile );
for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() )
{
2011-12-16 17:03:25 +00:00
fprintf( rptfile, "$PAD \"%s\"\n", TO_UTF8( pad->GetPadName() ) );
sprintf( line, "position %9.6f %9.6f\n",
pad->m_Pos0.x * conv_unit,
pad->m_Pos0.y * conv_unit );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
sprintf( line, "size %9.6f %9.6f\n",
pad->m_Size.x * conv_unit,
pad->m_Size.y * conv_unit );
fputs( line, rptfile );
sprintf( line, "drill %9.6f\n", pad->m_Drill.x * conv_unit );
fputs( line, rptfile );
sprintf( line, "shape_offset %9.6f %9.6f\n",
pad->m_Offset.x * conv_unit,
pad->m_Offset.y * conv_unit );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
sprintf( line, "orientation %.2f\n",
double(pad->m_Orient - Module->m_Orient) / 10 );
fputs( line, rptfile );
const char* shape_name[6] = { "??? ", "Circ", "Rect", "Oval", "trap", "spec" };
sprintf( line, "Shape %s\n", shape_name[pad->m_PadShape] );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
int layer = 0;
if( pad->m_layerMask & LAYER_BACK )
2007-08-23 04:28:46 +00:00
layer = 1;
if( pad->m_layerMask & LAYER_FRONT )
2007-08-23 04:28:46 +00:00
layer |= 2;
const char* layer_name[4] = { "??? ", "copper", "component", "all" };
sprintf( line, "Layer %s\n", layer_name[layer] );
fputs( line, rptfile );
2007-08-23 04:28:46 +00:00
fprintf( rptfile, "$EndPAD\n" );
}
fprintf( rptfile, "$EndMODULE %s\n\n",
TO_UTF8(Module->m_Reference->m_Text ) );
2007-08-23 04:28:46 +00:00
}
/* Write board Edges */
EDA_ITEM* PtStruct;
for( PtStruct = GetBoard()->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Next() )
2007-08-23 04:28:46 +00:00
{
if( PtStruct->Type() != PCB_LINE_T )
2007-08-23 04:28:46 +00:00
continue;
2007-08-23 04:28:46 +00:00
if( ( (DRAWSEGMENT*) PtStruct )->GetLayer() != EDGE_N )
continue;
2007-08-23 04:28:46 +00:00
WriteDrawSegmentPcb( (DRAWSEGMENT*) PtStruct, rptfile );
}
/* Generate EOF. */
2007-08-23 04:28:46 +00:00
fputs( "$EndDESCRIPTION\n", rptfile );
fclose( rptfile );
SetLocaleTo_Default( ); // revert to the current locale
msg = _( "Module report file created:" );
msg.Append( wxT( "\n" ) + fn.GetFullPath() );
wxMessageBox( msg, _( "Module Report" ), wxICON_INFORMATION );
}
/* Output to rpt file a segment type from the PCB drawing.
* The contours are of different types:
* Segment
* Circle
* Arc
2007-08-23 04:28:46 +00:00
*/
void WriteDrawSegmentPcb( DRAWSEGMENT* PtDrawSegment, FILE* rptfile )
{
++PCBNew * Removed Pcb_Frame argument from BOARD() constructor, since it precludes having a BOARD being edited by more than one editor, it was a bad design. And this meant removing m_PcbFrame from BOARD. * removed BOARD::SetWindowFrame(), and BOARD::m_PcbFrame * Removed the global BOARD_DESIGN_SETTINGS which was in class_board.cpp * added BOARD_DESIGN_SETTINGS to the BOARD class, a full instance * a couple dialogs now only change BOARD_DESIGN_SETTINGS when OK is pressed, such as dialog_mask_clearance, dialog_drc, etc. * Removed common/pcbcommon.cpp's int g_CurrentVersionPCB = 1 and replaced it with build_version.h's #define BOARD_FILE_VERSION, although there may be a better place for this constant. * Made the public functions in PARAM_CFG_ARRAY be type const. void SaveParam(..) const and void ReadParam(..) const * PARAM_CFG_BASE now has virtual destructor since we have various way of destroying the derived class and boost::ptr_vector must be told about this. * Pass const PARAM_CFG_ARRAY& instead of PARAM_CFG_ARRAY so that we can use an automatic PARAM_CFG_ARRAY which is on the stack.\ * PCB_EDIT_FRAME::GetProjectFileParameters() may no longer cache the array, since it has to access the current BOARD and the BOARD can change. Remember BOARD_DESIGN_SETTINGS are now in the BOARD. * Made the m_BoundingBox member private, this was a brutally hard task, and indicative of the lack of commitment to accessors and object oriented design on the part of KiCad developers. We must do better. Added BOARD::GetBoundingBox, SetBoundingBox(), ComputeBoundingBox(). * Added PCB_BASE_FRAME::GetBoardBoundingBox() which calls BOARD::ComputeBoundingBox()
2011-12-05 06:15:33 +00:00
double ux0, uy0, dx, dy;
double radius, width;
char line[1024];
2007-08-23 04:28:46 +00:00
2011-12-14 04:29:25 +00:00
ux0 = PtDrawSegment->GetStart().x * conv_unit;
uy0 = PtDrawSegment->GetStart().y * conv_unit;
2011-12-14 04:29:25 +00:00
dx = PtDrawSegment->GetEnd().x * conv_unit;
dy = PtDrawSegment->GetEnd().y * conv_unit;
2007-08-23 04:28:46 +00:00
2011-12-14 04:29:25 +00:00
width = PtDrawSegment->GetWidth() * conv_unit;
2007-08-23 04:28:46 +00:00
2011-12-14 04:29:25 +00:00
switch( PtDrawSegment->GetShape() )
2007-08-23 04:28:46 +00:00
{
case S_CIRCLE:
radius = hypot( dx - ux0, dy - uy0 );
2009-01-18 15:51:06 +00:00
fprintf( rptfile, "$CIRCLE \n" );
fprintf( rptfile, "centre %.6lf %.6lf\n", ux0, uy0 );
fprintf( rptfile, "radius %.6lf\n", radius );
2009-01-18 15:51:06 +00:00
fprintf( rptfile, "width %.6lf\n", width );
fprintf( rptfile, "$EndCIRCLE \n" );
2007-08-23 04:28:46 +00:00
break;
case S_ARC:
{
2011-12-14 04:29:25 +00:00
int endx = PtDrawSegment->GetEnd().x;
int endy = PtDrawSegment->GetEnd().y;
radius = hypot( dx - ux0, dy - uy0 );
RotatePoint( &endx,
&endy,
2011-12-14 04:29:25 +00:00
PtDrawSegment->GetStart().x,
PtDrawSegment->GetStart().y,
PtDrawSegment->GetAngle() );
2009-01-18 15:51:06 +00:00
fprintf( rptfile, "$ARC \n" );
fprintf( rptfile, "centre %.6lf %.6lf\n", ux0, uy0 );
fprintf( rptfile, "start %.6lf %.6lf\n",
endx * conv_unit, endy * conv_unit );
2009-01-18 15:51:06 +00:00
fprintf( rptfile, "end %.6lf %.6lf\n", dx, dy );
fprintf( rptfile, "width %.6lf\n", width );
fprintf( rptfile, "$EndARC \n" );
}
2007-08-23 04:28:46 +00:00
break;
default:
sprintf( line, "$LINE \n" );
fputs( line, rptfile );
2009-01-18 15:51:06 +00:00
fprintf( rptfile, "start %.6lf %.6lf\n", ux0, uy0 );
fprintf( rptfile, "end %.6lf %.6lf\n", dx, dy );
fprintf( rptfile, "width %.6lf\n", width );
fprintf( rptfile, "$EndLINE \n" );
2007-08-23 04:28:46 +00:00
break;
}
}