Commit f3fcfce6 authored by dickelbeck's avatar dickelbeck

specctra work

parent 74d373e6
...@@ -14,6 +14,7 @@ email address. ...@@ -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: ...@@ -837,6 +837,10 @@ public:
}; };
/**
* Class VIA
* corresponds to the &lt;via_descriptor&gt; 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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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>--------------------------------------------------
//-----<boundary_descriptor>------------------------------------------
// 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]; // get all the DRAWSEGMENTS into 'items', then look for layer == EDGE_N,
// and those segments comprize the board's perimeter.
wxASSERT( item->Type() == TYPEDRAWSEGMENT ); const KICAD_T scanDRAWSEGMENTS[] = { TYPEDRAWSEGMENT, EOT };
items.Collect( aBoard, scanDRAWSEGMENTS );
if( item->GetLayer() == EDGE_N )
bool haveEdges = false;
ppairs.clear();
for( int i=0; i<items.GetCount(); ++i )
{ {
pair.p1 = mapPt( item->m_Start ); DRAWSEGMENT* item = (DRAWSEGMENT*) items[i];
pair.p2 = mapPt( item->m_End );
pair.item = item; wxASSERT( item->Type() == TYPEDRAWSEGMENT );
ppairs.push_back( pair );
haveEdges = true; 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 )
if( haveEdges )
{
swapEnds( ppairs );
#if defined(DEBUG)
for( unsigned i=0; i<ppairs.size(); ++i )
{ {
POINT_PAIR* p = &ppairs[i]; swapEnds( ppairs );
p->item->Show( 0, std::cout );
#if defined(DEBUG)
for( unsigned i=0; i<ppairs.size(); ++i )
{
POINT_PAIR* p = &ppairs[i];
p->item->Show( 0, std::cout );
}
#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 );
} }
#endif else
BOUNDARY* boundary = new BOUNDARY(0);
if( isRectangle( ppairs ) )
{ {
RECTANGLE* rect = new RECTANGLE( boundary ); aBoard->ComputeBoundaryBox();
BOUNDARY* boundary = new BOUNDARY(0);
RECTANGLE* rect = new RECTANGLE( boundary );
rect->layer_id = "pcb"; rect->layer_id = "pcb";
// opposite corners // opposite corners
rect->point0 = ppairs[0].p1; wxPoint bottomRight;
rect->point1 = ppairs[2].p1; bottomRight.x = aBoard->m_BoundaryBox.GetRight();
bottomRight.y = aBoard->m_BoundaryBox.GetBottom();
boundary->rectangle = rect; rect->point0 = mapPt( aBoard->m_BoundaryBox.GetOrigin() );
} rect->point1 = mapPt( bottomRight );
else
{
PATH* path = new PATH( boundary );
path->layer_id = "pcb"; boundary->rectangle = rect;
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 );
} }
pcb->structure->SetBOUNDARY( boundary );
} }
else
{
aBoard->ComputeBoundaryBox();
BOUNDARY* boundary = new BOUNDARY(0);
RECTANGLE* rect = new RECTANGLE( boundary );
rect->layer_id = "pcb";
//-----<layer_descriptor>-----------------------------------------------
// opposite corners {
wxPoint bottomRight; // specctra wants top physical layer first, then going down to the
bottomRight.x = aBoard->m_BoundaryBox.GetRight(); // bottom most physical layer in physical sequence.
bottomRight.y = aBoard->m_BoundaryBox.GetBottom(); // @question : why does Kicad not display layers in that order?
int layerCount = aBoard->GetCopperLayerCount();
rect->point0 = mapPt( aBoard->m_BoundaryBox.GetOrigin() );
rect->point1 = mapPt( bottomRight );
boundary->rectangle = rect;
pcb->structure->SetBOUNDARY( boundary ); for( int ndx=layerCount-1; ndx >= 0; --ndx )
{
wxString layerName = aBoard->GetLayerName( ndx>0 && ndx==layerCount-1 ? LAYER_CMP_N : ndx );
LAYER* layer = new LAYER( pcb->structure );
layer->name = CONV_TO_UTF8( layerName );
// layer->type =
pcb->structure->layers.push_back( layer );
}
} }
//-----<layers>------------------------------------------------------- //-----<build the padstack list here, no output>------------------------
//-----<via_descriptor>-------------------------------------------------
{
// Output the vias in the padstack list here, by name
}
} }
......
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