Commit 300d50b1 authored by dickelbeck's avatar dickelbeck

more specctra dsn work

parent 0f3b3ee2
...@@ -5,6 +5,16 @@ Please add newer entries at the top, list the date and your name with ...@@ -5,6 +5,16 @@ Please add newer entries at the top, list the date and your name with
email address. email address.
2008-Jan-22 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew:
* Actually able now to export a *.dsn file, but the contents of the file
is incomplete, not a complete input BOARD.
* Added DRAWSEGMENT::Show() for debugging.
* Changed specctra.h's POINT to use double for coordinates. Changed format
string for Format()ing a double.
* Changed specctra_export.cpp to actually output an incomplete file.
2008-Jan-21 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Jan-21 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
......
...@@ -36,6 +36,14 @@ ...@@ -36,6 +36,14 @@
#include "pcbnew.h" #include "pcbnew.h"
/**
* Class LEXER
* implements a lexical analyzer for the SPECCTRA DSN file format. It
* reads lexical tokens from the current LINE_READER through the NextTok()
* function. The NextTok() function returns one of the DSN_T values.
*/
namespace DSN { namespace DSN {
......
...@@ -535,6 +535,7 @@ public: ...@@ -535,6 +535,7 @@ public:
/** /**
* Class LEXER * Class LEXER
* implements a lexical analyzer for the SPECCTRA DSN file format. It
* reads lexical tokens from the current LINE_READER through the NextTok() * reads lexical tokens from the current LINE_READER through the NextTok()
* function. The NextTok() function returns one of the DSN_T values. * function. The NextTok() function returns one of the DSN_T values.
*/ */
...@@ -635,7 +636,7 @@ public: ...@@ -635,7 +636,7 @@ public:
/** /**
* Function ThrowIOError * Function ThrowIOError
* encapsulates the formatting of an error message which contains the exact * encapsulates the formatting of an error message which contains the exact
* location within the input file of a lexical error. * location within the input file of something the caller is rejecting.
*/ */
void ThrowIOError( wxString aText, int charOffset ) throw (IOError); void ThrowIOError( wxString aText, int charOffset ) throw (IOError);
......
...@@ -55,11 +55,10 @@ ...@@ -55,11 +55,10 @@
#include <wx/ffile.h> #include <wx/ffile.h>
#define STANDALONE 0 // set to 1 for "stand alone, i.e. unit testing" //#define STANDALONE // define "stand alone, i.e. unit testing"
// set to 0 for component of pcbnew
#if STANDALONE #if defined(STANDALONE)
#define EDA_BASE // build_version.h behavior #define EDA_BASE // build_version.h behavior
#undef COMMON_GLOBL #undef COMMON_GLOBL
#define COMMON_GLOBL // build_version.h behavior #define COMMON_GLOBL // build_version.h behavior
...@@ -3326,7 +3325,7 @@ const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee ) ...@@ -3326,7 +3325,7 @@ const char* SPECCTRA_DB::GetQuoteChar( const char* wrapee )
} }
void SPECCTRA_DB::ExportPCB( wxString filename ) throw( IOError ) void SPECCTRA_DB::ExportPCB( wxString filename, bool aNameChange ) throw( IOError )
{ {
fp = wxFopen( filename, wxT("w") ); fp = wxFopen( filename, wxT("w") );
...@@ -3334,10 +3333,18 @@ void SPECCTRA_DB::ExportPCB( wxString filename ) throw( IOError ) ...@@ -3334,10 +3333,18 @@ void SPECCTRA_DB::ExportPCB( wxString filename ) throw( IOError )
{ {
ThrowIOError( _("Unable to open file \"%s\""), filename.GetData() ); ThrowIOError( _("Unable to open file \"%s\""), filename.GetData() );
} }
if( pcb ) if( pcb )
{
if( aNameChange )
pcb->pcbname = CONV_TO_UTF8(filename);
pcb->Format( this, 0 ); pcb->Format( this, 0 );
}
// if an exception is thrown by Format, then ~SPECCTRA_DB() will close
// the file.
fclose( fp ); fclose( fp );
fp = 0; fp = 0;
} }
...@@ -3369,6 +3376,7 @@ PCB* SPECCTRA_DB::MakePCB() ...@@ -3369,6 +3376,7 @@ PCB* SPECCTRA_DB::MakePCB()
pcb->unit = new UNIT_RES( pcb, T_unit ); pcb->unit = new UNIT_RES( pcb, T_unit );
pcb->structure = new STRUCTURE( pcb ); pcb->structure = new STRUCTURE( pcb );
pcb->structure->boundary = new BOUNDARY( pcb->structure );
pcb->placement = new PLACEMENT( pcb ); pcb->placement = new PLACEMENT( pcb );
...@@ -3506,13 +3514,13 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) ...@@ -3506,13 +3514,13 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
} }
if( hasVertex ) if( hasVertex )
out->Print( 0, " %f %f", vertex.x, vertex.y ); out->Print( 0, " %.6g %.6g", vertex.x, vertex.y );
if( side != T_NONE ) if( side != T_NONE )
out->Print( 0, " %s", LEXER::GetTokenText( side ) ); out->Print( 0, " %s", LEXER::GetTokenText( side ) );
if( isRotated ) if( isRotated )
out->Print( 0, " %f", rotation ); out->Print( 0, " %.6g", rotation );
if( mirror != T_NONE ) if( mirror != T_NONE )
out->Print( 0, " (mirror %s)", LEXER::GetTokenText( mirror ) ); out->Print( 0, " (mirror %s)", LEXER::GetTokenText( mirror ) );
...@@ -3572,7 +3580,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) ...@@ -3572,7 +3580,7 @@ void PLACE::Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
// unit test this source file // unit test this source file
#if STANDALONE #if defined(STANDALONE)
using namespace DSN; using namespace DSN;
......
...@@ -106,11 +106,21 @@ public: ...@@ -106,11 +106,21 @@ public:
struct POINT struct POINT
{ {
float x; double x;
float y; double y;
POINT() { x=0.0; y=0.0; } POINT() { x=0.0; y=0.0; }
bool operator==( const POINT& other ) const
{
return x==other.x && y==other.y;
}
bool operator!=( const POINT& other ) const
{
return !( *this == other );
}
/** /**
* Function Format * Function Format
* writes this object as ASCII out to an OUTPUTFORMATTER according to the * writes this object as ASCII out to an OUTPUTFORMATTER according to the
...@@ -121,7 +131,7 @@ struct POINT ...@@ -121,7 +131,7 @@ struct POINT
*/ */
void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) const throw( IOError )
{ {
out->Print( nestLevel, " %f %f", x, y ); out->Print( nestLevel, " %.6g %.6g", x, y );
} }
}; };
...@@ -161,6 +171,8 @@ typedef std::vector<PROPERTY> PROPERTIES; ...@@ -161,6 +171,8 @@ typedef std::vector<PROPERTY> PROPERTIES;
*/ */
class ELEM class ELEM
{ {
friend class SPECCTRA_DB;
protected: protected:
DSN_T type; DSN_T type;
ELEM* parent; ELEM* parent;
...@@ -213,6 +225,11 @@ public: ...@@ -213,6 +225,11 @@ public:
{ {
// overridden in ELEM_HOLDER // overridden in ELEM_HOLDER
} }
void SetParent( ELEM* aParent )
{
parent = aParent;
}
}; };
...@@ -223,7 +240,8 @@ public: ...@@ -223,7 +240,8 @@ public:
*/ */
class ELEM_HOLDER : public ELEM class ELEM_HOLDER : public ELEM
{ {
// see http://www.boost.org/libs/ptr_container/doc/ptr_sequence_adapter.html friend class SPECCTRA_DB;
typedef boost::ptr_vector<ELEM> ELEM_ARRAY; typedef boost::ptr_vector<ELEM> ELEM_ARRAY;
ELEM_ARRAY kids; ///< ELEM pointers ELEM_ARRAY kids; ///< ELEM pointers
...@@ -393,7 +411,7 @@ public: ...@@ -393,7 +411,7 @@ public:
{ {
const char* quote = out->GetQuoteChar( layer_id.c_str() ); const char* quote = out->GetQuoteChar( layer_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s %f %f %f %f)\n", out->Print( nestLevel, "(%s %s%s%s %.6g %.6g %.6g %.6g)\n",
LEXER::GetTokenText( Type() ), LEXER::GetTokenText( Type() ),
quote, layer_id.c_str(), quote, quote, layer_id.c_str(), quote,
point0.x, point0.y, point0.x, point0.y,
...@@ -546,7 +564,7 @@ class PATH : public ELEM ...@@ -546,7 +564,7 @@ class PATH : public ELEM
public: public:
PATH( ELEM* aParent, DSN_T aType ) : PATH( ELEM* aParent, DSN_T aType = T_path ) :
ELEM( aType, aParent ) ELEM( aType, aParent )
{ {
aperture_width = 0.0; aperture_width = 0.0;
...@@ -561,13 +579,13 @@ public: ...@@ -561,13 +579,13 @@ public:
{ {
const char* quote = out->GetQuoteChar( layer_id.c_str() ); const char* quote = out->GetQuoteChar( layer_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s %f\n", LEXER::GetTokenText( Type() ), out->Print( nestLevel, "(%s %s%s%s %.6g\n", LEXER::GetTokenText( Type() ),
quote, layer_id.c_str(), quote, quote, layer_id.c_str(), quote,
aperture_width ); aperture_width );
for( unsigned i=0; i<points.size(); ++i ) for( unsigned i=0; i<points.size(); ++i )
{ {
out->Print( nestLevel+1, "%f %f\n", points[i].x, points[i].y ); out->Print( nestLevel+1, "%.6g %.6g\n", points[i].x, points[i].y );
} }
if( aperture_type == T_square ) if( aperture_type == T_square )
...@@ -587,6 +605,7 @@ class BOUNDARY : public ELEM ...@@ -587,6 +605,7 @@ class BOUNDARY : public ELEM
PATHS paths; PATHS paths;
RECTANGLE* rectangle; RECTANGLE* rectangle;
public: public:
BOUNDARY( ELEM* aParent, DSN_T aType = T_boundary ) : BOUNDARY( ELEM* aParent, DSN_T aType = T_boundary ) :
...@@ -636,7 +655,7 @@ public: ...@@ -636,7 +655,7 @@ public:
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
const char* quote = out->GetQuoteChar( layer_id.c_str() ); const char* quote = out->GetQuoteChar( layer_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s %f %f %f)\n", LEXER::GetTokenText( Type() ) , out->Print( nestLevel, "(%s %s%s%s %.6g %.6g %.6g)\n", LEXER::GetTokenText( Type() ) ,
quote, layer_id.c_str(), quote, quote, layer_id.c_str(), quote,
diameter, vertex.x, vertex.y ); diameter, vertex.x, vertex.y );
} }
...@@ -661,12 +680,12 @@ public: ...@@ -661,12 +680,12 @@ public:
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
const char* quote = out->GetQuoteChar( layer_id.c_str() ); const char* quote = out->GetQuoteChar( layer_id.c_str() );
out->Print( nestLevel, "(%s %s%s%s %f\n", LEXER::GetTokenText( Type() ) , out->Print( nestLevel, "(%s %s%s%s %.6g\n", LEXER::GetTokenText( Type() ) ,
quote, layer_id.c_str(), quote, quote, layer_id.c_str(), quote,
aperture_width); aperture_width);
for( int i=0; i<3; ++i ) for( int i=0; i<3; ++i )
out->Print( nestLevel+1, "%f %f\n", vertex[i].x, vertex[i].y ); out->Print( nestLevel+1, "%.6g %.6g\n", vertex[i].x, vertex[i].y );
out->Print( nestLevel, ")\n" ); out->Print( nestLevel, ")\n" );
} }
...@@ -1072,7 +1091,7 @@ public: ...@@ -1072,7 +1091,7 @@ public:
const char* quote0 = out->GetQuoteChar( layer_id0.c_str() ); const char* quote0 = out->GetQuoteChar( layer_id0.c_str() );
const char* quote1 = out->GetQuoteChar( layer_id1.c_str() ); const char* quote1 = out->GetQuoteChar( layer_id1.c_str() );
out->Print( nestLevel, "(%s %s%s%s %s%s%s %f)\n", LEXER::GetTokenText( Type() ), out->Print( nestLevel, "(%s %s%s%s %s%s%s %.6g)\n", LEXER::GetTokenText( Type() ),
quote0, layer_id0.c_str(), quote0, quote0, layer_id0.c_str(), quote0,
quote1, layer_id1.c_str(), quote1, quote1, layer_id1.c_str(), quote1,
layer_weight ); layer_weight );
...@@ -1113,7 +1132,7 @@ class PLANE : public KEEPOUT ...@@ -1113,7 +1132,7 @@ class PLANE : public KEEPOUT
public: public:
PLANE( ELEM* aParent ) : PLANE( ELEM* aParent ) :
KEEPOUT( aParent, T_plane ) KEEPOUT( aParent, T_plane )
{} {}
}; };
...@@ -1232,11 +1251,11 @@ class GRID : public ELEM ...@@ -1232,11 +1251,11 @@ class GRID : public ELEM
DSN_T grid_type; ///< T_via | T_wire | T_via_keepout | T_place | T_snap DSN_T grid_type; ///< T_via | T_wire | T_via_keepout | T_place | T_snap
float dimension; double dimension;
DSN_T direction; ///< T_x | T_y | -1 for both DSN_T direction; ///< T_x | T_y | -1 for both
float offset; double offset;
DSN_T image_type; DSN_T image_type;
...@@ -1254,7 +1273,7 @@ public: ...@@ -1254,7 +1273,7 @@ public:
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
out->Print( nestLevel, "(%s %s %f", out->Print( nestLevel, "(%s %s %.6g",
LEXER::GetTokenText( Type() ), LEXER::GetTokenText( Type() ),
LEXER::GetTokenText( grid_type ), dimension ); LEXER::GetTokenText( grid_type ), dimension );
...@@ -1270,7 +1289,7 @@ public: ...@@ -1270,7 +1289,7 @@ public:
} }
if( offset != 0.0 ) if( offset != 0.0 )
out->Print( 0, " (offset %f)", offset ); out->Print( 0, " (offset %.6g)", offset );
out->Print( 0, ")\n"); out->Print( 0, ")\n");
} }
...@@ -1335,6 +1354,24 @@ public: ...@@ -1335,6 +1354,24 @@ public:
delete place_rules; delete place_rules;
} }
void SetBOUNDARY( BOUNDARY *aBoundary )
{
delete boundary;
boundary = aBoundary;
if( boundary )
{
boundary->SetParent( this );
}
}
void SetPlaceBOUNDARY( BOUNDARY *aBoundary )
{
delete place_boundary;
place_boundary = aBoundary;
if( place_boundary )
place_boundary->SetParent( this );
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
if( unit ) if( unit )
...@@ -1401,7 +1438,7 @@ class PLACE : public ELEM ...@@ -1401,7 +1438,7 @@ class PLACE : public ELEM
DSN_T side; DSN_T side;
bool isRotated; bool isRotated;
float rotation; double rotation;
bool hasVertex; bool hasVertex;
POINT vertex; POINT vertex;
...@@ -1457,7 +1494,7 @@ public: ...@@ -1457,7 +1494,7 @@ public:
void SetRotation( double aRotation ) void SetRotation( double aRotation )
{ {
rotation = (float) aRotation; rotation = aRotation;
isRotated = (aRotation != 0.0); isRotated = (aRotation != 0.0);
} }
...@@ -1607,7 +1644,7 @@ class PIN : public ELEM ...@@ -1607,7 +1644,7 @@ class PIN : public ELEM
friend class SPECCTRA_DB; friend class SPECCTRA_DB;
std::string padstack_id; std::string padstack_id;
float rotation; double rotation;
bool isRotated; bool isRotated;
std::string pin_id; std::string pin_id;
POINT vertex; POINT vertex;
...@@ -1622,7 +1659,7 @@ public: ...@@ -1622,7 +1659,7 @@ public:
void SetRotation( double aRotation ) void SetRotation( double aRotation )
{ {
rotation = (float) aRotation; rotation = aRotation;
isRotated = (aRotation != 0.0); isRotated = (aRotation != 0.0);
} }
...@@ -1630,7 +1667,7 @@ public: ...@@ -1630,7 +1667,7 @@ public:
{ {
const char* quote = out->GetQuoteChar( padstack_id.c_str() ); const char* quote = out->GetQuoteChar( padstack_id.c_str() );
if( isRotated ) if( isRotated )
out->Print( nestLevel, "(pin %s%s%s (rotate %1.2f)", out->Print( nestLevel, "(pin %s%s%s (rotate %.6g)",
quote, padstack_id.c_str(), quote, quote, padstack_id.c_str(), quote,
rotation rotation
); );
...@@ -1638,7 +1675,7 @@ public: ...@@ -1638,7 +1675,7 @@ public:
out->Print( nestLevel, "(pin %s%s%s", quote, padstack_id.c_str(), quote ); out->Print( nestLevel, "(pin %s%s%s", quote, padstack_id.c_str(), quote );
quote = out->GetQuoteChar( pin_id.c_str() ); quote = out->GetQuoteChar( pin_id.c_str() );
out->Print( 0, " %s%s%s %f %f)\n", quote, pin_id.c_str(), quote, out->Print( 0, " %s%s%s %.6g %.6g)\n", quote, pin_id.c_str(), quote,
vertex.x, vertex.y ); vertex.x, vertex.y );
} }
}; };
...@@ -2356,11 +2393,11 @@ public: ...@@ -2356,11 +2393,11 @@ public:
{ {
out->Print( 0, "\n" ); out->Print( 0, "\n" );
perLine = 0; perLine = 0;
perLine += out->Print( nestLevel+1, "%f %f", i->x, i->y ); perLine += out->Print( nestLevel+1, "%.6g %.6g", i->x, i->y );
} }
else else
{ {
perLine += out->Print( 0, " %f %f", i->x, i->y ); perLine += out->Print( 0, " %.6g %.6g", i->x, i->y );
} }
} }
out->Print( 0, "\n" ); out->Print( 0, "\n" );
...@@ -2370,6 +2407,9 @@ public: ...@@ -2370,6 +2407,9 @@ public:
const char* quote = out->GetQuoteChar( net_id.c_str() ); const char* quote = out->GetQuoteChar( net_id.c_str() );
out->Print( nestLevel+1, "(net %s%s%s)\n", quote, net_id.c_str(), quote ); out->Print( nestLevel+1, "(net %s%s%s)\n", quote, net_id.c_str(), quote );
} }
if( via_number != -1 )
out->Print( nestLevel+1, "(via_number %d)\n", via_number );
if( type != T_NONE ) if( type != T_NONE )
out->Print( nestLevel+1, "(type %s)\n", LEXER::GetTokenText( type ) ); out->Print( nestLevel+1, "(type %s)\n", LEXER::GetTokenText( type ) );
...@@ -2599,10 +2639,6 @@ public: ...@@ -2599,10 +2639,6 @@ public:
{ {
time_stamp = time(NULL); time_stamp = time(NULL);
} }
~HISTORY()
{
;
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
...@@ -3070,6 +3106,14 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3070,6 +3106,14 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
void doWAS_IS( WAS_IS* growth ) throw( IOError ); void doWAS_IS( WAS_IS* growth ) throw( IOError );
void doNET_OUT( NET_OUT* growth ) throw( IOError ); void doNET_OUT( NET_OUT* growth ) throw( IOError );
void doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IOError ); void doSUPPLY_PIN( SUPPLY_PIN* growth ) throw( IOError );
/**
* Function exportEdges
* exports the EDGES_N layer of the board.
*/
void exportEdges( BOARD* aBoard ) throw( IOError );
public: public:
...@@ -3160,9 +3204,11 @@ public: ...@@ -3160,9 +3204,11 @@ public:
* writes the internal PCB instance out as a SPECTRA DSN format file. * writes the internal PCB instance out as a SPECTRA DSN format file.
* *
* @param aFilename The file to save to. * @param aFilename The file to save to.
* @param aNameChange If true, causes the pcb's name to change to "aFilename"
* and also to to be changed in the output file.
* @throw IOError, if an i/o error occurs saving the file. * @throw IOError, if an i/o error occurs saving the file.
*/ */
void ExportPCB( wxString aFilename ) throw( IOError ); void ExportPCB( wxString aFilename, bool aNameChange=false ) throw( IOError );
/** /**
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "specctra.h" #include "specctra.h"
#include "collectors.h"
using namespace DSN; using namespace DSN;
...@@ -40,32 +41,242 @@ using namespace DSN; ...@@ -40,32 +41,242 @@ using namespace DSN;
// see wxPcbStruct.h // see wxPcbStruct.h
void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event ) void WinEDA_PcbFrame::ExportToSPECCTRA( wxCommandEvent& event )
{ {
SPECCTRA_DB db; wxString fullFileName = GetScreen()->m_FileName;
wxString std_ext = wxT( ".dsn" );
wxString mask = wxT( "*" ) + std_ext;
ChangeFileNameExt( fullFileName, std_ext );
fullFileName = EDA_FileSelector( _( "Specctra DSN file:" ),
wxEmptyString, /* Chemin par defaut */
fullFileName, /* nom fichier par defaut */
std_ext, /* extension par defaut */
mask, /* Masque d'affichage */
this,
wxFD_SAVE,
FALSE
);
if( fullFileName == wxEmptyString )
return;
SPECCTRA_DB db;
db.SetPCB( SPECCTRA_DB::MakePCB() ); db.SetPCB( SPECCTRA_DB::MakePCB() );
try try
{ {
db.FromBOARD( m_Pcb ); db.FromBOARD( m_Pcb );
// db.Export( filename ); db.ExportPCB( fullFileName, true );
} }
catch ( IOError ioe ) catch ( IOError ioe )
{ {
DisplayError( this, ioe.errorText );
} }
// if an exception is thrown by FromBOARD or Export(), then
// ~SPECCTRA_DB() will close the file.
} }
namespace DSN { namespace DSN {
struct POINT_PAIR
{
POINT p1; ///< start
POINT p2; ///< end
BOARD_ITEM* item; ///< the item which has these points, TRACK or DRAWSEGMENT
};
typedef std::vector<POINT_PAIR> POINT_PAIRS;
void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
static inline void swap( POINT_PAIR& pair )
{
POINT temp = pair.p1;
pair.p1 = pair.p2;
pair.p2 = temp;
}
static POINT mapPt( const wxPoint& pt )
{ {
POINT ret;
ret.x = pt.x;
ret.y = -pt.y; // make y negative, since it is increasing going down.
return ret;
}
/**
* Function swapEnds
* will swap ends of any POINT_PAIR in the POINT_PAIRS list in order to
* make the consecutive POINT_PAIRs be "connected" at their ends.
*/
static void swapEnds( POINT_PAIRS& aList )
{
POINT temp;
if( aList.size() <= 1 )
return;
for( unsigned i=0; i<aList.size(); ++i )
{
if( aList[i].p1 == aList[i+1].p1 )
swap( aList[i] );
else if( aList[i].p1 == aList[i+1].p2 )
{
swap( aList[i] );
swap( aList[i+1] );
++i; // skip next one, we swapped i+1 here
}
}
}
/**
* Function isRectangle
* tests to see if the POINT_PAIRS list make up a vertically/horizontally
* oriented rectangle.
* @return bool - true if there are 4 point pairs making a rectangle.
*/
static bool isRectangle( POINT_PAIRS& aList )
{
if( aList.size() == 4 )
{
for( unsigned i=0; i<aList.size(); ++i )
{
if( i < aList.size()-1 )
if( aList[i].p2 != aList[i+1].p1 )
return false;
if( aList[i].p1.x != aList[i].p2.x
&& aList[i].p1.y != aList[i].p2.y )
return false;
}
return ( aList[0].p1 == aList[3].p2 );
}
return false;
}
void SPECCTRA_DB::exportEdges( BOARD* aBoard ) throw( IOError )
{
} }
void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
{
TYPE_COLLECTOR items;
POINT_PAIRS ppairs;
POINT_PAIR pair;
if( !pcb )
pcb = SPECCTRA_DB::MakePCB();
//-----<header stuff>-------------------------------------------------
pcb->unit->units = T_mil;
pcb->resolution->units = T_mil;
pcb->resolution->value = 10;
//-----<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 )
{
swapEnds( ppairs );
#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 );
}
else
{
aBoard->ComputeBoundaryBox();
BOUNDARY* boundary = new BOUNDARY(0);
RECTANGLE* rect = new RECTANGLE( boundary );
rect->layer_id = "pcb";
// 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 );
}
//-----<layers>-------------------------------------------------------
}
} // namespace DSN } // namespace DSN
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