specctra work
This commit is contained in:
parent
74d373e6fa
commit
f3fcfce609
|
@ -14,6 +14,7 @@ email address.
|
||||||
* Changed specctra.h's POINT to use double for coordinates. Changed format
|
* Changed specctra.h's POINT to use double for coordinates. Changed format
|
||||||
string for Format()ing a double.
|
string for Format()ing a double.
|
||||||
* Changed specctra_export.cpp to actually output an incomplete file.
|
* Changed specctra_export.cpp to actually output an incomplete file.
|
||||||
|
* Added BOARD::GetCopperLayerCount() and BOARD::GetLayerName().
|
||||||
|
|
||||||
|
|
||||||
2008-Jan-21 UPDATE Dick Hollenbeck <dick@softplc.com>
|
2008-Jan-21 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||||
|
|
|
@ -837,6 +837,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class VIA
|
||||||
|
* corresponds to the <via_descriptor> in the specctra dsn spec.
|
||||||
|
*/
|
||||||
class VIA : public ELEM
|
class VIA : public ELEM
|
||||||
{
|
{
|
||||||
friend class SPECCTRA_DB;
|
friend class SPECCTRA_DB;
|
||||||
|
|
|
@ -68,14 +68,17 @@ void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
db.FromBOARD( m_Pcb );
|
db.FromBOARD( m_Pcb );
|
||||||
db.ExportPCB( fullFileName, true );
|
db.ExportPCB( fullFileName, true );
|
||||||
|
|
||||||
|
// if an exception is thrown by FromBOARD or Export(), then
|
||||||
|
// ~SPECCTRA_DB() will close the file.
|
||||||
}
|
}
|
||||||
catch ( IOError ioe )
|
catch ( IOError ioe )
|
||||||
{
|
{
|
||||||
DisplayError( this, ioe.errorText );
|
DisplayError( this, ioe.errorText );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if an exception is thrown by FromBOARD or Export(), then
|
// @todo display a message saying the export is complete.
|
||||||
// ~SPECCTRA_DB() will close the file.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,11 +103,17 @@ static inline void swap( POINT_PAIR& pair )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function mapPt
|
||||||
|
* converts a Kicad point into a DSN file point. Kicad's BOARD coordinates
|
||||||
|
* are in deci-mils (i.e. 1/10,000th of an inch) and we are exporting in units
|
||||||
|
* of mils, so we have to divide by 10.
|
||||||
|
*/
|
||||||
static POINT mapPt( const wxPoint& pt )
|
static POINT mapPt( const wxPoint& pt )
|
||||||
{
|
{
|
||||||
POINT ret;
|
POINT ret;
|
||||||
ret.x = pt.x;
|
ret.x = pt.x / 10.0;
|
||||||
ret.y = -pt.y; // make y negative, since it is increasing going down.
|
ret.y = -pt.y /10.0; // make y negative, since it is increasing going down.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +147,7 @@ static void swapEnds( POINT_PAIRS& aList )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function isRectangle
|
* Function isRectangle
|
||||||
* tests to see if the POINT_PAIRS list make up a vertically/horizontally
|
* tests to see if the POINT_PAIRS list makes up a vertically/horizontally
|
||||||
* oriented rectangle.
|
* oriented rectangle.
|
||||||
* @return bool - true if there are 4 point pairs making a rectangle.
|
* @return bool - true if there are 4 point pairs making a rectangle.
|
||||||
*/
|
*/
|
||||||
|
@ -177,103 +186,132 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
|
||||||
if( !pcb )
|
if( !pcb )
|
||||||
pcb = SPECCTRA_DB::MakePCB();
|
pcb = SPECCTRA_DB::MakePCB();
|
||||||
|
|
||||||
//-----<header stuff>-------------------------------------------------
|
//-----<unit_descriptor> & <resolution_descriptor>--------------------
|
||||||
pcb->unit->units = T_mil;
|
{
|
||||||
pcb->resolution->units = T_mil;
|
pcb->unit->units = T_mil;
|
||||||
pcb->resolution->value = 10;
|
pcb->resolution->units = T_mil;
|
||||||
|
pcb->resolution->value = 100;
|
||||||
//-----<board edges>--------------------------------------------------
|
|
||||||
|
|
||||||
// get all the DRAWSEGMENTS into 'items', then look for layer == EDGE_N,
|
|
||||||
// and those segments comprize the board's perimeter.
|
|
||||||
const KICAD_T scanDRAWSEGMENTS[] = { TYPEDRAWSEGMENT, EOT };
|
|
||||||
items.Collect( aBoard, scanDRAWSEGMENTS );
|
|
||||||
|
|
||||||
bool haveEdges = false;
|
|
||||||
ppairs.clear();
|
|
||||||
for( int i=0; i<items.GetCount(); ++i )
|
|
||||||
{
|
|
||||||
DRAWSEGMENT* item = (DRAWSEGMENT*) items[i];
|
|
||||||
|
|
||||||
wxASSERT( item->Type() == TYPEDRAWSEGMENT );
|
|
||||||
|
|
||||||
if( item->GetLayer() == EDGE_N )
|
|
||||||
{
|
|
||||||
pair.p1 = mapPt( item->m_Start );
|
|
||||||
pair.p2 = mapPt( item->m_End );
|
|
||||||
pair.item = item;
|
|
||||||
ppairs.push_back( pair );
|
|
||||||
haveEdges = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( haveEdges )
|
|
||||||
|
//-----<boundary_descriptor>------------------------------------------
|
||||||
{
|
{
|
||||||
swapEnds( ppairs );
|
// get all the DRAWSEGMENTS into 'items', then look for layer == EDGE_N,
|
||||||
|
// and those segments comprize the board's perimeter.
|
||||||
#if defined(DEBUG)
|
const KICAD_T scanDRAWSEGMENTS[] = { TYPEDRAWSEGMENT, EOT };
|
||||||
for( unsigned i=0; i<ppairs.size(); ++i )
|
items.Collect( aBoard, scanDRAWSEGMENTS );
|
||||||
|
|
||||||
|
bool haveEdges = false;
|
||||||
|
ppairs.clear();
|
||||||
|
for( int i=0; i<items.GetCount(); ++i )
|
||||||
{
|
{
|
||||||
POINT_PAIR* p = &ppairs[i];
|
DRAWSEGMENT* item = (DRAWSEGMENT*) items[i];
|
||||||
p->item->Show( 0, std::cout );
|
|
||||||
|
wxASSERT( item->Type() == TYPEDRAWSEGMENT );
|
||||||
|
|
||||||
|
if( item->GetLayer() == EDGE_N )
|
||||||
|
{
|
||||||
|
pair.p1 = mapPt( item->m_Start );
|
||||||
|
pair.p2 = mapPt( item->m_End );
|
||||||
|
pair.item = item;
|
||||||
|
ppairs.push_back( pair );
|
||||||
|
haveEdges = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
if( haveEdges )
|
||||||
BOUNDARY* boundary = new BOUNDARY(0);
|
|
||||||
|
|
||||||
if( isRectangle( ppairs ) )
|
|
||||||
{
|
{
|
||||||
RECTANGLE* rect = new RECTANGLE( boundary );
|
swapEnds( ppairs );
|
||||||
|
|
||||||
rect->layer_id = "pcb";
|
#if defined(DEBUG)
|
||||||
// opposite corners
|
for( unsigned i=0; i<ppairs.size(); ++i )
|
||||||
rect->point0 = ppairs[0].p1;
|
{
|
||||||
rect->point1 = ppairs[2].p1;
|
POINT_PAIR* p = &ppairs[i];
|
||||||
|
p->item->Show( 0, std::cout );
|
||||||
boundary->rectangle = rect;
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BOUNDARY* boundary = new BOUNDARY(0);
|
||||||
|
|
||||||
|
if( isRectangle( ppairs ) )
|
||||||
|
{
|
||||||
|
RECTANGLE* rect = new RECTANGLE( boundary );
|
||||||
|
rect->layer_id = "pcb";
|
||||||
|
|
||||||
|
// opposite corners
|
||||||
|
rect->point0 = ppairs[0].p1;
|
||||||
|
rect->point1 = ppairs[2].p1;
|
||||||
|
|
||||||
|
boundary->rectangle = rect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PATH* path = new PATH( boundary );
|
||||||
|
|
||||||
|
path->layer_id = "pcb";
|
||||||
|
for( unsigned i=0; i<ppairs.size(); ++i )
|
||||||
|
{
|
||||||
|
// unless its a closed polygon, this probably won't work,
|
||||||
|
// otherwise it will.
|
||||||
|
path->points.push_back( ppairs[i].p1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
boundary->paths.push_back( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
pcb->structure->SetBOUNDARY( boundary );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PATH* path = new PATH( boundary );
|
aBoard->ComputeBoundaryBox();
|
||||||
|
|
||||||
path->layer_id = "pcb";
|
BOUNDARY* boundary = new BOUNDARY(0);
|
||||||
for( unsigned i=0; i<ppairs.size(); ++i )
|
RECTANGLE* rect = new RECTANGLE( boundary );
|
||||||
{
|
|
||||||
// unless its a closed polygon, this probably won't work,
|
rect->layer_id = "pcb";
|
||||||
// otherwise it will.
|
|
||||||
path->points.push_back( ppairs[i].p1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
boundary->paths.push_back( path );
|
// opposite corners
|
||||||
|
wxPoint bottomRight;
|
||||||
|
bottomRight.x = aBoard->m_BoundaryBox.GetRight();
|
||||||
|
bottomRight.y = aBoard->m_BoundaryBox.GetBottom();
|
||||||
|
|
||||||
|
rect->point0 = mapPt( aBoard->m_BoundaryBox.GetOrigin() );
|
||||||
|
rect->point1 = mapPt( bottomRight );
|
||||||
|
|
||||||
|
boundary->rectangle = rect;
|
||||||
|
|
||||||
|
pcb->structure->SetBOUNDARY( boundary );
|
||||||
}
|
}
|
||||||
|
|
||||||
pcb->structure->SetBOUNDARY( boundary );
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
|
||||||
|
//-----<layer_descriptor>-----------------------------------------------
|
||||||
{
|
{
|
||||||
aBoard->ComputeBoundaryBox();
|
// specctra wants top physical layer first, then going down to the
|
||||||
|
// bottom most physical layer in physical sequence.
|
||||||
|
// @question : why does Kicad not display layers in that order?
|
||||||
|
int layerCount = aBoard->GetCopperLayerCount();
|
||||||
|
|
||||||
BOUNDARY* boundary = new BOUNDARY(0);
|
for( int ndx=layerCount-1; ndx >= 0; --ndx )
|
||||||
RECTANGLE* rect = new RECTANGLE( boundary );
|
{
|
||||||
|
wxString layerName = aBoard->GetLayerName( ndx>0 && ndx==layerCount-1 ? LAYER_CMP_N : ndx );
|
||||||
rect->layer_id = "pcb";
|
LAYER* layer = new LAYER( pcb->structure );
|
||||||
|
|
||||||
// opposite corners
|
layer->name = CONV_TO_UTF8( layerName );
|
||||||
wxPoint bottomRight;
|
|
||||||
bottomRight.x = aBoard->m_BoundaryBox.GetRight();
|
// layer->type =
|
||||||
bottomRight.y = aBoard->m_BoundaryBox.GetBottom();
|
pcb->structure->layers.push_back( layer );
|
||||||
|
}
|
||||||
rect->point0 = mapPt( aBoard->m_BoundaryBox.GetOrigin() );
|
|
||||||
rect->point1 = mapPt( bottomRight );
|
|
||||||
|
|
||||||
boundary->rectangle = rect;
|
|
||||||
|
|
||||||
pcb->structure->SetBOUNDARY( boundary );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----<layers>-------------------------------------------------------
|
//-----<build the padstack list here, no output>------------------------
|
||||||
|
|
||||||
|
|
||||||
|
//-----<via_descriptor>-------------------------------------------------
|
||||||
|
{
|
||||||
|
// Output the vias in the padstack list here, by name
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue