2011-11-10 15:55:05 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2016-05-10 06:56:03 +00:00
|
|
|
* Copyright (C) 2016 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
2012-06-08 09:56:42 +00:00
|
|
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
|
|
|
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
2016-05-10 06:56:03 +00:00
|
|
|
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
2011-11-10 15:55:05 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2011-09-23 13:57:12 +00:00
|
|
|
/**
|
|
|
|
* @file export_gencad.cpp
|
|
|
|
* @brief Export GenCAD 1.4 format.
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <fctsys.h>
|
|
|
|
#include <class_drawpanel.h>
|
|
|
|
#include <confirm.h>
|
|
|
|
#include <gestfich.h>
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
#include <pgm_base.h>
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <wxPcbStruct.h>
|
|
|
|
#include <trigo.h>
|
|
|
|
#include <build_version.h>
|
|
|
|
#include <macros.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <pcbnew.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <class_board.h>
|
|
|
|
#include <class_module.h>
|
|
|
|
#include <class_track.h>
|
|
|
|
#include <class_edge_mod.h>
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2010-01-05 08:48:49 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* frame );
|
2011-12-05 07:03:57 +00:00
|
|
|
static void CreateArtworksSection( FILE* aFile );
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateTracksInfoData( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreateBoardSection( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreateComponentsSection( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreateDevicesSection( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreateRoutesSection( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreateSignalsSection( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreateShapesSection( FILE* aFile, BOARD* aPcb );
|
|
|
|
static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb );
|
2009-11-02 20:36:20 +00:00
|
|
|
static void FootprintWriteShape( FILE* File, MODULE* module );
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
// layer names for Gencad export
|
|
|
|
|
|
|
|
#if 0 // was:
|
|
|
|
static const wxString GenCADLayerName[] =
|
2009-11-02 20:36:20 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
wxT( "BOTTOM" ), wxT( "INNER1" ), wxT( "INNER2" ),
|
|
|
|
wxT( "INNER3" ), wxT( "INNER4" ), wxT( "INNER5" ),
|
|
|
|
wxT( "INNER6" ), wxT( "INNER7" ), wxT( "INNER8" ),
|
|
|
|
wxT( "INNER9" ), wxT( "INNER10" ), wxT( "INNER11" ),
|
|
|
|
wxT( "INNER12" ), wxT( "INNER13" ), wxT( "INNER14" ),
|
|
|
|
wxT( "TOP" ), wxT( "LAYER17" ), wxT( "LAYER18" ),
|
2009-11-14 22:15:22 +00:00
|
|
|
wxT( "SOLDERPASTE_BOTTOM" ), wxT( "SOLDERPASTE_TOP" ),
|
|
|
|
wxT( "SILKSCREEN_BOTTOM" ), wxT( "SILKSCREEN_TOP" ),
|
2011-12-05 07:03:57 +00:00
|
|
|
wxT( "SOLDERMASK_BOTTOM" ), wxT( "SOLDERMASK_TOP" ), wxT( "LAYER25" ),
|
|
|
|
wxT( "LAYER26" ), wxT( "LAYER27" ), wxT( "LAYER28" ),
|
|
|
|
wxT( "LAYER29" ), wxT( "LAYER30" ), wxT( "LAYER31" ),
|
2011-12-02 15:09:57 +00:00
|
|
|
wxT( "LAYER32" )
|
2007-08-23 04:28:46 +00:00
|
|
|
};
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// flipped layer name for Gencad export (to make CAM350 imports correct)
|
|
|
|
static const wxString GenCADLayerNameFlipped[32] =
|
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
wxT( "TOP" ), wxT( "INNER14" ), wxT( "INNER13" ),
|
|
|
|
wxT( "INNER12" ), wxT( "INNER11" ), wxT( "INNER10" ),
|
|
|
|
wxT( "INNER9" ), wxT( "INNER8" ), wxT( "INNER7" ),
|
|
|
|
wxT( "INNER6" ), wxT( "INNER5" ), wxT( "INNER4" ),
|
|
|
|
wxT( "INNER3" ), wxT( "INNER2" ), wxT( "INNER1" ),
|
|
|
|
wxT( "BOTTOM" ), wxT( "LAYER17" ), wxT( "LAYER18" ),
|
|
|
|
wxT( "SOLDERPASTE_TOP" ), wxT( "SOLDERPASTE_BOTTOM" ),
|
|
|
|
wxT( "SILKSCREEN_TOP" ), wxT( "SILKSCREEN_BOTTOM" ),
|
|
|
|
wxT( "SOLDERMASK_TOP" ), wxT( "SOLDERMASK_BOTTOM" ), wxT( "LAYER25" ),
|
|
|
|
wxT( "LAYER26" ), wxT( "LAYER27" ), wxT( "LAYER28" ),
|
|
|
|
wxT( "LAYER29" ), wxT( "LAYER30" ), wxT( "LAYER31" ),
|
2011-12-02 15:09:57 +00:00
|
|
|
wxT( "LAYER32" )
|
|
|
|
};
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
static std::string GenCADLayerName( int aCuCount, LAYER_ID aId )
|
|
|
|
{
|
|
|
|
if( IsCopperLayer( aId ) )
|
|
|
|
{
|
|
|
|
if( aId == F_Cu )
|
|
|
|
return "TOP";
|
|
|
|
else if( aId == B_Cu )
|
2014-06-30 15:03:20 +00:00
|
|
|
return "BOTTOM";
|
2014-06-24 16:17:18 +00:00
|
|
|
|
|
|
|
else if( aId <= 14 )
|
|
|
|
{
|
2014-06-30 15:03:20 +00:00
|
|
|
return StrPrintf( "INNER%d", aCuCount - aId - 1 );
|
2014-06-24 16:17:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-06-30 15:03:20 +00:00
|
|
|
return StrPrintf( "LAYER%d", aId );
|
2014-06-24 16:17:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char* txt;
|
|
|
|
|
|
|
|
// using a switch to clearly show mapping & catch out of bounds index.
|
|
|
|
switch( aId )
|
|
|
|
{
|
|
|
|
// Technicals
|
|
|
|
case B_Adhes: txt = "B.Adhes"; break;
|
|
|
|
case F_Adhes: txt = "F.Adhes"; break;
|
|
|
|
case B_Paste: txt = "SOLDERPASTE_BOTTOM"; break;
|
|
|
|
case F_Paste: txt = "SOLDERPASTE_TOP"; break;
|
|
|
|
case B_SilkS: txt = "SILKSCREEN_BOTTOM"; break;
|
|
|
|
case F_SilkS: txt = "SILKSCREEN_TOP"; break;
|
|
|
|
case B_Mask: txt = "SOLDERMASK_BOTTOM"; break;
|
|
|
|
case F_Mask: txt = "SOLDERMASK_TOP"; break;
|
|
|
|
|
|
|
|
// Users
|
|
|
|
case Dwgs_User: txt = "Dwgs.User"; break;
|
|
|
|
case Cmts_User: txt = "Cmts.User"; break;
|
|
|
|
case Eco1_User: txt = "Eco1.User"; break;
|
|
|
|
case Eco2_User: txt = "Eco2.User"; break;
|
|
|
|
case Edge_Cuts: txt = "Edge.Cuts"; break;
|
|
|
|
case Margin: txt = "Margin"; break;
|
|
|
|
|
|
|
|
// Footprint
|
|
|
|
case F_CrtYd: txt = "F_CrtYd"; break;
|
|
|
|
case B_CrtYd: txt = "B_CrtYd"; break;
|
|
|
|
case F_Fab: txt = "F_Fab"; break;
|
|
|
|
case B_Fab: txt = "B_Fab"; break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
wxASSERT_MSG( 0, wxT( "aId UNEXPECTED" ) );
|
|
|
|
txt = "BAD-INDEX!"; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return txt;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-06-30 15:03:20 +00:00
|
|
|
static const LAYER_ID gc_seq[] = {
|
|
|
|
B_Cu,
|
|
|
|
In30_Cu,
|
|
|
|
In29_Cu,
|
|
|
|
In28_Cu,
|
|
|
|
In27_Cu,
|
|
|
|
In26_Cu,
|
|
|
|
In25_Cu,
|
|
|
|
In24_Cu,
|
|
|
|
In23_Cu,
|
|
|
|
In22_Cu,
|
|
|
|
In21_Cu,
|
|
|
|
In20_Cu,
|
|
|
|
In19_Cu,
|
|
|
|
In18_Cu,
|
|
|
|
In17_Cu,
|
|
|
|
In16_Cu,
|
|
|
|
In15_Cu,
|
|
|
|
In14_Cu,
|
|
|
|
In13_Cu,
|
|
|
|
In12_Cu,
|
|
|
|
In11_Cu,
|
|
|
|
In10_Cu,
|
|
|
|
In9_Cu,
|
|
|
|
In8_Cu,
|
|
|
|
In7_Cu,
|
|
|
|
In6_Cu,
|
|
|
|
In5_Cu,
|
|
|
|
In4_Cu,
|
|
|
|
In3_Cu,
|
|
|
|
In2_Cu,
|
|
|
|
In1_Cu,
|
|
|
|
F_Cu,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
// flipped layer name for Gencad export (to make CAM350 imports correct)
|
|
|
|
static std::string GenCADLayerNameFlipped( int aCuCount, LAYER_ID aId )
|
|
|
|
{
|
2014-06-30 15:03:20 +00:00
|
|
|
if( 1<= aId && aId <= 14 )
|
2014-06-24 16:17:18 +00:00
|
|
|
{
|
2014-06-30 15:03:20 +00:00
|
|
|
return StrPrintf( "INNER%d", 14 - aId );
|
2014-06-24 16:17:18 +00:00
|
|
|
}
|
|
|
|
|
2014-06-30 15:03:20 +00:00
|
|
|
return GenCADLayerName( aCuCount, aId );
|
2014-06-24 16:17:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2014-06-30 15:03:20 +00:00
|
|
|
static std::string fmt_mask( LSET aSet )
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
return aSet.FmtHex();
|
|
|
|
#else
|
|
|
|
return StrPrintf( "%08x", (unsigned) ( aSet & LSET::AllCuMask() ).to_ulong() );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// These are the export origin (the auxiliary axis)
|
|
|
|
static int GencadOffsetX, GencadOffsetY;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2016-06-05 11:49:25 +00:00
|
|
|
// GerbTool chokes on units different than INCH so this is the conversion factor
|
|
|
|
const static double SCALE_FACTOR = 1000.0 * IU_PER_MILS;
|
2011-11-10 15:55:05 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
/* Two helper functions to calculate coordinates of modules in gencad values
|
|
|
|
* (GenCAD Y axis from bottom to top)
|
2009-11-02 20:36:20 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static double MapXTo( int aX )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
return (aX - GencadOffsetX) / SCALE_FACTOR;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
static double MapYTo( int aY )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
return (GencadOffsetY - aY) / SCALE_FACTOR;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
/* Driver function: processing starts here */
|
|
|
|
void PCB_EDIT_FRAME::ExportToGenCAD( wxCommandEvent& aEvent )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
wxFileName fn = GetBoard()->GetFileName();
|
|
|
|
FILE* file;
|
|
|
|
|
|
|
|
wxString ext = wxT( "cad" );
|
|
|
|
wxString wildcard = _( "GenCAD 1.4 board files (.cad)|*.cad" );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2009-04-05 20:49:15 +00:00
|
|
|
fn.SetExt( ext );
|
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
wxString pro_dir = wxPathOnly( Prj().GetProjectFullName() );
|
|
|
|
|
|
|
|
wxFileDialog dlg( this, _( "Save GenCAD Board File" ), pro_dir,
|
2009-04-05 20:49:15 +00:00
|
|
|
fn.GetFullName(), wildcard,
|
|
|
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
|
|
|
|
|
|
|
|
if( dlg.ShowModal() == wxID_CANCEL )
|
2007-08-23 04:28:46 +00:00
|
|
|
return;
|
|
|
|
|
2009-04-05 20:49:15 +00:00
|
|
|
if( ( file = wxFopen( dlg.GetPath(), wxT( "wt" ) ) ) == NULL )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
wxString msg;
|
|
|
|
|
2013-04-09 17:49:01 +00:00
|
|
|
msg.Printf( _( "Unable to create <%s>" ), GetChars( dlg.GetPath() ) );
|
2007-08-23 04:28:46 +00:00
|
|
|
DisplayError( this, msg ); return;
|
|
|
|
}
|
|
|
|
|
2016-05-10 06:56:03 +00:00
|
|
|
// Switch the locale to standard C (needed to print floating point numbers)
|
|
|
|
LOCALE_IO toggle;
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
// Update some board data, to ensure a reliable gencad export
|
2011-02-25 16:23:24 +00:00
|
|
|
GetBoard()->ComputeBoundingBox();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Save the auxiliary origin for the rest of the module
|
2013-08-03 05:15:23 +00:00
|
|
|
GencadOffsetX = GetAuxOrigin().x;
|
|
|
|
GencadOffsetY = GetAuxOrigin().y;
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
// No idea on *why* this should be needed... maybe to fix net names?
|
2011-09-07 19:41:04 +00:00
|
|
|
Compile_Ratsnest( NULL, true );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2009-11-14 22:15:22 +00:00
|
|
|
/* Temporary modification of footprints that are flipped (i.e. on bottom
|
|
|
|
* layer) to convert them to non flipped footprints.
|
2009-11-02 20:36:20 +00:00
|
|
|
* This is necessary to easily export shapes to GenCAD,
|
|
|
|
* that are given as normal orientation (non flipped, rotation = 0))
|
|
|
|
* these changes will be undone later
|
|
|
|
*/
|
2011-12-05 07:03:57 +00:00
|
|
|
BOARD* pcb = GetBoard();
|
2007-08-23 04:28:46 +00:00
|
|
|
MODULE* module;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( module = pcb->m_Modules; module; module = module->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
module->SetFlag( 0 );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
if( module->GetLayer() == B_Cu )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
module->Flip( module->GetPosition() );
|
|
|
|
module->SetFlag( 1 );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
/* Gencad has some mandatory and some optional sections: some importer
|
2011-12-05 07:03:57 +00:00
|
|
|
* need the padstack section (which is optional) anyway. Also the
|
|
|
|
* order of the section *is* important */
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
CreateHeaderInfoData( file, this ); // Gencad header
|
|
|
|
CreateBoardSection( file, pcb ); // Board perimeter
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
CreatePadsShapesSection( file, pcb ); // Pads and padstacks
|
|
|
|
CreateArtworksSection( file ); // Empty but mandatory
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
/* Gencad splits a component info in shape, component and device.
|
2011-12-05 07:03:57 +00:00
|
|
|
* We don't do any sharing (it would be difficult since each module is
|
|
|
|
* customizable after placement) */
|
2011-12-02 15:09:57 +00:00
|
|
|
CreateShapesSection( file, pcb );
|
|
|
|
CreateComponentsSection( file, pcb );
|
|
|
|
CreateDevicesSection( file, pcb );
|
2009-11-12 10:18:02 +00:00
|
|
|
|
++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
|
|
|
// In a similar way the netlist is split in net, track and route
|
2011-12-02 15:09:57 +00:00
|
|
|
CreateSignalsSection( file, pcb );
|
|
|
|
CreateTracksInfoData( file, pcb );
|
|
|
|
CreateRoutesSection( file, pcb );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
|
|
fclose( file );
|
|
|
|
|
++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
|
|
|
// Undo the footprints modifications (flipped footprints)
|
2014-06-24 16:17:18 +00:00
|
|
|
for( module = pcb->m_Modules; module; module = module->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetFlag() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
module->Flip( module->GetPosition() );
|
|
|
|
module->SetFlag( 0 );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Comparator for sorting pads with qsort
|
|
|
|
static int PadListSortByShape( const void* aRefptr, const void* aObjptr )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
const D_PAD* padref = *(D_PAD**) aRefptr;
|
|
|
|
const D_PAD* padcmp = *(D_PAD**) aObjptr;
|
2008-01-24 21:50:12 +00:00
|
|
|
|
2008-11-18 18:13:55 +00:00
|
|
|
return D_PAD::Compare( padref, padcmp );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Sort vias for uniqueness
|
2011-12-05 07:03:57 +00:00
|
|
|
static int ViaSort( const void* aRefptr, const void* aObjptr )
|
2011-12-02 15:09:57 +00:00
|
|
|
{
|
2014-04-25 06:00:04 +00:00
|
|
|
VIA* padref = *(VIA**) aRefptr;
|
|
|
|
VIA* padcmp = *(VIA**) aObjptr;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2013-01-13 00:04:00 +00:00
|
|
|
if( padref->GetWidth() != padcmp->GetWidth() )
|
|
|
|
return padref->GetWidth() - padcmp->GetWidth();
|
++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
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
if( padref->GetDrillValue() != padcmp->GetDrillValue() )
|
2011-12-05 07:03:57 +00:00
|
|
|
return padref->GetDrillValue() - padcmp->GetDrillValue();
|
2011-12-02 15:09:57 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
if( padref->GetLayerSet() != padcmp->GetLayerSet() )
|
|
|
|
return padref->GetLayerSet().FmtBin().compare( padcmp->GetLayerSet().FmtBin() );
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// The ARTWORKS section is empty but (officially) mandatory
|
|
|
|
static void CreateArtworksSection( FILE* aFile )
|
|
|
|
{
|
|
|
|
/* The artworks section is empty */
|
|
|
|
fputs( "$ARTWORKS\n", aFile );
|
|
|
|
fputs( "$ENDARTWORKS\n\n", aFile );
|
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
++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
|
|
|
// Emit PADS and PADSTACKS. They are sorted and emitted uniquely.
|
2011-12-02 15:09:57 +00:00
|
|
|
// Via name is synthesized from their attributes, pads are numbered
|
|
|
|
static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2008-12-04 04:28:11 +00:00
|
|
|
std::vector<D_PAD*> pads;
|
2011-12-02 15:09:57 +00:00
|
|
|
std::vector<D_PAD*> padstacks;
|
2014-06-24 16:17:18 +00:00
|
|
|
std::vector<VIA*> vias;
|
|
|
|
std::vector<VIA*> viastacks;
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
padstacks.resize( 1 ); // We count pads from 1
|
2008-11-18 18:13:55 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// The master layermask (i.e. the enabled layers) for padstack generation
|
2014-06-24 16:17:18 +00:00
|
|
|
LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
|
|
|
|
int cu_count = aPcb->GetCopperLayerCount();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$PADS\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Enumerate and sort the pads
|
2011-12-10 05:33:24 +00:00
|
|
|
if( aPcb->GetPadCount() > 0 )
|
2008-01-23 01:18:41 +00:00
|
|
|
{
|
2011-12-10 05:33:24 +00:00
|
|
|
pads = aPcb->GetPads();
|
|
|
|
qsort( &pads[0], aPcb->GetPadCount(), sizeof( D_PAD* ),
|
2011-12-05 07:03:57 +00:00
|
|
|
PadListSortByShape );
|
2008-01-23 01:18:41 +00:00
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// The same for vias
|
2014-06-24 16:17:18 +00:00
|
|
|
for( VIA* via = GetFirstVia( aPcb->m_Track ); via;
|
2014-04-30 19:16:22 +00:00
|
|
|
via = GetFirstVia( via->Next() ) )
|
++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
|
|
|
{
|
2014-04-30 19:16:22 +00:00
|
|
|
vias.push_back( via );
|
2011-12-02 15:09:57 +00:00
|
|
|
}
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2014-04-25 06:00:04 +00:00
|
|
|
qsort( &vias[0], vias.size(), sizeof(VIA*), ViaSort );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Emit vias pads
|
|
|
|
TRACK* old_via = 0;
|
2014-06-30 15:03:20 +00:00
|
|
|
|
++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
|
|
|
for( unsigned i = 0; i < vias.size(); i++ )
|
2011-12-02 15:09:57 +00:00
|
|
|
{
|
2014-04-25 06:00:04 +00:00
|
|
|
VIA* via = vias[i];
|
2014-06-30 15:03:20 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
if( old_via && 0 == ViaSort( &old_via, &via ) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
old_via = via;
|
|
|
|
viastacks.push_back( via );
|
2014-06-24 16:17:18 +00:00
|
|
|
fprintf( aFile, "PAD V%d.%d.%s ROUND %g\nCIRCLE 0 0 %g\n",
|
2013-01-13 00:04:00 +00:00
|
|
|
via->GetWidth(), via->GetDrillValue(),
|
2014-06-30 15:03:20 +00:00
|
|
|
fmt_mask( via->GetLayerSet() ).c_str(),
|
2011-12-05 07:03:57 +00:00
|
|
|
via->GetDrillValue() / SCALE_FACTOR,
|
2013-01-13 00:04:00 +00:00
|
|
|
via->GetWidth() / (SCALE_FACTOR * 2) );
|
2011-12-02 15:09:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Emit component pads
|
|
|
|
D_PAD* old_pad = 0;
|
|
|
|
int pad_name_number = 0;
|
2014-06-24 16:17:18 +00:00
|
|
|
|
2009-11-14 22:15:22 +00:00
|
|
|
for( unsigned i = 0; i<pads.size(); ++i )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2008-12-04 04:28:11 +00:00
|
|
|
D_PAD* pad = pads[i];
|
|
|
|
|
2008-11-18 18:13:55 +00:00
|
|
|
pad->SetSubRatsnest( pad_name_number );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2008-01-24 21:50:12 +00:00
|
|
|
if( old_pad && 0==D_PAD::Compare( old_pad, pad ) )
|
2009-11-14 22:15:22 +00:00
|
|
|
continue; // already created
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
|
|
old_pad = pad;
|
|
|
|
|
|
|
|
pad_name_number++;
|
2008-11-18 18:13:55 +00:00
|
|
|
pad->SetSubRatsnest( pad_name_number );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "PAD P%d", pad->GetSubRatsnest() );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
padstacks.push_back( pad ); // Will have its own padstack later
|
2012-02-19 04:02:19 +00:00
|
|
|
int dx = pad->GetSize().x / 2;
|
|
|
|
int dy = pad->GetSize().y / 2;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2012-02-19 04:02:19 +00:00
|
|
|
switch( pad->GetShape() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
|
|
|
default:
|
2015-08-23 19:40:33 +00:00
|
|
|
case PAD_SHAPE_CIRCLE:
|
++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
|
|
|
fprintf( aFile, " ROUND %g\n",
|
2012-02-19 04:02:19 +00:00
|
|
|
pad->GetDrillSize().x / SCALE_FACTOR );
|
2011-12-05 07:03:57 +00:00
|
|
|
/* Circle is center, radius */
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "CIRCLE %g %g %g\n",
|
2012-02-19 04:02:19 +00:00
|
|
|
pad->GetOffset().x / SCALE_FACTOR,
|
|
|
|
-pad->GetOffset().y / SCALE_FACTOR,
|
|
|
|
pad->GetSize().x / (SCALE_FACTOR * 2) );
|
2007-08-23 04:28:46 +00:00
|
|
|
break;
|
|
|
|
|
2015-08-23 19:40:33 +00:00
|
|
|
case PAD_SHAPE_RECT:
|
++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
|
|
|
fprintf( aFile, " RECTANGULAR %g\n",
|
2012-02-19 04:02:19 +00:00
|
|
|
pad->GetDrillSize().x / SCALE_FACTOR );
|
2011-12-05 07:03:57 +00:00
|
|
|
|
|
|
|
// Rectangle is begin, size *not* begin, end!
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "RECTANGLE %g %g %g %g\n",
|
2012-02-19 04:02:19 +00:00
|
|
|
(-dx + pad->GetOffset().x ) / SCALE_FACTOR,
|
|
|
|
(-dy - pad->GetOffset().y ) / SCALE_FACTOR,
|
2011-12-05 07:03:57 +00:00
|
|
|
dx / (SCALE_FACTOR / 2), dy / (SCALE_FACTOR / 2) );
|
2007-08-23 04:28:46 +00:00
|
|
|
break;
|
|
|
|
|
2015-08-23 19:40:33 +00:00
|
|
|
case PAD_SHAPE_OVAL: // Create outline by 2 lines and 2 arcs
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-06-30 15:03:20 +00:00
|
|
|
// OrCAD Layout call them OVAL or OBLONG - GenCAD call them FINGERs
|
|
|
|
fprintf( aFile, " FINGER %g\n",
|
|
|
|
pad->GetDrillSize().x / SCALE_FACTOR );
|
|
|
|
int dr = dx - dy;
|
|
|
|
|
|
|
|
if( dr >= 0 ) // Horizontal oval
|
|
|
|
{
|
|
|
|
int radius = dy;
|
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
|
|
|
(-dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - radius) / SCALE_FACTOR,
|
|
|
|
(dr + pad->GetOffset().x ) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - radius) / SCALE_FACTOR );
|
|
|
|
|
|
|
|
// GenCAD arcs are (start, end, center)
|
|
|
|
fprintf( aFile, "ARC %g %g %g %g %g %g\n",
|
|
|
|
(dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - radius) / SCALE_FACTOR,
|
|
|
|
(dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + radius) / SCALE_FACTOR,
|
|
|
|
(dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
-pad->GetOffset().y / SCALE_FACTOR );
|
|
|
|
|
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
|
|
|
(dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + radius) / SCALE_FACTOR,
|
|
|
|
(-dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + radius) / SCALE_FACTOR );
|
|
|
|
fprintf( aFile, "ARC %g %g %g %g %g %g\n",
|
|
|
|
(-dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + radius) / SCALE_FACTOR,
|
|
|
|
(-dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - radius) / SCALE_FACTOR,
|
|
|
|
(-dr + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
-pad->GetOffset().y / SCALE_FACTOR );
|
|
|
|
}
|
|
|
|
else // Vertical oval
|
|
|
|
{
|
|
|
|
dr = -dr;
|
|
|
|
int radius = dx;
|
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
|
|
|
(-radius + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - dr) / SCALE_FACTOR,
|
|
|
|
(-radius + pad->GetOffset().x ) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + dr) / SCALE_FACTOR );
|
|
|
|
fprintf( aFile, "ARC %g %g %g %g %g %g\n",
|
|
|
|
(-radius + pad->GetOffset().x ) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + dr) / SCALE_FACTOR,
|
|
|
|
(radius + pad->GetOffset().x ) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + dr) / SCALE_FACTOR,
|
|
|
|
pad->GetOffset().x / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + dr) / SCALE_FACTOR );
|
|
|
|
|
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
|
|
|
(radius + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y + dr) / SCALE_FACTOR,
|
|
|
|
(radius + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - dr) / SCALE_FACTOR );
|
|
|
|
fprintf( aFile, "ARC %g %g %g %g %g %g\n",
|
|
|
|
(radius + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - dr) / SCALE_FACTOR,
|
|
|
|
(-radius + pad->GetOffset().x) / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - dr) / SCALE_FACTOR,
|
|
|
|
pad->GetOffset().x / SCALE_FACTOR,
|
|
|
|
(-pad->GetOffset().y - dr) / SCALE_FACTOR );
|
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-08-23 19:40:33 +00:00
|
|
|
case PAD_SHAPE_TRAPEZOID:
|
++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
|
|
|
fprintf( aFile, " POLYGON %g\n",
|
2012-02-19 04:02:19 +00:00
|
|
|
pad->GetDrillSize().x / SCALE_FACTOR );
|
2011-12-05 07:03:57 +00:00
|
|
|
|
|
|
|
// XXX TO BE IMPLEMENTED! and I don't know if it could be actually imported by something
|
2007-08-23 04:28:46 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "\n$ENDPADS\n\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Now emit the padstacks definitions, using the combined layer masks
|
|
|
|
fputs( "$PADSTACKS\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Via padstacks
|
|
|
|
for( unsigned i = 0; i < viastacks.size(); i++ )
|
|
|
|
{
|
2014-04-25 06:00:04 +00:00
|
|
|
VIA* via = viastacks[i];
|
2014-06-24 16:17:18 +00:00
|
|
|
|
|
|
|
LSET mask = via->GetLayerSet() & master_layermask;
|
|
|
|
|
|
|
|
fprintf( aFile, "PADSTACK VIA%d.%d.%s %g\n",
|
|
|
|
via->GetWidth(), via->GetDrillValue(),
|
2014-06-30 15:03:20 +00:00
|
|
|
fmt_mask( mask ).c_str(),
|
2011-12-05 07:03:57 +00:00
|
|
|
via->GetDrillValue() / SCALE_FACTOR );
|
++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
|
|
|
|
2014-06-30 15:03:20 +00:00
|
|
|
for( LSEQ seq = mask.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
|
++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
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
LAYER_ID layer = *seq;
|
|
|
|
|
|
|
|
fprintf( aFile, "PAD V%d.%d.%s %s 0 0\n",
|
|
|
|
via->GetWidth(), via->GetDrillValue(),
|
2014-06-30 15:03:20 +00:00
|
|
|
fmt_mask( mask ).c_str(),
|
2014-06-24 16:17:18 +00:00
|
|
|
GenCADLayerName( cu_count, layer ).c_str()
|
|
|
|
);
|
++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
|
|
|
}
|
2011-12-02 15:09:57 +00:00
|
|
|
}
|
2011-12-05 07:03:57 +00:00
|
|
|
|
++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
|
|
|
/* Component padstacks
|
2011-12-05 07:03:57 +00:00
|
|
|
* CAM350 don't apply correctly the FLIP semantics for padstacks, i.e. doesn't
|
|
|
|
* swap the top and bottom layers... so I need to define the shape as MIRRORX
|
|
|
|
* and define a separate 'flipped' padstack... until it appears yet another
|
|
|
|
* noncompliant importer */
|
2011-12-02 15:09:57 +00:00
|
|
|
for( unsigned i = 1; i < padstacks.size(); i++ )
|
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
D_PAD* pad = padstacks[i];
|
2011-12-02 15:09:57 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
// Straight padstack
|
2015-02-22 14:43:44 +00:00
|
|
|
fprintf( aFile, "PADSTACK PAD%u %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
|
2014-06-24 16:17:18 +00:00
|
|
|
|
|
|
|
LSET pad_set = pad->GetLayerSet() & master_layermask;
|
|
|
|
|
2014-06-30 15:03:20 +00:00
|
|
|
// the special gc_seq
|
|
|
|
for( LSEQ seq = pad_set.Seq( gc_seq, DIM( gc_seq ) ); seq; ++seq )
|
++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
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
LAYER_ID layer = *seq;
|
|
|
|
|
2015-02-22 14:43:44 +00:00
|
|
|
fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerName( cu_count, layer ).c_str() );
|
++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
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
// Flipped padstack
|
2015-02-22 14:43:44 +00:00
|
|
|
fprintf( aFile, "PADSTACK PAD%uF %g\n", i, pad->GetDrillSize().x / SCALE_FACTOR );
|
2014-06-24 16:17:18 +00:00
|
|
|
|
2014-06-30 15:03:20 +00:00
|
|
|
// the normal LAYER_ID sequence is inverted from gc_seq[]
|
2014-06-24 16:17:18 +00:00
|
|
|
for( LSEQ seq = pad_set.Seq(); seq; ++seq )
|
2011-12-05 07:03:57 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
LAYER_ID layer = *seq;
|
|
|
|
|
2015-02-22 14:43:44 +00:00
|
|
|
fprintf( aFile, "PAD P%u %s 0 0\n", i, GenCADLayerNameFlipped( cu_count, layer ).c_str() );
|
++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
|
|
|
}
|
|
|
|
}
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDPADSTACKS\n\n", aFile );
|
2009-11-12 10:18:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
/* Creates the footprint shape list.
|
2011-12-02 15:09:57 +00:00
|
|
|
* Since module shape is customizable after the placement we cannot share them;
|
|
|
|
* instead we opt for the one-module-one-shape-one-component-one-device approach
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateShapesSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-11-02 20:36:20 +00:00
|
|
|
MODULE* module;
|
|
|
|
D_PAD* pad;
|
|
|
|
const char* layer;
|
|
|
|
wxString pinname;
|
|
|
|
const char* mirror = "0";
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$SHAPES\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
const LSET all_cu = LSET::AllCuMask();
|
|
|
|
|
|
|
|
for( module = aPcb->m_Modules; module; module = module->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
FootprintWriteShape( aFile, module );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( pad = module->Pads(); pad; pad = pad->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
/* Funny thing: GenCAD requires the pad side even if you use
|
|
|
|
* padstacks (which are theorically optional but gerbtools
|
|
|
|
*requires* them). Now the trouble thing is that 'BOTTOM'
|
|
|
|
* is interpreted by someone as a padstack flip even
|
|
|
|
* if the spec explicitly says it's not... */
|
2007-08-23 04:28:46 +00:00
|
|
|
layer = "ALL";
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
if( ( pad->GetLayerSet() & all_cu ) == LSET( B_Cu ) )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
layer = module->GetFlag() ? "TOP" : "BOTTOM";
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
2014-06-24 16:17:18 +00:00
|
|
|
else if( ( pad->GetLayerSet() & all_cu ) == LSET( F_Cu ) )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
layer = module->GetFlag() ? "BOTTOM" : "TOP";
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
pad->StringPadName( pinname );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
if( pinname.IsEmpty() )
|
2011-12-02 15:09:57 +00:00
|
|
|
pinname = wxT( "none" );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2013-05-05 07:17:48 +00:00
|
|
|
double orient = pad->GetOrientation() - module->GetOrientation();
|
2007-08-23 04:28:46 +00:00
|
|
|
NORMALIZE_ANGLE_POS( orient );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
// Bottom side modules use the flipped padstack
|
2013-03-13 18:53:58 +00:00
|
|
|
fprintf( aFile, (module->GetFlag()) ?
|
2011-12-05 07:03:57 +00:00
|
|
|
"PIN %s PAD%dF %g %g %s %g %s\n" :
|
|
|
|
"PIN %s PAD%d %g %g %s %g %s\n",
|
|
|
|
TO_UTF8( pinname ), pad->GetSubRatsnest(),
|
2012-02-19 04:02:19 +00:00
|
|
|
pad->GetPos0().x / SCALE_FACTOR,
|
|
|
|
-pad->GetPos0().y / SCALE_FACTOR,
|
2011-12-05 07:03:57 +00:00
|
|
|
layer, orient / 10.0, mirror );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDSHAPES\n\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
/* Creates the section $COMPONENTS (Footprints placement)
|
2011-12-02 15:09:57 +00:00
|
|
|
* Bottom side components are difficult to handle: shapes must be mirrored or
|
|
|
|
* flipped, silk layers need to be handled correctly and so on. Also it seems
|
|
|
|
* that *noone* follows the specs...
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateComponentsSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$COMPONENTS\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
int cu_count = aPcb->GetCopperLayerCount();
|
|
|
|
|
|
|
|
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
const char* mirror;
|
|
|
|
const char* flip;
|
2016-04-18 18:15:44 +00:00
|
|
|
double fp_orient = module->GetOrientation();
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetFlag() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
++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
|
|
|
mirror = "0";
|
|
|
|
flip = "FLIP";
|
2016-04-18 18:15:44 +00:00
|
|
|
NEGATE_AND_NORMALIZE_ANGLE_POS( fp_orient );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mirror = "0";
|
|
|
|
flip = "0";
|
|
|
|
}
|
|
|
|
|
++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
|
|
|
fprintf( aFile, "\nCOMPONENT %s\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
TO_UTF8( module->GetReference() ) );
|
++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
|
|
|
fprintf( aFile, "DEVICE %s_%s\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
TO_UTF8( module->GetReference() ),
|
|
|
|
TO_UTF8( module->GetValue() ) );
|
++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
|
|
|
fprintf( aFile, "PLACE %g %g\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
MapXTo( module->GetPosition().x ),
|
|
|
|
MapYTo( module->GetPosition().y ) );
|
++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
|
|
|
fprintf( aFile, "LAYER %s\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
(module->GetFlag()) ? "BOTTOM" : "TOP" );
|
++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
|
|
|
fprintf( aFile, "ROTATION %g\n",
|
2016-04-18 18:15:44 +00:00
|
|
|
fp_orient / 10.0 );
|
++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
|
|
|
fprintf( aFile, "SHAPE %s %s %s\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
TO_UTF8( module->GetReference() ),
|
2011-12-05 07:03:57 +00:00
|
|
|
mirror, flip );
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
// Text on silk layer: RefDes and value (are they actually useful?)
|
2014-09-10 15:18:42 +00:00
|
|
|
TEXTE_MODULE *textmod = &module->Reference();
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
for( int ii = 0; ii < 2; ii++ )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2016-04-18 18:15:44 +00:00
|
|
|
double txt_orient = textmod->GetOrientation();
|
2014-06-24 16:17:18 +00:00
|
|
|
std::string layer = GenCADLayerName( cu_count, module->GetFlag() ? B_SilkS : F_SilkS );
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
fprintf( aFile, "TEXT %g %g %g %g %s %s \"%s\"",
|
2013-03-13 18:53:58 +00:00
|
|
|
textmod->GetPos0().x / SCALE_FACTOR,
|
2011-12-12 08:37:05 +00:00
|
|
|
-textmod->GetPos0().y / SCALE_FACTOR,
|
2013-03-13 18:53:58 +00:00
|
|
|
textmod->GetSize().x / SCALE_FACTOR,
|
2016-04-18 18:15:44 +00:00
|
|
|
txt_orient / 10.0,
|
2013-03-13 18:53:58 +00:00
|
|
|
mirror,
|
2014-06-24 16:17:18 +00:00
|
|
|
layer.c_str(),
|
2013-03-13 18:53:58 +00:00
|
|
|
TO_UTF8( textmod->GetText() ) );
|
2011-12-05 07:03:57 +00:00
|
|
|
|
|
|
|
// Please note, the width is approx
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, " 0 0 %g %g\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
( textmod->GetSize().x * textmod->GetLength() ) / SCALE_FACTOR,
|
2012-02-19 04:02:19 +00:00
|
|
|
textmod->GetSize().y / SCALE_FACTOR );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2013-03-13 18:53:58 +00:00
|
|
|
textmod = &module->Value(); // Dirty trick for the second iteration
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// The SHEET is a 'generic description' for referencing the component
|
|
|
|
fprintf( aFile, "SHEET \"RefDes: %s, Value: %s\"\n",
|
2013-03-13 18:53:58 +00:00
|
|
|
TO_UTF8( module->GetReference() ),
|
|
|
|
TO_UTF8( module->GetValue() ) );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDCOMPONENTS\n\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
/* Emit the netlist (which is actually the thing for which GenCAD is used these
|
|
|
|
* days!); tracks are handled later */
|
|
|
|
static void CreateSignalsSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2009-11-02 20:36:20 +00:00
|
|
|
wxString msg;
|
2009-05-24 18:28:36 +00:00
|
|
|
NETINFO_ITEM* net;
|
2009-11-02 20:36:20 +00:00
|
|
|
D_PAD* pad;
|
|
|
|
MODULE* module;
|
|
|
|
int NbNoConn = 1;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$SIGNALS\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-10 05:33:24 +00:00
|
|
|
for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-12-10 05:33:24 +00:00
|
|
|
net = aPcb->FindNet( ii );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
|
|
|
if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection)
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2016-06-05 11:49:25 +00:00
|
|
|
msg.Printf( "NoConnection%d", NbNoConn++ );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2009-11-14 22:15:22 +00:00
|
|
|
if( net->GetNet() <= 0 ) // dummy netlist (no connection)
|
2007-08-23 04:28:46 +00:00
|
|
|
continue;
|
|
|
|
|
2009-11-12 10:18:02 +00:00
|
|
|
msg = wxT( "SIGNAL " ) + net->GetNetname();
|
2008-11-18 18:13:55 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( TO_UTF8( msg ), aFile );
|
|
|
|
fputs( "\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( module = aPcb->m_Modules; module; module = module->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
for( pad = module->Pads(); pad; pad = pad->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
|
|
|
wxString padname;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-02-25 10:40:34 +00:00
|
|
|
if( pad->GetNetCode() != net->GetNet() )
|
2007-08-23 04:28:46 +00:00
|
|
|
continue;
|
2008-11-18 18:13:55 +00:00
|
|
|
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
pad->StringPadName( padname );
|
2011-12-02 15:09:57 +00:00
|
|
|
msg.Printf( wxT( "NODE %s %s" ),
|
2013-03-13 18:53:58 +00:00
|
|
|
GetChars( module->GetReference() ),
|
|
|
|
GetChars( padname ) );
|
2008-11-18 18:13:55 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( TO_UTF8( msg ), aFile );
|
|
|
|
fputs( "\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDSIGNALS\n\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2012-01-09 08:35:06 +00:00
|
|
|
// Creates the header section
|
2011-12-02 15:09:57 +00:00
|
|
|
static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* aFrame )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
wxString msg;
|
2012-08-29 16:59:50 +00:00
|
|
|
BOARD *board = aFrame->GetBoard();
|
2011-12-02 15:09:57 +00:00
|
|
|
|
|
|
|
fputs( "$HEADER\n", aFile );
|
|
|
|
fputs( "GENCAD 1.4\n", aFile );
|
|
|
|
|
|
|
|
// Please note: GenCAD syntax requires quoted strings if they can contain spaces
|
|
|
|
msg.Printf( wxT( "USER \"%s %s\"\n" ),
|
* KIWAY Milestone A): Make major modules into DLL/DSOs.
! The initial testing of this commit should be done using a Debug build so that
all the wxASSERT()s are enabled. Also, be sure and keep enabled the
USE_KIWAY_DLLs option. The tree won't likely build without it. Turning it
off is senseless anyways. If you want stable code, go back to a prior version,
the one tagged with "stable".
* Relocate all functionality out of the wxApp derivative into more finely
targeted purposes:
a) DLL/DSO specific
b) PROJECT specific
c) EXE or process specific
d) configuration file specific data
e) configuration file manipulations functions.
All of this functionality was blended into an extremely large wxApp derivative
and that was incompatible with the desire to support multiple concurrently
loaded DLL/DSO's ("KIFACE")s and multiple concurrently open projects.
An amazing amount of organization come from simply sorting each bit of
functionality into the proper box.
* Switch to wxConfigBase from wxConfig everywhere except instantiation.
* Add classes KIWAY, KIFACE, KIFACE_I, SEARCH_STACK, PGM_BASE, PGM_KICAD,
PGM_SINGLE_TOP,
* Remove "Return" prefix on many function names.
* Remove obvious comments from CMakeLists.txt files, and from else() and endif()s.
* Fix building boost for use in a DSO on linux.
* Remove some of the assumptions in the CMakeLists.txt files that windows had
to be the host platform when building windows binaries.
* Reduce the number of wxStrings being constructed at program load time via
static construction.
* Pass wxConfigBase* to all SaveSettings() and LoadSettings() functions so that
these functions are useful even when the wxConfigBase comes from another
source, as is the case in the KICAD_MANAGER_FRAME.
* Move the setting of the KIPRJMOD environment variable into class PROJECT,
so that it can be moved into a project variable soon, and out of FP_LIB_TABLE.
* Add the KIWAY_PLAYER which is associated with a particular PROJECT, and all
its child wxFrames and wxDialogs now have a Kiway() member function which
returns a KIWAY& that that window tree branch is in support of. This is like
wxWindows DNA in that child windows get this member with proper value at time
of construction.
* Anticipate some of the needs for milestones B) and C) and make code
adjustments now in an effort to reduce work in those milestones.
* No testing has been done for python scripting, since milestone C) has that
being largely reworked and re-thought-out.
2014-03-20 00:42:08 +00:00
|
|
|
GetChars( Pgm().App().GetAppName() ),
|
2011-12-05 07:03:57 +00:00
|
|
|
GetChars( GetBuildVersion() ) );
|
++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
|
|
|
fputs( TO_UTF8( msg ), aFile );
|
2012-01-09 08:35:06 +00:00
|
|
|
|
2012-08-29 16:59:50 +00:00
|
|
|
msg = wxT( "DRAWING \"" ) + board->GetFileName() + wxT( "\"\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
|
|
|
fputs( TO_UTF8( msg ), aFile );
|
2012-01-09 08:35:06 +00:00
|
|
|
|
|
|
|
const TITLE_BLOCK& tb = aFrame->GetTitleBlock();
|
|
|
|
|
|
|
|
msg = wxT( "REVISION \"" ) + tb.GetRevision() + wxT( " " ) + tb.GetDate() + wxT( "\"\n" );
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( TO_UTF8( msg ), aFile );
|
2011-12-05 07:03:57 +00:00
|
|
|
fputs( "UNITS INCH\n", aFile );
|
2012-01-09 08:35:06 +00:00
|
|
|
|
++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
|
|
|
msg.Printf( wxT( "ORIGIN %g %g\n" ),
|
2013-08-03 05:15:23 +00:00
|
|
|
MapXTo( aFrame->GetAuxOrigin().x ),
|
|
|
|
MapYTo( aFrame->GetAuxOrigin().y ) );
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( TO_UTF8( msg ), aFile );
|
2012-01-09 08:35:06 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "INTERTRACK 0\n", aFile );
|
|
|
|
fputs( "$ENDHEADER\n\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-09-07 19:41:04 +00:00
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
/*
|
2009-11-02 20:36:20 +00:00
|
|
|
* Sort function used to sort tracks segments:
|
|
|
|
* items are sorted by netcode, then by width then by layer
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static int TrackListSortByNetcode( const void* refptr, const void* objptr )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
const TRACK* ref, * cmp;
|
|
|
|
int diff;
|
|
|
|
|
|
|
|
ref = *( (TRACK**) refptr );
|
|
|
|
cmp = *( (TRACK**) objptr );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-02-25 10:40:34 +00:00
|
|
|
if( ( diff = ref->GetNetCode() - cmp->GetNetCode() ) )
|
2007-08-23 04:28:46 +00:00
|
|
|
return diff;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2013-01-13 00:04:00 +00:00
|
|
|
if( ( diff = ref->GetWidth() - cmp->GetWidth() ) )
|
2007-08-23 04:28:46 +00:00
|
|
|
return diff;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
if( ( diff = ref->GetLayer() - cmp->GetLayer() ) )
|
2007-08-23 04:28:46 +00:00
|
|
|
return diff;
|
|
|
|
|
|
|
|
return 0;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
|
|
|
2009-11-12 10:18:02 +00:00
|
|
|
/* Creates the section ROUTES
|
|
|
|
* that handles tracks, vias
|
2009-11-02 20:36:20 +00:00
|
|
|
* TODO: add zones
|
2007-08-23 04:28:46 +00:00
|
|
|
* section:
|
|
|
|
* $ROUTE
|
|
|
|
* ...
|
|
|
|
* $ENROUTE
|
2009-11-02 20:36:20 +00:00
|
|
|
* Track segments must be sorted by nets
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateRoutesSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
TRACK* track, ** tracklist;
|
|
|
|
int vianum = 1;
|
|
|
|
int old_netcode, old_width, old_layer;
|
|
|
|
int nbitems, ii;
|
|
|
|
LSET master_layermask = aPcb->GetDesignSettings().GetEnabledLayers();
|
|
|
|
|
|
|
|
int cu_count = aPcb->GetCopperLayerCount();
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
// Count items
|
2007-08-23 04:28:46 +00:00
|
|
|
nbitems = 0;
|
2011-11-10 15:55:05 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( track = aPcb->m_Track; track; track = track->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
nbitems++;
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( track = aPcb->m_Zone; track; track = track->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-10-01 19:24:27 +00:00
|
|
|
if( track->Type() == PCB_ZONE_T )
|
2007-08-23 04:28:46 +00:00
|
|
|
nbitems++;
|
|
|
|
}
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
tracklist = (TRACK**) operator new( (nbitems + 1)* sizeof( TRACK* ) );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
|
|
nbitems = 0;
|
2011-10-01 19:24:27 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( track = aPcb->m_Track; track; track = track->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
tracklist[nbitems++] = track;
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( track = aPcb->m_Zone; track; track = track->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-10-01 19:24:27 +00:00
|
|
|
if( track->Type() == PCB_ZONE_T )
|
2007-08-23 04:28:46 +00:00
|
|
|
tracklist[nbitems++] = track;
|
|
|
|
}
|
|
|
|
|
|
|
|
tracklist[nbitems] = NULL;
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
qsort( tracklist, nbitems, sizeof(TRACK*), TrackListSortByNetcode );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ROUTES\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
|
|
old_netcode = -1; old_width = -1; old_layer = -1;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
for( ii = 0; ii < nbitems; ii++ )
|
|
|
|
{
|
|
|
|
track = tracklist[ii];
|
2011-10-01 19:24:27 +00:00
|
|
|
|
2014-02-25 10:40:34 +00:00
|
|
|
if( old_netcode != track->GetNetCode() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-02-25 10:40:34 +00:00
|
|
|
old_netcode = track->GetNetCode();
|
|
|
|
NETINFO_ITEM* net = track->GetNet();
|
2009-11-02 20:36:20 +00:00
|
|
|
wxString netname;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2009-05-24 18:28:36 +00:00
|
|
|
if( net && (net->GetNetname() != wxEmptyString) )
|
|
|
|
netname = net->GetNetname();
|
2007-08-23 04:28:46 +00:00
|
|
|
else
|
|
|
|
netname = wxT( "_noname_" );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "ROUTE %s\n", TO_UTF8( netname ) );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2013-01-13 00:04:00 +00:00
|
|
|
if( old_width != track->GetWidth() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-01-13 00:04:00 +00:00
|
|
|
old_width = track->GetWidth();
|
|
|
|
fprintf( aFile, "TRACK TRACK%d\n", track->GetWidth() );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2011-10-01 19:24:27 +00:00
|
|
|
if( (track->Type() == PCB_TRACE_T) || (track->Type() == PCB_ZONE_T) )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
|
|
|
if( old_layer != track->GetLayer() )
|
|
|
|
{
|
|
|
|
old_layer = track->GetLayer();
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "LAYER %s\n",
|
2014-06-24 16:17:18 +00:00
|
|
|
GenCADLayerName( cu_count, track->GetLayer() ).c_str()
|
|
|
|
);
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
2013-01-13 00:04:00 +00:00
|
|
|
MapXTo( track->GetStart().x ), MapYTo( track->GetStart().y ),
|
|
|
|
MapXTo( track->GetEnd().x ), MapYTo( track->GetEnd().y ) );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
2014-06-24 16:17:18 +00:00
|
|
|
|
2011-10-01 19:24:27 +00:00
|
|
|
if( track->Type() == PCB_VIA_T )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2014-06-24 16:17:18 +00:00
|
|
|
const VIA* via = static_cast<const VIA*>(track);
|
|
|
|
|
|
|
|
LSET vset = via->GetLayerSet() & master_layermask;
|
|
|
|
|
|
|
|
fprintf( aFile, "VIA VIA%d.%d.%s %g %g ALL %g via%d\n",
|
2014-04-25 06:00:04 +00:00
|
|
|
via->GetWidth(), via->GetDrillValue(),
|
2014-06-30 15:03:20 +00:00
|
|
|
fmt_mask( vset ).c_str(),
|
2014-04-25 06:00:04 +00:00
|
|
|
MapXTo( via->GetStart().x ), MapYTo( via->GetStart().y ),
|
|
|
|
via->GetDrillValue() / SCALE_FACTOR, vianum++ );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDROUTES\n\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-11-10 15:55:05 +00:00
|
|
|
delete tracklist;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-12 10:18:02 +00:00
|
|
|
/* Creates the section $DEVICES
|
2009-11-02 20:36:20 +00:00
|
|
|
* This is a list of footprints properties
|
|
|
|
* ( Shapes are in section $SHAPE )
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateDevicesSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
MODULE* module;
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$DEVICES\n", aFile );
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( module = aPcb->m_Modules; module; module = module->Next() )
|
2011-12-05 07:03:57 +00:00
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
fprintf( aFile, "DEVICE \"%s\"\n", TO_UTF8( module->GetReference() ) );
|
|
|
|
fprintf( aFile, "PART \"%s\"\n", TO_UTF8( module->GetValue() ) );
|
2013-09-08 18:31:21 +00:00
|
|
|
fprintf( aFile, "PACKAGE \"%s\"\n", module->GetFPID().Format().c_str() );
|
2011-12-05 07:03:57 +00:00
|
|
|
|
|
|
|
// The TYPE attribute is almost freeform
|
|
|
|
const char* ty = "TH";
|
2013-09-08 18:31:21 +00:00
|
|
|
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetAttributes() & MOD_CMS )
|
2011-12-02 15:09:57 +00:00
|
|
|
ty = "SMD";
|
2013-09-08 18:31:21 +00:00
|
|
|
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetAttributes() & MOD_VIRTUAL )
|
2011-12-02 15:09:57 +00:00
|
|
|
ty = "VIRTUAL";
|
2013-09-08 18:31:21 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "TYPE %s\n", ty );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDDEVICES\n\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-12 10:18:02 +00:00
|
|
|
/* Creates the section $BOARD.
|
2011-12-02 15:09:57 +00:00
|
|
|
* We output here only the board perimeter
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateBoardSection( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$BOARD\n", aFile );
|
2011-12-05 07:03:57 +00:00
|
|
|
|
++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
|
|
|
// Extract the board edges
|
2015-03-21 09:06:04 +00:00
|
|
|
for( EDA_ITEM* drawing = aPcb->m_Drawings; drawing != 0;
|
++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
|
|
|
drawing = drawing->Next() )
|
2011-12-02 15:09:57 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
if( drawing->Type() == PCB_LINE_T )
|
++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
|
|
|
{
|
2015-03-21 09:06:04 +00:00
|
|
|
DRAWSEGMENT* drawseg = static_cast<DRAWSEGMENT*>( drawing );
|
2014-06-24 16:17:18 +00:00
|
|
|
if( drawseg->GetLayer() == Edge_Cuts )
|
2011-12-05 07:03:57 +00:00
|
|
|
{
|
|
|
|
// XXX GenCAD supports arc boundaries but I've seen nothing that reads them
|
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
2013-09-08 18:31:21 +00:00
|
|
|
MapXTo( drawseg->GetStart().x ), MapYTo( drawseg->GetStart().y ),
|
|
|
|
MapXTo( drawseg->GetEnd().x ), MapYTo( drawseg->GetEnd().y ) );
|
2011-12-05 07:03:57 +00:00
|
|
|
}
|
++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
|
|
|
}
|
|
|
|
}
|
2011-12-05 07:03:57 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDBOARD\n\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
/* Creates the section "$TRACKS"
|
|
|
|
* This sections give the list of widths (tools) used in tracks and vias
|
2007-08-23 04:28:46 +00:00
|
|
|
* format:
|
|
|
|
* $TRACK
|
|
|
|
* TRACK <name> <width>
|
|
|
|
* $ENDTRACK
|
2008-11-18 18:13:55 +00:00
|
|
|
*
|
2009-11-02 20:36:20 +00:00
|
|
|
* Each tool name is build like this: "TRACK" + track width.
|
|
|
|
* For instance for a width = 120 : name = "TRACK120".
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void CreateTracksInfoData( FILE* aFile, BOARD* aPcb )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2007-08-23 04:28:46 +00:00
|
|
|
TRACK* track;
|
2009-11-02 20:36:20 +00:00
|
|
|
int last_width = -1;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Find thickness used for traces
|
|
|
|
// XXX could use the same sorting approach used for pads
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2009-05-23 15:53:47 +00:00
|
|
|
std::vector <int> trackinfo;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
unsigned ii;
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( track = aPcb->m_Track; track; track = track->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-01-13 00:04:00 +00:00
|
|
|
if( last_width != track->GetWidth() ) // Find a thickness already used.
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2009-11-14 22:15:22 +00:00
|
|
|
for( ii = 0; ii < trackinfo.size(); ii++ )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-01-13 00:04:00 +00:00
|
|
|
if( trackinfo[ii] == track->GetWidth() )
|
2009-11-02 20:36:20 +00:00
|
|
|
break;
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
if( ii == trackinfo.size() ) // not found
|
2013-01-13 00:04:00 +00:00
|
|
|
trackinfo.push_back( track->GetWidth() );
|
2009-05-23 15:53:47 +00:00
|
|
|
|
2013-01-13 00:04:00 +00:00
|
|
|
last_width = track->GetWidth();
|
2009-11-02 20:36:20 +00:00
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2014-06-24 16:17:18 +00:00
|
|
|
for( track = aPcb->m_Zone; track; track = track->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-01-13 00:04:00 +00:00
|
|
|
if( last_width != track->GetWidth() ) // Find a thickness already used.
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2009-11-14 22:15:22 +00:00
|
|
|
for( ii = 0; ii < trackinfo.size(); ii++ )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2013-01-13 00:04:00 +00:00
|
|
|
if( trackinfo[ii] == track->GetWidth() )
|
2009-11-02 20:36:20 +00:00
|
|
|
break;
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
if( ii == trackinfo.size() ) // not found
|
2013-01-13 00:04:00 +00:00
|
|
|
trackinfo.push_back( track->GetWidth() );
|
2009-05-23 15:53:47 +00:00
|
|
|
|
2013-01-13 00:04:00 +00:00
|
|
|
last_width = track->GetWidth();
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write data
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$TRACKS\n", aFile );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2009-11-14 22:15:22 +00:00
|
|
|
for( ii = 0; ii < trackinfo.size(); ii++ )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
++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
|
|
|
fprintf( aFile, "TRACK TRACK%d %g\n", trackinfo[ii],
|
2011-12-05 07:03:57 +00:00
|
|
|
trackinfo[ii] / SCALE_FACTOR );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fputs( "$ENDTRACKS\n\n", aFile );
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
/* Creates the shape of a footprint (section SHAPE)
|
|
|
|
* The shape is always given "normal" (Orient 0, not mirrored)
|
2011-12-02 15:09:57 +00:00
|
|
|
* It's almost guaranteed that the silk layer will be imported wrong but
|
|
|
|
* the shape also contains the pads!
|
2007-08-23 04:28:46 +00:00
|
|
|
*/
|
2011-12-02 15:09:57 +00:00
|
|
|
static void FootprintWriteShape( FILE* aFile, MODULE* module )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
EDGE_MODULE* PtEdge;
|
|
|
|
EDA_ITEM* PtStruct;
|
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Control Y axis change sign for flipped modules
|
2011-12-05 07:03:57 +00:00
|
|
|
int Yaxis_sign = -1;
|
2011-12-02 15:09:57 +00:00
|
|
|
|
++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
|
|
|
// Flip for bottom side components
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetFlag() )
|
2011-12-02 15:09:57 +00:00
|
|
|
Yaxis_sign = 1;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2009-11-02 20:36:20 +00:00
|
|
|
/* creates header: */
|
2013-03-13 18:53:58 +00:00
|
|
|
fprintf( aFile, "\nSHAPE %s\n", TO_UTF8( module->GetReference() ) );
|
2011-12-02 15:09:57 +00:00
|
|
|
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetAttributes() & MOD_VIRTUAL )
|
2011-12-02 15:09:57 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
fprintf( aFile, "INSERT SMD\n" );
|
2011-12-02 15:09:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
if( module->GetAttributes() & MOD_CMS )
|
2011-12-05 07:03:57 +00:00
|
|
|
{
|
|
|
|
fprintf( aFile, "INSERT SMD\n" );
|
2011-12-02 15:09:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fprintf( aFile, "INSERT TH\n" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 /* ATTRIBUTE name and value is unspecified and the original exporter
|
|
|
|
* got the syntax wrong, so CAM350 rejected the whole shape! */
|
2007-08-23 04:28:46 +00:00
|
|
|
|
|
|
|
if( module->m_Attributs != MOD_DEFAULT )
|
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "ATTRIBUTE" );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
if( module->m_Attributs & MOD_CMS )
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, " PAD_SMD" );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2007-08-23 04:28:46 +00:00
|
|
|
if( module->m_Attributs & MOD_VIRTUAL )
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, " VIRTUAL" );
|
2011-09-07 19:41:04 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "\n" );
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
2011-12-02 15:09:57 +00:00
|
|
|
#endif
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-02 15:09:57 +00:00
|
|
|
// Silk outline; wildly interpreted by various importers:
|
|
|
|
// CAM350 read it right but only closed shapes
|
|
|
|
// ProntoPlace double-flip it (at least the pads are correct)
|
|
|
|
// GerberTool usually get it right...
|
2014-06-24 16:17:18 +00:00
|
|
|
for( PtStruct = module->GraphicalItems(); PtStruct; PtStruct = PtStruct->Next() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-12-02 15:09:57 +00:00
|
|
|
switch( PtStruct->Type() )
|
2007-08-23 04:28:46 +00:00
|
|
|
{
|
2011-10-01 19:24:27 +00:00
|
|
|
case PCB_MODULE_TEXT_T:
|
2011-12-05 07:03:57 +00:00
|
|
|
|
|
|
|
// If we wanted to export text, this is not the correct section
|
2007-08-23 04:28:46 +00:00
|
|
|
break;
|
|
|
|
|
2011-10-01 19:24:27 +00:00
|
|
|
case PCB_MODULE_EDGE_T:
|
2011-12-02 15:09:57 +00:00
|
|
|
PtEdge = (EDGE_MODULE*) PtStruct;
|
2014-06-24 16:17:18 +00:00
|
|
|
if( PtEdge->GetLayer() == F_SilkS
|
|
|
|
|| PtEdge->GetLayer() == B_SilkS )
|
2011-12-02 15:09:57 +00:00
|
|
|
{
|
2011-12-14 04:29:25 +00:00
|
|
|
switch( PtEdge->GetShape() )
|
2011-12-05 07:03:57 +00:00
|
|
|
{
|
|
|
|
case S_SEGMENT:
|
2011-12-02 15:09:57 +00:00
|
|
|
fprintf( aFile, "LINE %g %g %g %g\n",
|
2011-12-05 07:03:57 +00:00
|
|
|
(PtEdge->m_Start0.x) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * PtEdge->m_Start0.y) / SCALE_FACTOR,
|
|
|
|
(PtEdge->m_End0.x) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * PtEdge->m_End0.y ) / SCALE_FACTOR );
|
|
|
|
break;
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
case S_CIRCLE:
|
|
|
|
{
|
2013-05-01 17:32:36 +00:00
|
|
|
int radius = KiROUND( GetLineLength( PtEdge->m_End0,
|
|
|
|
PtEdge->m_Start0 ) );
|
2011-12-05 07:03:57 +00:00
|
|
|
fprintf( aFile, "CIRCLE %g %g %g\n",
|
|
|
|
PtEdge->m_Start0.x / SCALE_FACTOR,
|
|
|
|
Yaxis_sign * PtEdge->m_Start0.y / SCALE_FACTOR,
|
|
|
|
radius / SCALE_FACTOR );
|
|
|
|
break;
|
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
|
++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
|
|
|
case S_ARC:
|
2011-12-05 07:03:57 +00:00
|
|
|
{
|
|
|
|
int arcendx, arcendy;
|
|
|
|
arcendx = PtEdge->m_End0.x - PtEdge->m_Start0.x;
|
|
|
|
arcendy = PtEdge->m_End0.y - PtEdge->m_Start0.y;
|
2011-12-14 04:29:25 +00:00
|
|
|
RotatePoint( &arcendx, &arcendy, -PtEdge->GetAngle() );
|
|
|
|
arcendx += PtEdge->GetStart0().x;
|
|
|
|
arcendy += PtEdge->GetStart0().y;
|
2011-12-05 07:03:57 +00:00
|
|
|
if( Yaxis_sign == -1 )
|
2011-12-02 15:09:57 +00:00
|
|
|
{
|
2011-12-05 07:03:57 +00:00
|
|
|
// Flipping Y flips the arc direction too
|
|
|
|
fprintf( aFile, "ARC %g %g %g %g %g %g\n",
|
|
|
|
(arcendx) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * arcendy) / SCALE_FACTOR,
|
|
|
|
(PtEdge->m_End0.x) / SCALE_FACTOR,
|
2011-12-14 04:29:25 +00:00
|
|
|
(Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
|
|
|
|
(PtEdge->GetStart0().x) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
|
2011-12-05 07:03:57 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fprintf( aFile, "ARC %g %g %g %g %g %g\n",
|
2011-12-14 04:29:25 +00:00
|
|
|
(PtEdge->GetEnd0().x) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
|
2011-12-05 07:03:57 +00:00
|
|
|
(arcendx) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * arcendy) / SCALE_FACTOR,
|
2011-12-14 04:29:25 +00:00
|
|
|
(PtEdge->GetStart0().x) / SCALE_FACTOR,
|
|
|
|
(Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
|
2011-12-05 07:03:57 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
|
2016-06-05 11:49:25 +00:00
|
|
|
case S_POLYGON:
|
|
|
|
// Not exported (TODO)
|
|
|
|
break;
|
|
|
|
|
2011-12-05 07:03:57 +00:00
|
|
|
default:
|
2016-06-05 11:49:25 +00:00
|
|
|
DisplayError( NULL, wxString::Format( "Type Edge Module %d invalid.", PtStruct->Type() ) );
|
2011-12-05 07:03:57 +00:00
|
|
|
break;
|
++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
|
|
|
}
|
2011-12-02 15:09:57 +00:00
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
++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
|
|
|
}
|
2007-08-23 04:28:46 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|