Commit 8ef96230 authored by dickelbeck's avatar dickelbeck

more amazing free specctra software

parent 316d7b73
...@@ -1251,10 +1251,10 @@ void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth ) throw( IOError ) ...@@ -1251,10 +1251,10 @@ void SPECCTRA_DB::doPROPERTIES( PROPERTIES* growth ) throw( IOError )
if( tok != T_LEFT ) if( tok != T_LEFT )
expecting( T_LEFT ); expecting( T_LEFT );
needSYMBOL(); needSYMBOLorNUMBER();
property.name = lexer->CurText(); property.name = lexer->CurText();
needSYMBOL(); needSYMBOLorNUMBER();
property.value = lexer->CurText(); property.value = lexer->CurText();
growth->push_back( property ); growth->push_back( property );
...@@ -1848,7 +1848,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError ) ...@@ -1848,7 +1848,7 @@ void SPECCTRA_DB::doPLACE( PLACE* growth ) throw( IOError )
case T_pn: case T_pn:
if( growth->part_number.size() ) if( growth->part_number.size() )
unexpected( tok ); unexpected( tok );
needSYMBOL(); needSYMBOLorNUMBER();
growth->part_number = lexer->CurText(); growth->part_number = lexer->CurText();
needRIGHT(); needRIGHT();
break; break;
...@@ -2561,7 +2561,7 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError ) ...@@ -2561,7 +2561,7 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
doTOPOLOGY( growth->topology ); doTOPOLOGY( growth->topology );
break; break;
default: // handle all the circuit_descriptor here as strings case T_circuit: // handle all the circuit_descriptor here as strings
{ {
std::string builder; std::string builder;
int bracketNesting = 1; // we already saw the opening T_LEFT int bracketNesting = 1; // we already saw the opening T_LEFT
...@@ -2607,6 +2607,10 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError ) ...@@ -2607,6 +2607,10 @@ void SPECCTRA_DB::doCLASS( CLASS* growth ) throw( IOError )
if( tok==T_EOF ) if( tok==T_EOF )
unexpected( T_EOF ); unexpected( T_EOF );
} // scope bracket } // scope bracket
break;
default:
unexpected( lexer->CurText() );
} // switch } // switch
tok = nextTok(); tok = nextTok();
...@@ -3486,6 +3490,7 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote ...@@ -3486,6 +3490,7 @@ const char* OUTPUTFORMATTER::GetQuoteChar( const char* wrapee, const char* quote
{ {
static const char quoteThese[] = "\t ()" static const char quoteThese[] = "\t ()"
"%" // per Alfons of freerouting.net, he does not like this unquoted as of 1-Feb-2008 "%" // per Alfons of freerouting.net, he does not like this unquoted as of 1-Feb-2008
"{}" // guessing that these are problems too
; ;
// if the string to be wrapped (wrapee) has a delimiter in it, // if the string to be wrapped (wrapee) has a delimiter in it,
......
...@@ -225,8 +225,8 @@ struct POINT ...@@ -225,8 +225,8 @@ struct POINT
/** /**
* Function FixNegativeZero * Function FixNegativeZero
* will change negative zero to positive zero in the IEEE floating point * will change negative zero to positive zero in the IEEE floating point
* storage format. Basically turns off the sign bit if the mantiss and exponent * storage format. Basically turns off the sign bit if the mantissa and
* would say the value is zero. * exponent say the value is otherwise zero.
*/ */
void FixNegativeZero() void FixNegativeZero()
{ {
...@@ -536,7 +536,7 @@ class RECTANGLE : public ELEM ...@@ -536,7 +536,7 @@ class RECTANGLE : public ELEM
std::string layer_id; std::string layer_id;
POINT point0; POINT point0; ///< one of two opposite corners
POINT point1; POINT point1;
public: public:
...@@ -882,11 +882,12 @@ class WINDOW : public ELEM ...@@ -882,11 +882,12 @@ class WINDOW : public ELEM
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
protected: protected:
/* shape holds one of these /* <shape_descriptor >::=
PATH* path; ///< used for both path and polygon [<rectangle_descriptor> |
RECTANGLE* rectangle; <circle_descriptor> |
CIRCLE* circle; <polygon_descriptor> |
QARC* qarc; <path_descriptor> |
<qarc_descriptor> ]
*/ */
ELEM* shape; ELEM* shape;
...@@ -2561,6 +2562,7 @@ public: ...@@ -2561,6 +2562,7 @@ public:
out->Print( 0, "\n" ); out->Print( 0, "\n" );
} }
}; };
typedef boost::ptr_vector<COMP_ORDER> COMP_ORDERS;
class NET : public ELEM class NET : public ELEM
...@@ -2677,6 +2679,7 @@ public: ...@@ -2677,6 +2679,7 @@ public:
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
}; };
typedef boost::ptr_vector<NET> NETS;
class TOPOLOGY : public ELEM class TOPOLOGY : public ELEM
...@@ -2685,7 +2688,6 @@ class TOPOLOGY : public ELEM ...@@ -2685,7 +2688,6 @@ class TOPOLOGY : public ELEM
FROMTOS fromtos; FROMTOS fromtos;
typedef boost::ptr_vector<COMP_ORDER> COMP_ORDERS;
COMP_ORDERS comp_orders; COMP_ORDERS comp_orders;
public: public:
...@@ -2739,35 +2741,45 @@ public: ...@@ -2739,35 +2741,45 @@ public:
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
const int RIGHTMARGIN = 80;
const char* quote = out->GetQuoteChar( class_id.c_str() ); const char* quote = out->GetQuoteChar( class_id.c_str() );
int perLine = out->Print( nestLevel, "(%s %s%s%s", int perLine = out->Print( nestLevel, "(%s %s%s%s",
LEXER::GetTokenText( Type() ), LEXER::GetTokenText( Type() ),
quote, class_id.c_str(), quote ); quote, class_id.c_str(), quote );
const int RIGHTMARGIN = 72;
for( STRINGS::iterator i=net_ids.begin(); i!=net_ids.end(); ++i ) for( STRINGS::iterator i=net_ids.begin(); i!=net_ids.end(); ++i )
{ {
const char* space = " ";
if( perLine > RIGHTMARGIN ) if( perLine > RIGHTMARGIN )
{ {
out->Print( 0, "\n" ); out->Print( 0, "\n" );
perLine = out->Print( nestLevel+1, "%s", "" ); perLine = out->Print( nestLevel+1, "%s", "" );
space = ""; // no space at first net_id of the line
} }
quote = out->GetQuoteChar( i->c_str() ); quote = out->GetQuoteChar( i->c_str() );
perLine += out->Print( 0, " %s%s%s", quote, i->c_str(), quote ); perLine += out->Print( 0, "%s%s%s%s", space, quote, i->c_str(), quote );
} }
bool newLine = false; bool newLine = false;
if( circuit.size() || layer_rules.size() || topology ) if( circuit.size() || rules || layer_rules.size() || topology )
{ {
out->Print( 0, "\n" ); out->Print( 0, "\n" );
newLine = true; newLine = true;
} }
if( circuit.size() )
{
out->Print( nestLevel+1, "(circuit\n" );
for( STRINGS::iterator i=circuit.begin(); i!=circuit.end(); ++i ) for( STRINGS::iterator i=circuit.begin(); i!=circuit.end(); ++i )
out->Print( nestLevel+1, "%s\n", i->c_str() ); out->Print( nestLevel+2, "%s\n", i->c_str() );
out->Print( nestLevel+1, ")\n" );
}
if( rules )
rules->Format( out, nestLevel+1 );
for( LAYER_RULES::iterator i=layer_rules.begin(); i!=layer_rules.end(); ++i ) for( LAYER_RULES::iterator i=layer_rules.begin(); i!=layer_rules.end(); ++i )
i->Format( out, nestLevel+1 ); i->Format( out, nestLevel+1 );
...@@ -2778,16 +2790,14 @@ public: ...@@ -2778,16 +2790,14 @@ public:
out->Print( newLine ? nestLevel : 0, ")\n" ); out->Print( newLine ? nestLevel : 0, ")\n" );
} }
}; };
typedef boost::ptr_vector<CLASS> CLASSLIST;
class NETWORK : public ELEM class NETWORK : public ELEM
{ {
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
typedef boost::ptr_vector<NET> NETS;
NETS nets; NETS nets;
typedef boost::ptr_vector<CLASS> CLASSLIST;
CLASSLIST classes; CLASSLIST classes;
...@@ -3637,6 +3647,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3637,6 +3647,7 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/ */
int findLayerName( const std::string& aLayerName ) const; int findLayerName( const std::string& aLayerName ) const;
/** /**
* Function nextTok * Function nextTok
* returns the next token from the lexer. * returns the next token from the lexer.
...@@ -3843,12 +3854,6 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3843,12 +3854,6 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
nets.clear(); nets.clear();
} }
/**
* Function flipMODULEs
* flips the modules which are on the back side of the board to the front.
*/
void flipMODULEs( BOARD* aBoard );
//-----<FromSESSION>----------------------------------------------------- //-----<FromSESSION>-----------------------------------------------------
/** /**
...@@ -4002,6 +4007,12 @@ public: ...@@ -4002,6 +4007,12 @@ public:
*/ */
void ExportSESSION( wxString aFilename ); void ExportSESSION( wxString aFilename );
/**
* Function FlipMODULEs
* flips the modules which are on the back side of the board to the front.
*/
void FlipMODULEs( BOARD* aBoard );
/** /**
* Function RevertMODULEs * Function RevertMODULEs
* flips the modules which were on the back side of the board back to the back. * flips the modules which were on the back side of the board back to the back.
......
...@@ -84,6 +84,11 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event ) ...@@ -84,6 +84,11 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C setlocale( LC_NUMERIC, "C" ); // Switch the locale to standard C
// DSN Images (=Kicad MODULES and pads) must be presented from the
// top view. So we temporarily flip any modules which are on the back
// side of the board to the front, and record this in the MODULE's flag field.
db.FlipMODULEs( m_Pcb );
try try
{ {
db.FromBOARD( m_Pcb ); db.FromBOARD( m_Pcb );
...@@ -102,8 +107,7 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event ) ...@@ -102,8 +107,7 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
setlocale( LC_NUMERIC, "" ); // revert to the current locale setlocale( LC_NUMERIC, "" ); // revert to the current locale
// this is called in FromBOARD() too, but if it throws an exception, that call // done assuredly, even if an exception was thrown and caught.
// does not happen, so call it again just in case here.
db.RevertMODULEs( m_Pcb ); db.RevertMODULEs( m_Pcb );
...@@ -538,7 +542,7 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad ) ...@@ -538,7 +542,7 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad )
} }
/// data type used to ensure unique-ness of pin names /// data type used to ensure unique-ness of pin names, holding (wxString and int)
typedef std::map<wxString, int, wxString_less_than> PINMAP; typedef std::map<wxString, int, wxString_less_than> PINMAP;
...@@ -672,19 +676,26 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule ) ...@@ -672,19 +676,26 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, MODULE* aModule )
path->SetAperture( scale( graphic->m_Width ) ); path->SetAperture( scale( graphic->m_Width ) );
path->SetLayerId( "signal" ); path->SetLayerId( "signal" );
double radius = hypot( scale( graphic->m_Start.x - graphic->m_End.x ), // Do the math using Kicad units, that way we stay out of the
scale( graphic->m_Start.y - graphic->m_End.y ) ); // scientific notation range of floating point numbers in the
// DSN file. We do not parse scientific notation in our own
// lexer/beautifier, and the spec is not clear that this is
// required. Fixed point floats are all that should be needed.
POINT offset = mapPt( graphic->m_Start0 ); double radius = hypot( double( graphic->m_Start.x - graphic->m_End.x ),
double( graphic->m_Start.y - graphic->m_End.y ) );
// better if evenly divisible into 360 // better if evenly divisible into 360
const int DEGREE_INTERVAL = 18; // 18 means 20 line segments const int DEGREE_INTERVAL = 18; // 18 means 20 line segments
for( double radians = 0.0; radians < 2*M_PI; radians += DEGREE_INTERVAL * M_PI / 180.0 ) for( double radians = 0.0; radians < 2*M_PI; radians += DEGREE_INTERVAL * M_PI / 180.0 )
{ {
POINT point( radius*cos( radians ), radius*sin( radians ) ); wxPoint point( int( radius * cos( radians ) ),
point += offset; int( radius * sin( radians ) ) );
path->AppendPoint( point );
point += graphic->m_Start0; // an offset
path->AppendPoint( mapPt(point) );
} }
} }
break; break;
...@@ -749,8 +760,7 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia ) ...@@ -749,8 +760,7 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
return makeVia( aVia->m_Width, aVia->GetDrillValue(), topLayer, botLayer ); return makeVia( aVia->m_Width, aVia->GetDrillValue(), topLayer, botLayer );
} }
typedef std::set<std::string> STRINGSET;
typedef std::set<wxString, wxString_less_than> STRINGSET;
typedef std::pair<STRINGSET::iterator, bool> STRINGSET_PAIR; typedef std::pair<STRINGSET::iterator, bool> STRINGSET_PAIR;
...@@ -785,7 +795,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -785,7 +795,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
} }
// if we cannot insert OK, that means the reference has been seen before. // if we cannot insert OK, that means the reference has been seen before.
STRINGSET_PAIR refpair = refs.insert( module->GetReference() ); STRINGSET_PAIR refpair = refs.insert( CONV_TO_UTF8( module->GetReference() ) );
if( !refpair.second ) // insert failed if( !refpair.second ) // insert failed
{ {
ThrowIOError( _("Multiple components have identical reference IDs of \"%s\"."), ThrowIOError( _("Multiple components have identical reference IDs of \"%s\"."),
...@@ -797,11 +807,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -797,11 +807,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
if( !pcb ) if( !pcb )
pcb = SPECCTRA_DB::MakePCB(); pcb = SPECCTRA_DB::MakePCB();
// DSN Images (=Kicad MODULES and pads) must be presented from the
// top view. So we temporarily flip any modules which are on the back
// side of the board to the front, and record this in the MODULE's flag field.
flipMODULEs( aBoard );
//-----<layer_descriptor>----------------------------------------------- //-----<layer_descriptor>-----------------------------------------------
{ {
// specctra wants top physical layer first, then going down to the // specctra wants top physical layer first, then going down to the
...@@ -938,10 +943,11 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -938,10 +943,11 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
int curTrackWidth = aBoard->m_BoardSettings->m_CurrentTrackWidth; int curTrackWidth = aBoard->m_BoardSettings->m_CurrentTrackWidth;
int curTrackClear = aBoard->m_BoardSettings->m_TrackClearence; int curTrackClear = aBoard->m_BoardSettings->m_TrackClearence;
// The +5 is to give freerouter a little extra room, this is 0.5 mils. // The +1 is to give freerouter a little extra room, this is 0.1 mils.
// If we export without this, then on import freerouter violates our // If we export without this, then on import freerouter violates our
// DRC checks with track to via spacing. // DRC checks with track to via spacing, although this could be a
double clearance = scale(curTrackClear+5); // result of > testing vs. >= testing in PCBNEW's DRC.
double clearance = scale(curTrackClear+1);
STRINGS& rules = pcb->structure->rules->rules; STRINGS& rules = pcb->structure->rules->rules;
...@@ -996,15 +1002,14 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -996,15 +1002,14 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
plane->name = CONV_TO_UTF8( item->m_Netname ); plane->name = CONV_TO_UTF8( item->m_Netname );
wxString layerName = aBoard->GetLayerName( item->GetLayer() ); polygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
polygon->layer_id = CONV_TO_UTF8( layerName );
int count = item->m_Poly->corner.size(); int count = item->m_Poly->corner.size();
for( int j=0; j<count; ++j ) for( int j=0; j<count; ++j )
{ {
wxPoint point( item->m_Poly->corner[j].x, wxPoint point( item->m_Poly->corner[j].x,
item->m_Poly->corner[j].y ); item->m_Poly->corner[j].y );
polygon->points.push_back( mapPt(point) ); polygon->AppendPoint( mapPt(point) );
} }
pcb->structure->planes.push_back( plane ); pcb->structure->planes.push_back( plane );
...@@ -1015,6 +1020,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1015,6 +1020,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
//-----<build the images, components, and netlist>----------------------- //-----<build the images, components, and netlist>-----------------------
{ {
PIN_REF empty( pcb->network );
std::string componentId;
// find the highest numbered netCode within the board. // find the highest numbered netCode within the board.
int highestNetCode = -1; int highestNetCode = -1;
for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() ) for( EQUIPOT* equipot = aBoard->m_Equipots; equipot; equipot = equipot->Next() )
...@@ -1046,15 +1054,17 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1046,15 +1054,17 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
IMAGE* image = makeIMAGE( aBoard, module ); IMAGE* image = makeIMAGE( aBoard, module );
componentId = CONV_TO_UTF8( module->GetReference() );
// create a net list entry for all the actual pins in the image // create a net list entry for all the actual pins in the image
// for the current module. location of this code is critical // for the current module. location of this code is critical
// because we fabricated some pin names to ensure unique-ness // because we fabricated some pin names to ensure unique-ness
// of pin names within a module, do not move this code. The // of pin names within a module, do not move this code because
// the life of this 'IMAGE* image' is not necessarily long. The
// exported netlist will have some fabricated pin names in it. // exported netlist will have some fabricated pin names in it.
// If you don't like fabricated pin names, then make sure all pads // If you don't like fabricated pin names, then make sure all pads
// within your MODULEs are uniquely named! // within your MODULEs are uniquely named!
PIN_REF empty( pcb->network );
for( unsigned p=0; p<image->pins.size(); ++p ) for( unsigned p=0; p<image->pins.size(); ++p )
{ {
PIN* pin = &image->pins[p]; PIN* pin = &image->pins[p];
...@@ -1068,7 +1078,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1068,7 +1078,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
PIN_REF& pin_ref = net->pins.back(); PIN_REF& pin_ref = net->pins.back();
pin_ref.component_id = CONV_TO_UTF8( module->GetReference() ); pin_ref.component_id = componentId;
pin_ref.pin_id = pin->pin_id; pin_ref.pin_id = pin->pin_id;
} }
} }
...@@ -1090,7 +1100,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1090,7 +1100,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
place->SetRotation( module->m_Orient/10.0 ); place->SetRotation( module->m_Orient/10.0 );
place->SetVertex( mapPt( module->m_Pos ) ); place->SetVertex( mapPt( module->m_Pos ) );
place->component_id = CONV_TO_UTF8( module->GetReference() ); place->component_id = componentId;
place->part_number = CONV_TO_UTF8( module->GetValue() ); place->part_number = CONV_TO_UTF8( module->GetValue() );
// module is flipped from bottom side, set side to T_back // module is flipped from bottom side, set side to T_back
...@@ -1115,21 +1125,11 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1115,21 +1125,11 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
pcb->library->AddPadstack( padstack ); pcb->library->AddPadstack( padstack );
} }
D(std::string component = "U1";)
// copy our SPECCTRA_DB::nets to the pcb->network // copy our SPECCTRA_DB::nets to the pcb->network
for( unsigned n=1; n<nets.size(); ++n ) for( unsigned n=1; n<nets.size(); ++n )
{ {
NET* net = nets[n]; NET* net = nets[n];
if( net->pins.size() if( net->pins.size() )
#if defined(DEBUG)
// experimenting with exporting a subset of all the nets
// and with incremental, iterative autorouting.
&& net->FindPIN_REF( component ) >= 0
#endif
)
{ {
// give ownership to pcb->network // give ownership to pcb->network
pcb->network->nets.push_back( net ); pcb->network->nets.push_back( net );
...@@ -1146,7 +1146,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1146,7 +1146,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
// Next we add the via's which may be used. // Next we add the via's which may be used.
int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize; int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize;
/* I need at least one via for the (class...) scope below
if( defaultViaSize ) if( defaultViaSize )
*/
{ {
PADSTACK* padstack = makeVia( defaultViaSize, g_DesignSettings.m_ViaDrill, PADSTACK* padstack = makeVia( defaultViaSize, g_DesignSettings.m_ViaDrill,
0, aBoard->GetCopperLayerCount()-1 ); 0, aBoard->GetCopperLayerCount()-1 );
...@@ -1196,10 +1199,12 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1196,10 +1199,12 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
{ {
TRACK* track = (TRACK*) items[i]; TRACK* track = (TRACK*) items[i];
if( track->GetNet() == 0 ) int netcode = track->GetNet();
if( netcode == 0 )
continue; continue;
if( old_netcode != track->GetNet() if( old_netcode != netcode
|| old_width != track->m_Width || old_width != track->m_Width
|| old_layer != track->GetLayer() || old_layer != track->GetLayer()
|| (path && path->points.back() != mapPt(track->m_Start) ) || (path && path->points.back() != mapPt(track->m_Start) )
...@@ -1208,10 +1213,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1208,10 +1213,10 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
old_width = track->m_Width; old_width = track->m_Width;
old_layer = track->GetLayer(); old_layer = track->GetLayer();
if( old_netcode != track->GetNet() ) if( old_netcode != netcode )
{ {
old_netcode = track->GetNet(); old_netcode = netcode;
EQUIPOT* equipot = aBoard->FindNet( track->GetNet() ); EQUIPOT* equipot = aBoard->FindNet( netcode );
wxASSERT( equipot ); wxASSERT( equipot );
netname = CONV_TO_UTF8( equipot->m_Netname ); netname = CONV_TO_UTF8( equipot->m_Netname );
} }
...@@ -1290,21 +1295,65 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1290,21 +1295,65 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
if( viaNdx != -1 ) if( viaNdx != -1 )
{ {
#if 1
for( ; viaNdx < (int)padstacks.size(); ++viaNdx ) for( ; viaNdx < (int)padstacks.size(); ++viaNdx )
{ {
vias->AppendVia( padstacks[viaNdx].padstack_id.c_str() ); vias->AppendVia( padstacks[viaNdx].padstack_id.c_str() );
} }
#else
// output only the default via. Then use class_descriptors to
// override the default. No, this causes free router not to
// output the unmentioned vias into the session file.
vias->AppendVia( padstacks[viaNdx].padstack_id.c_str() );
#endif
} }
} }
//-----<flip modules back>---------------------------------------------- //-----<output a default class with all nets and the via and track size>--
{
char text[80];
STRINGSET netIds; // sort the net names in here
CLASS* clazz = new CLASS( pcb->network );
pcb->network->classes.push_back( clazz );
// freerouter creates a class named 'default' anyway, and if we
// try and use that, we end up with two 'default' via rules so use
// something else as the name of our default class. Someday we may support
// additional classes. Until then the user can text edit the exported
// DSN file and use this class as a template, copying it and giving the
// copy a different class_id and splitting out some of the nets.
clazz->class_id = "kicad_default";
// Insert all the net_ids into the set. They are unique, but even if
// they were not the duplicated name is not our error, but the BOARD's.
// A duplicate would be removed here.
NETS& nets = pcb->network->nets;
for( NETS::iterator i=nets.begin(); i!=nets.end(); ++i )
netIds.insert( i->net_id );
// netIds is now sorted, put them into clazz->net_ids
for( STRINGSET::iterator i=netIds.begin(); i!=netIds.end(); ++i )
clazz->net_ids.push_back( *i );
// output the via and track dimensions, the whole reason for this scope.
int curTrackWidth = aBoard->m_BoardSettings->m_CurrentTrackWidth;
clazz->rules = new RULE( clazz, T_rule );
sprintf( text, "(width %.6g)", scale( curTrackWidth ) );
clazz->rules->rules.push_back( text );
RevertMODULEs( aBoard ); int viaNdx = pcb->library->via_start_index;
sprintf( text, "(use_via %s)", pcb->library->padstacks[viaNdx].padstack_id.c_str() );
clazz->circuit.push_back( text );
}
} }
void SPECCTRA_DB::flipMODULEs( BOARD* aBoard ) void SPECCTRA_DB::FlipMODULEs( BOARD* aBoard )
{ {
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() ) for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{ {
......
...@@ -167,7 +167,7 @@ static int scale( double distance, UNIT_RES* aResolution ) ...@@ -167,7 +167,7 @@ static int scale( double distance, UNIT_RES* aResolution )
static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution ) static wxPoint mapPt( const POINT& aPoint, UNIT_RES* aResolution )
{ {
wxPoint ret( scale( aPoint.x, aResolution ), wxPoint ret( scale( aPoint.x, aResolution ),
-scale( aPoint.y, aResolution )); // negate y -scale( aPoint.y, aResolution ) ); // negate y
return ret; return ret;
} }
...@@ -347,15 +347,18 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -347,15 +347,18 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
if( !session->route->library ) if( !session->route->library )
ThrowIOError( _("Session file is missing the \"library_out\" section") ); ThrowIOError( _("Session file is missing the \"library_out\" section") );
#if 1
// delete all the old tracks and vias // delete all the old tracks and vias
aBoard->m_Track->DeleteStructList(); aBoard->m_Track->DeleteStructList();
aBoard->m_Track = NULL; aBoard->m_Track = NULL;
aBoard->m_NbSegmTrack = 0; aBoard->m_NbSegmTrack = 0;
#endif
aBoard->DeleteMARKERs(); aBoard->DeleteMARKERs();
buildLayerMaps( aBoard ); buildLayerMaps( aBoard );
#if 1
// Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within // Walk the PLACEMENT object's COMPONENTs list, and for each PLACE within
// each COMPONENT, reposition and re-orient each component and put on // each COMPONENT, reposition and re-orient each component and put on
// correct side of the board. // correct side of the board.
...@@ -413,6 +416,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -413,6 +416,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
} }
} }
} }
#endif
routeResolution = session->route->GetUnits(); routeResolution = session->route->GetUnits();
...@@ -430,8 +434,10 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -430,8 +434,10 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
EQUIPOT* equipot = aBoard->FindNet( netName ); EQUIPOT* equipot = aBoard->FindNet( netName );
if( equipot ) if( equipot )
netCode = equipot->GetNet(); netCode = equipot->GetNet();
else // else netCode remains 0
// else netCode remains 0 {
// int breakhere = 1;
}
} }
WIRES& wires = net->wires; WIRES& wires = net->wires;
...@@ -442,21 +448,38 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -442,21 +448,38 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
if( shape != T_path ) if( shape != T_path )
{ {
/* shape == T_polygon is expected from freerouter if you have
a zone on a non "power" type layer, i.e. a T_signal layer
and the design does a round trip back in as session here.
We kept our own zones in the BOARD, so ignore this so called
'wire'.
wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() ); wxString netId = CONV_FROM_UTF8( wire->net_id.c_str() );
ThrowIOError( ThrowIOError(
_("Unsupported wire shape: \"%s\" for net: \"%s\""), _("Unsupported wire shape: \"%s\" for net: \"%s\""),
LEXER::GetTokenString(shape).GetData(), LEXER::GetTokenString(shape).GetData(),
netId.GetData() netId.GetData()
); );
*/
} }
else
{
PATH* path = (PATH*) wire->shape; PATH* path = (PATH*) wire->shape;
for( unsigned pt=0; pt<path->points.size()-1; ++pt ) for( unsigned pt=0; pt<path->points.size()-1; ++pt )
{ {
/* a debugging aid, may come in handy
if( path->points[pt].x == 547800
&& path->points[pt].y == -380250 )
{
int breakhere = 1;
}
*/
TRACK* track = makeTRACK( path, pt, netCode ); TRACK* track = makeTRACK( path, pt, netCode );
aBoard->Add( track ); aBoard->Add( track );
} }
} }
}
WIRE_VIAS& wire_vias = net->wire_vias; WIRE_VIAS& wire_vias = net->wire_vias;
LIBRARY& library = *session->route->library; LIBRARY& library = *session->route->library;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment