2008-02-06 22:32:15 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2007-2008 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
|
|
|
* Copyright (C) 2007 Kicad Developers, see change_log.txt for contributors.
|
2008-02-07 20:23:58 +00:00
|
|
|
*
|
2008-02-06 22:32:15 +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.
|
2008-02-07 20:23:58 +00:00
|
|
|
*
|
2008-02-06 22:32:15 +00:00
|
|
|
* 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.
|
2008-02-07 20:23:58 +00:00
|
|
|
*
|
2008-02-06 22:32:15 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
2008-02-07 20:23:58 +00:00
|
|
|
* 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.,
|
2008-02-06 22:32:15 +00:00
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-06 22:32:15 +00:00
|
|
|
/* This source is a complement to specctra.cpp and implements the import of
|
2008-02-07 20:23:58 +00:00
|
|
|
a specctra session file (*.ses), and import of a specctra design file
|
|
|
|
(*.dsn) file. The specification for the grammar of the specctra dsn file
|
2008-02-06 22:32:15 +00:00
|
|
|
used to develop this code is given here:
|
|
|
|
http://www.autotraxeda.com/docs/SPECCTRA/SPECCTRA.pdf
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-06 22:32:15 +00:00
|
|
|
Also see the comments at the top of the specctra.cpp file itself.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "specctra.h"
|
2008-02-07 06:49:16 +00:00
|
|
|
#include "common.h" // IsOK() & EDA_FileSelector()
|
|
|
|
|
2008-02-06 22:32:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
using namespace DSN;
|
|
|
|
|
|
|
|
void WinEDA_PcbFrame::ImportSpecctraDesign( wxCommandEvent& event )
|
|
|
|
{
|
2008-02-07 20:23:58 +00:00
|
|
|
/* @todo write this someday
|
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
if( !Clear_Pcb( true ) )
|
|
|
|
return;
|
2008-02-07 20:23:58 +00:00
|
|
|
*/
|
2008-02-06 22:32:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
|
|
|
|
{
|
2008-02-07 20:23:58 +00:00
|
|
|
/*
|
2008-02-07 06:49:16 +00:00
|
|
|
if( GetScreen()->IsModify() )
|
|
|
|
{
|
|
|
|
if( !IsOK( this, _( "Board Modified: Continue ?" ) ) )
|
|
|
|
return;
|
|
|
|
}
|
2008-02-07 20:23:58 +00:00
|
|
|
*/
|
2008-02-07 06:49:16 +00:00
|
|
|
|
|
|
|
wxString sessionExt( wxT( ".ses" ) );
|
|
|
|
wxString fileName = GetScreen()->m_FileName;
|
|
|
|
wxString mask = wxT( "*" ) + sessionExt;
|
|
|
|
|
|
|
|
ChangeFileNameExt( fileName, sessionExt );
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
fileName = EDA_FileSelector( _( "Merge Specctra Session file:" ),
|
|
|
|
wxEmptyString,
|
|
|
|
fileName,
|
|
|
|
sessionExt,
|
|
|
|
mask,
|
|
|
|
this,
|
|
|
|
wxFD_OPEN,
|
|
|
|
FALSE );
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
if( fileName == wxEmptyString )
|
|
|
|
return;
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
SPECCTRA_DB db;
|
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2008-02-07 06:49:16 +00:00
|
|
|
db.LoadSESSION( fileName );
|
|
|
|
db.FromSESSION( m_Pcb );
|
|
|
|
}
|
|
|
|
catch( IOError ioe )
|
|
|
|
{
|
2008-02-07 20:23:58 +00:00
|
|
|
setlocale( LC_NUMERIC, "" ); // revert to the current locale
|
2008-02-07 06:49:16 +00:00
|
|
|
DisplayError( this, ioe.errorText );
|
|
|
|
return;
|
|
|
|
}
|
2008-02-07 17:10:12 +00:00
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
setlocale( LC_NUMERIC, "" ); // revert to the current locale
|
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
m_SelTrackWidthBox_Changed = TRUE;
|
|
|
|
m_SelViaSizeBox_Changed = TRUE;
|
|
|
|
|
|
|
|
GetScreen()->SetModify();
|
|
|
|
m_Pcb->m_Status_Pcb = 0;
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
Affiche_Message( wxString( _("Session file imported and merged OK.")) );
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
DrawPanel->Refresh( TRUE );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace DSN {
|
2008-02-07 17:10:12 +00:00
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
|
|
|
|
static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution )
|
2008-02-07 17:10:12 +00:00
|
|
|
{
|
|
|
|
wxPoint ret;
|
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
double resValue = aResolution->GetValue();
|
|
|
|
|
|
|
|
double factor; // multiply this times units to get mils for Kicad.
|
|
|
|
|
|
|
|
switch( aResolution->GetEngUnits() )
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case T_inch:
|
|
|
|
factor = 0.001;
|
|
|
|
break;
|
|
|
|
case T_mil:
|
|
|
|
factor = 1.0;
|
|
|
|
break;
|
|
|
|
case T_cm:
|
|
|
|
factor = 2.54/1000.0;
|
|
|
|
break;
|
|
|
|
case T_mm:
|
|
|
|
factor = 25.4/1000.0;
|
|
|
|
break;
|
|
|
|
case T_um:
|
|
|
|
factor = 25.4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
// the factor of 10.0 is used to convert mils to deci-mils, the units
|
2008-02-07 20:23:58 +00:00
|
|
|
// used within Kicad.
|
|
|
|
factor *= 10.0;
|
|
|
|
|
|
|
|
ret.x = (int) (factor * aPoint.x / resValue);
|
|
|
|
ret.y = (int) -(factor * aPoint.y / resValue); // negate y coord
|
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2008-02-07 06:49:16 +00:00
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
|
|
|
|
// no UI code in this function, throw exception to report problems to the
|
2008-02-07 06:49:16 +00:00
|
|
|
// UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
|
|
|
|
|
|
|
|
void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
|
|
|
|
{
|
2008-02-07 17:10:12 +00:00
|
|
|
//wxASSERT( session );
|
2008-02-07 06:49:16 +00:00
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
if( !session )
|
|
|
|
ThrowIOError( _("Session file is missing the \"session\" section") );
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
if( !session->placement )
|
|
|
|
ThrowIOError( _("Session file is missing the \"placement\" section") );
|
|
|
|
|
|
|
|
if( !session->route )
|
|
|
|
ThrowIOError( _("Session file is missing the \"routes\" section") );
|
|
|
|
|
|
|
|
if( !session->route->library )
|
|
|
|
ThrowIOError( _("Session file is missing the \"library_out\" section") );
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
// delete all the old tracks and vias
|
|
|
|
aBoard->m_Track->DeleteStructList();
|
|
|
|
aBoard->m_Track = NULL;
|
|
|
|
aBoard->m_NbSegmTrack = 0;
|
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
aBoard->DeleteMARKERs();
|
2008-02-07 17:10:12 +00:00
|
|
|
|
|
|
|
// Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
|
2008-02-07 20:23:58 +00:00
|
|
|
// each COMPONENT, reposition and re-orient each component and put on
|
2008-02-07 17:10:12 +00:00
|
|
|
// correct side of the board.
|
2008-02-07 06:49:16 +00:00
|
|
|
COMPONENTS& components = session->placement->components;
|
2008-02-07 17:10:12 +00:00
|
|
|
for( COMPONENTS::iterator comp=components.begin(); comp!=components.end(); ++comp )
|
2008-02-07 06:49:16 +00:00
|
|
|
{
|
2008-02-07 17:10:12 +00:00
|
|
|
PLACES& places = comp->places;
|
|
|
|
for( unsigned i=0; i<places.size(); ++i )
|
|
|
|
{
|
|
|
|
PLACE* place = &places[i]; // '&' even though places[] holds a pointer!
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
wxString reference = CONV_FROM_UTF8( place->component_id.c_str() );
|
|
|
|
MODULE* module = aBoard->FindModuleByReference( reference );
|
|
|
|
if( !module )
|
|
|
|
{
|
2008-02-07 20:23:58 +00:00
|
|
|
ThrowIOError(
|
|
|
|
_("Session file has 'reference' to non-existent component \"%s\""),
|
2008-02-07 17:10:12 +00:00
|
|
|
reference.GetData() );
|
|
|
|
}
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
if( !place->hasVertex )
|
|
|
|
continue;
|
2008-02-07 20:23:58 +00:00
|
|
|
|
|
|
|
UNIT_RES* resolution = place->GetUnits();
|
|
|
|
wxASSERT( resolution );
|
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
wxPoint newPos = mapPt( place->vertex, resolution );
|
|
|
|
module->SetPosition( newPos );
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
if( place->side == T_front )
|
|
|
|
{
|
|
|
|
// convert from degrees to tenths of degrees used in Kicad.
|
|
|
|
int orientation = (int) (place->rotation * 10.0);
|
2008-02-07 20:23:58 +00:00
|
|
|
|
2008-02-07 17:10:12 +00:00
|
|
|
if( module->GetLayer() != CMP_N )
|
2008-02-07 20:23:58 +00:00
|
|
|
{
|
|
|
|
// module is on copper layer (back)
|
2008-02-07 17:10:12 +00:00
|
|
|
aBoard->Change_Side_Module( module, 0 );
|
2008-02-07 20:23:58 +00:00
|
|
|
}
|
|
|
|
module->SetOrientation( orientation );
|
2008-02-07 17:10:12 +00:00
|
|
|
}
|
|
|
|
else if( place->side == T_back )
|
|
|
|
{
|
2008-02-07 20:23:58 +00:00
|
|
|
int orientation = (place->rotation + 180.0) * 10.0;
|
2008-02-07 17:10:12 +00:00
|
|
|
if( module->GetLayer() != COPPER_LAYER_N )
|
2008-02-07 20:23:58 +00:00
|
|
|
{
|
|
|
|
// module is on component layer (front)
|
2008-02-07 17:10:12 +00:00
|
|
|
aBoard->Change_Side_Module( module, 0 );
|
2008-02-07 20:23:58 +00:00
|
|
|
}
|
|
|
|
module->SetOrientation( orientation );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// as I write this, the LEXER *is* catching this, so we should never see below:
|
|
|
|
wxFAIL_MSG( wxT("DSN::LEXER did not catch an illegal side := 'back|front'") );
|
2008-02-07 17:10:12 +00:00
|
|
|
}
|
|
|
|
}
|
2008-02-07 06:49:16 +00:00
|
|
|
}
|
|
|
|
|
2008-02-07 20:23:58 +00:00
|
|
|
// Walk the NET_OUTs and create tracks and vias anew.
|
2008-02-07 06:49:16 +00:00
|
|
|
NET_OUTS& net_outs = session->route->net_outs;
|
|
|
|
for( NET_OUTS::iterator i=net_outs.begin(); i!=net_outs.end(); ++i )
|
|
|
|
{
|
|
|
|
// create a track or via and position it.
|
2008-02-07 20:23:58 +00:00
|
|
|
|
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
}
|
2008-02-06 22:32:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-07 06:49:16 +00:00
|
|
|
} // namespace DSN
|
|
|
|
|