Commit 8e3b896b authored by unknown's avatar unknown Committed by jean-pierre charras

idf tools: code cleanup and debugging

parent a90680aa
......@@ -187,4 +187,4 @@ int main( int argc, char **argv )
fprintf( fp, ".END_ELECTRICAL\n" );
return 0;
}
}
\ No newline at end of file
......@@ -31,6 +31,7 @@
* would be more likely if we used a 1:1 scale.
*/
#include <iostream>
#include <iomanip>
#include <fstream>
......@@ -45,6 +46,7 @@
#include <vector>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <libgen.h>
#include <unistd.h>
......@@ -111,6 +113,7 @@ VRML_COLOR colors[NCOLORS] = { \
bool WriteHeader( IDF3_BOARD& board, std::ofstream& file );
bool MakeBoard( IDF3_BOARD& board, std::ofstream& file );
bool MakeComponents( IDF3_BOARD& board, std::ofstream& file, bool compact );
bool MakeOtherOutlines( IDF3_BOARD& board, std::ofstream& file );
bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items, bool bottom,
double scale, double dX = 0.0, double dY = 0.0, double angle = 0.0 );
bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg );
......@@ -124,12 +127,19 @@ VRML_IDS* GetColor( std::map<std::string, VRML_IDS*>& cmap,
void PrintUsage( void )
{
cout << "-\nUsage: idf2vrml -f input_file.emn -s scale_factor -k\n";
cout << "flags: -k: produce KiCad-firendly VRML output; default is compact VRML\n-\n";
cout << "-\nUsage: idf2vrml -f input_file.emn -s scale_factor {-k} {-d} {-z} {-m}\n";
cout << "flags:\n";
cout << " -k: produce KiCad-friendly VRML output; default is compact VRML\n";
cout << " -d: suppress substitution of default outlines\n";
cout << " -z: suppress rendering of zero-height outlines\n";
cout << " -m: print object mapping to stdout for debugging purposes\n";
cout << "example to produce a model for use by KiCad: idf2vrml -f input.emn -s 0.3937008 -k\n\n";
return;
}
bool nozeroheights;
bool showObjectMapping;
int main( int argc, char **argv )
{
// IDF implicitly requires the C locale
......@@ -148,9 +158,13 @@ int main( int argc, char **argv )
std::string inputFilename;
double scaleFactor = 1.0;
bool compact = true;
bool nooutlinesubs = false;
int ichar;
while( ( ichar = getopt( argc, argv, ":f:s:k" ) ) != -1 )
nozeroheights = false;
showObjectMapping = false;
while( ( ichar = getopt( argc, argv, ":f:s:kdzm" ) ) != -1 )
{
switch( ichar )
{
......@@ -184,6 +198,18 @@ int main( int argc, char **argv )
compact = false;
break;
case 'd':
nooutlinesubs = true;
break;
case 'z':
nozeroheights = true;
break;
case 'm':
showObjectMapping = true;
break;
case ':':
cerr << "* Missing parameter to option '-" << ((char) optopt) << "'\n";
PrintUsage();
......@@ -215,10 +241,11 @@ int main( int argc, char **argv )
cout << "** Reading file: " << inputFilename << "\n";
if( !pcb.ReadFile( FROM_UTF8( inputFilename.c_str() ) ) )
if( !pcb.ReadFile( FROM_UTF8( inputFilename.c_str() ), nooutlinesubs ) )
{
CLEANUP;
cerr << "* Could not read file: " << inputFilename << "\n";
cerr << "** Failed to read IDF data:\n";
cerr << pcb.GetError() << "\n\n";
return -1;
}
......@@ -261,6 +288,9 @@ int main( int argc, char **argv )
// STEP 2: Render the components
MakeComponents( pcb, ofile, compact );
// STEP 3: Render the OTHER outlines
MakeOtherOutlines( pcb, ofile );
ofile << "]\n}\n";
ofile.close();
......@@ -328,7 +358,7 @@ bool MakeBoard( IDF3_BOARD& board, std::ofstream& file )
vpcb.EnsureWinding( 0, false );
int nvcont = vpcb.GetNContours();
int nvcont = vpcb.GetNContours() - 1;
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
......@@ -553,13 +583,10 @@ bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool
file << "coord Coordinate {\n";
file << "point [\n";
// XXX: TODO: check return values of Write() routines; they may fail
// even though the stream is good (bad internal data)
// Coordinates (vertices)
if( plane )
{
if( ! layer->WriteVertices( top_z, file, precision ) )
if( !layer->WriteVertices( top_z, file, precision ) )
{
cerr << "* errors writing planar vertices to " << vID->objectName << "\n";
cerr << "** " << layer->GetError() << "\n";
......@@ -567,7 +594,7 @@ bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool
}
else
{
if( ! layer->Write3DVertices( top_z, bottom_z, file, precision ) )
if( !layer->Write3DVertices( top_z, bottom_z, file, precision ) )
{
cerr << "* errors writing 3D vertices to " << vID->objectName << "\n";
cerr << "** " << layer->GetError() << "\n";
......@@ -717,6 +744,7 @@ bool MakeComponents( IDF3_BOARD& board, std::ofstream& file, bool compact )
std::map< std::string, VRML_IDS*> cmap; // map colors by outline UID
VRML_IDS* vcp;
IDF3_COMP_OUTLINE* pout;
while( sc != ec )
{
......@@ -732,12 +760,28 @@ bool MakeComponents( IDF3_BOARD& board, std::ofstream& file, bool compact )
while( so != eo )
{
if( (*so)->GetOutline()->GetThickness() < 0.00000001 && nozeroheights )
{
vpcb.Clear();
++so;
continue;
}
(*so)->GetOffsets( tX, tY, tZ, tA );
tX += vX;
tY += vY;
tA += vA;
vcp = GetColor( cmap, cidx, ((IDF3_COMP_OUTLINE*)((*so)->GetOutline()))->GetUID() );
if( ( pout = (IDF3_COMP_OUTLINE*)((*so)->GetOutline()) ) )
{
vcp = GetColor( cmap, cidx, pout->GetUID() );
}
else
{
vpcb.Clear();
++so;
continue;
}
if( !compact )
{
......@@ -764,6 +808,12 @@ bool MakeComponents( IDF3_BOARD& board, std::ofstream& file, bool compact )
if( !compact || !vcp->used )
{
vpcb.EnsureWinding( 0, false );
int nvcont = vpcb.GetNContours() - 1;
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
vpcb.Tesselate( NULL );
}
......@@ -792,6 +842,10 @@ bool MakeComponents( IDF3_BOARD& board, std::ofstream& file, bool compact )
vcp = GetColor( cmap, cidx, ((IDF3_COMP_OUTLINE*)((*so)->GetOutline()))->GetUID() );
vcp->bottom = bottom;
// note: this can happen because IDF allows some negative heights/thicknesses
if( bot > top )
std::swap( bot, top );
WriteTriangles( file, vcp, &vpcb, false,
false, top, bot, board.GetUserPrecision(), compact );
......@@ -828,7 +882,8 @@ VRML_IDS* GetColor( std::map<std::string, VRML_IDS*>& cmap, int& index, const st
ostr << "OBJECTn" << refnum++;
id->objectName = ostr.str();
cout << "* " << ostr.str() << " = '" << uid << "'\n";
if( showObjectMapping )
cout << "* " << ostr.str() << " = '" << uid << "'\n";
cmap.insert( std::pair<std::string, VRML_IDS*>(uid, id) );
......@@ -840,3 +895,93 @@ VRML_IDS* GetColor( std::map<std::string, VRML_IDS*>& cmap, int& index, const st
return cit->second;
}
bool MakeOtherOutlines( IDF3_BOARD& board, std::ofstream& file )
{
int cidx = 2; // color index; start at 2 since 0,1 are special (board, NOGEOM_NOPART)
VRML_LAYER vpcb;
double scale = board.GetUserScale();
double thick = board.GetBoardThickness() / 2.0;
// set the arc parameters according to output scale
int tI;
double tMin, tMax;
vpcb.GetArcParams( tI, tMin, tMax );
vpcb.SetArcParams( tI, tMin * scale, tMax * scale );
// Add the component outlines
const std::map< std::string, OTHER_OUTLINE* >*const comp = board.GetOtherOutlines();
std::map< std::string, OTHER_OUTLINE* >::const_iterator sc = comp->begin();
std::map< std::string, OTHER_OUTLINE* >::const_iterator ec = comp->end();
double top, bot;
bool bottom;
int nvcont;
std::map< std::string, VRML_IDS*> cmap; // map colors by outline UID
VRML_IDS* vcp;
OTHER_OUTLINE* pout;
while( sc != ec )
{
pout = sc->second;
if( pout->GetSide() == IDF3::LYR_BOTTOM )
bottom = true;
else
bottom = false;
if( pout->GetThickness() < 0.00000001 && nozeroheights )
{
vpcb.Clear();
++sc;
continue;
}
vcp = GetColor( cmap, cidx, pout->GetOutlineIdentifier() );
if( !PopulateVRML( vpcb, pout->GetOutlines(), bottom,
board.GetUserScale(), 0, 0, 0 ) )
{
return false;
}
vpcb.EnsureWinding( 0, false );
nvcont = vpcb.GetNContours() - 1;
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
vpcb.Tesselate( NULL );
if( bottom )
{
top = -thick;
bot = ( top - pout->GetThickness() ) * scale;
top *= scale;
}
else
{
bot = thick;
top = (bot + pout->GetThickness() ) * scale;
bot *= scale;
}
// note: this can happen because IDF allows some negative heights/thicknesses
if( bot > top )
std::swap( bot, top );
vcp->bottom = bottom;
WriteTriangles( file, vcp, &vpcb, false,
false, top, bot, board.GetUserPrecision(), false );
vpcb.Clear();
++sc;
}
return true;
}
......@@ -23,6 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <list>
#include <string>
#include <iostream>
......@@ -89,7 +90,7 @@ IDF_NOTE::IDF_NOTE()
}
bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState,
bool IDF_NOTE::readNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState,
IDF3::IDF_UNIT aBoardUnit )
{
std::string iline; // the input line
......@@ -104,19 +105,16 @@ bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardStat
if( ( !aBoardFile.good() && !aBoardFile.eof() ) || iline.empty() )
{
ERROR_IDF;
cerr << "problems reading board notes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, "problems reading board notes" ) );
}
if( isComment )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: comment within a section (NOTES)\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: comment within a section (NOTES)" ) );
}
idx = 0;
......@@ -124,21 +122,14 @@ bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardStat
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: X position in NOTES section must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: X position in NOTES section must not be in quotes" ) );
}
if( CompareToken( ".END_NOTES", token ) )
{
// the end of the note section is a special case; although we return 'false'
// we do not change the board's state variable and we ensure that errno is 0;
// all other false returns set the state to FILE_INVALID
errno = 0;
return false;
}
istringstream istr;
istr.str( token );
......@@ -146,29 +137,26 @@ bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardStat
istr >> xpos;
if( istr.fail() )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: X position in NOTES section is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: X position in NOTES section is not numeric" ) );
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: Y position in NOTES section is missing\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: Y position in NOTES section is missing" ) );
}
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: Y position in NOTES section must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: Y position in NOTES section must not be in quotes" ) );
}
istr.clear();
......@@ -177,29 +165,26 @@ bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardStat
istr >> ypos;
if( istr.fail() )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: Y position in NOTES section is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: Y position in NOTES section is not numeric" ) );
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text height in NOTES section is missing\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text height in NOTES section is missing" ) );
}
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text height in NOTES section must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text height in NOTES section must not be in quotes" ) );
}
istr.clear();
......@@ -208,29 +193,26 @@ bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardStat
istr >> height;
if( istr.fail() )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text height in NOTES section is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text height in NOTES section is not numeric" ) );
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text length in NOTES section is missing\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text length in NOTES section is missing" ) );
}
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text length in NOTES section must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text length in NOTES section must not be in quotes" ) );
}
istr.clear();
......@@ -239,45 +221,43 @@ bool IDF_NOTE::ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardStat
istr >> length;
if( istr.fail() )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text length in NOTES section is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text length in NOTES section is not numeric" ) );
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: text value in NOTES section is missing\n";
aBoardState = IDF3::FILE_INVALID;
return false;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: text value in NOTES section is missing" ) );
}
text = token;
if( aBoardUnit == UNIT_THOU )
{
xpos *= IDF_MM_TO_THOU;
ypos *= IDF_MM_TO_THOU;
height *= IDF_MM_TO_THOU;
length *= IDF_MM_TO_THOU;
xpos *= IDF_THOU_TO_MM;
ypos *= IDF_THOU_TO_MM;
height *= IDF_THOU_TO_MM;
length *= IDF_THOU_TO_MM;
}
return true;
}
bool IDF_NOTE::WriteNote( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
bool IDF_NOTE::writeNote( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
{
if( aBoardUnit == UNIT_THOU )
{
aBoardFile << setiosflags(ios::fixed) << setprecision(1)
<< (xpos / IDF_MM_TO_THOU) << " "
<< (ypos / IDF_MM_TO_THOU) << " "
<< (height / IDF_MM_TO_THOU) << " "
<< (length / IDF_MM_TO_THOU) << " ";
<< (xpos / IDF_THOU_TO_MM) << " "
<< (ypos / IDF_THOU_TO_MM) << " "
<< (height / IDF_THOU_TO_MM) << " "
<< (length / IDF_THOU_TO_MM) << " ";
}
else
{
......@@ -422,8 +402,8 @@ bool IDF_DRILL_DATA::Matches( double aDrillDia, double aPosX, double aPosY )
return false;
}
bool IDF_DRILL_DATA::Read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
IDF3::FILE_STATE aBoardState )
bool IDF_DRILL_DATA::read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
IDF3::FILE_STATE aBoardState, IDF3::IDF_VERSION aIdfVersion )
{
std::string iline; // the input line
bool isComment; // true if a line just read in is a comment line
......@@ -436,161 +416,151 @@ bool IDF_DRILL_DATA::Read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
while( !FetchIDFLine( aBoardFile, iline, isComment, pos ) && aBoardFile.good() );
if( ( !aBoardFile.good() && !aBoardFile.eof() ) || iline.empty() )
{
ERROR_IDF;
cerr << "problems reading board drilled holes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"problems reading board drilled holes" ) );
if( isComment )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: comment within a section (DRILLED HOLES)\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: comment within a section (DRILLED HOLES)" ) );
idx = 0;
GetIDFString( iline, token, quoted, idx );
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: drill diameter must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: drill diameter must not be in quotes" ) );
if( CompareToken( ".END_DRILLED_HOLES", token ) )
{
// the end of the section is a special case; although we return 'false'
// we do not change the board's state variable and we ensure that errno is 0;
// all other false returns set the state to FILE_INVALID
errno = 0;
return false;
}
istringstream istr;
istr.str( token );
istr >> dia;
if( istr.fail() )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: drill diameter is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: drill diameter is not numeric" ) );
if( ( aBoardUnit == UNIT_MM && dia < IDF_MIN_DIA_MM )
|| ( aBoardUnit != UNIT_MM && dia < IDF_MIN_DIA_THOU ) )
|| ( aBoardUnit == UNIT_THOU && dia < IDF_MIN_DIA_THOU )
|| ( aBoardUnit == UNIT_TNM && dia < IDF_MIN_DIA_TNM ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Invalid drill diameter (too small): " << token << "\n";
aBoardState = IDF3::FILE_INVALID;
return false;
ostringstream ostr;
ostr << "invalid IDF file\n";
ostr << "* Invalid drill diameter (too small): '" << token << "'";
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: missing X position for drilled hole\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: missing X position for drilled hole" ) );
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: X position in DRILLED HOLES section must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: X position in DRILLED HOLES section must not be in quotes" ) );
istr.clear();
istr.str( token );
istr >> x;
if( istr.fail() )
{
ERROR_IDF;
cerr << "* Violation of specification: X position in DRILLED HOLES section is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: X position in DRILLED HOLES section is not numeric" ) );
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: missing Y position for drilled hole\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: missing Y position for drilled hole" ) );
if( quoted )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: Y position in DRILLED HOLES section must not be in quotes\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: Y position in DRILLED HOLES section must not be in quotes" ) );
istr.clear();
istr.str( token );
istr >> y;
if( istr.fail() )
{
ERROR_IDF;
cerr << "* Violation of specification: Y position in DRILLED HOLES section is not numeric\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDF file\n"
"* Violation of specification: Y position in DRILLED HOLES section is not numeric" ) );
if( !GetIDFString( iline, token, quoted, idx ) )
if( aIdfVersion > IDF_V2 )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: missing PLATING for drilled hole\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
if( !GetIDFString( iline, token, quoted, idx ) )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: missing PLATING for drilled hole" ) );
if( CompareToken( "PTH", token ) )
{
plating = IDF3::PTH;
if( CompareToken( "PTH", token ) )
{
plating = IDF3::PTH;
}
else if( CompareToken( "NPTH", token ) )
{
plating = IDF3::NPTH;
}
else
{
ostringstream ostr;
ostr << "invalid IDFv3 file\n";
ostr << "* Violation of specification: invalid PLATING type ('" << token << "')";
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
}
else if( CompareToken( "NPTH", token ) )
else
{
plating = IDF3::NPTH;
plating = IDF3::PTH;
}
else
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: invalid PLATING type ('" << token << "')\n";
aBoardState = IDF3::FILE_INVALID;
return false;
if( aIdfVersion > IDF_V2 )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: missing REFDES for drilled hole" ) );
}
else
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv2 file\n"
"* Violation of specification: missing HOLE TYPE for drilled hole" ) );
}
}
std::string tok1 = token;
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: missing REFDES for drilled hole\n";
aBoardState = IDF3::FILE_INVALID;
return false;
if( aIdfVersion > IDF_V2 )
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: missing HOLE TYPE for drilled hole" ) );
}
else
{
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv2 file\n"
"* Violation of specification: missing REFDES for drilled hole" ) );
}
}
std::string tok2 = token;
if( aIdfVersion > IDF_V2 )
token = tok1;
if( CompareToken( "BOARD", token ) )
{
kref = IDF3::BOARD;
......@@ -609,14 +579,10 @@ bool IDF_DRILL_DATA::Read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
refdes = token;
}
if( !GetIDFString( iline, token, quoted, idx ) )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: missing HOLE TYPE for drilled hole\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
if( aIdfVersion > IDF_V2 )
token = tok2;
else
token = tok1;
if( CompareToken( "PIN", token ) )
{
......@@ -640,35 +606,51 @@ bool IDF_DRILL_DATA::Read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit,
holetype = token;
}
if( !GetIDFString( iline, token, quoted, idx ) )
if( aIdfVersion > IDF_V2 )
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: missing OWNER for drilled hole\n";
aBoardState = IDF3::FILE_INVALID;
return false;
}
if( !GetIDFString( iline, token, quoted, idx ) )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__,
"invalid IDFv3 file\n"
"* Violation of specification: missing OWNER for drilled hole" ) );
if( !ParseOwner( token, owner ) )
{
ostringstream ostr;
ostr << "invalid IDFv3 file\n";
ostr << "* Violation of specification: invalid OWNER for drilled hole ('" << token << "')";
if( !ParseOwner( token, owner ) )
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
}
else
{
ERROR_IDF;
cerr << "invalid IDFv3 file\n";
cerr << "* Violation of specification: invalid OWNER for drilled hole ('" << token << "')\n";
aBoardState = IDF3::FILE_INVALID;
return false;
owner = IDF3::UNOWNED;
}
if( aBoardUnit == UNIT_THOU )
{
dia *= IDF_MM_TO_THOU;
x *= IDF_MM_TO_THOU;
y *= IDF_MM_TO_THOU;
dia *= IDF_THOU_TO_MM;
x *= IDF_THOU_TO_MM;
y *= IDF_THOU_TO_MM;
}
else if( ( aIdfVersion == IDF_V2 ) && ( aBoardUnit == UNIT_TNM ) )
{
dia *= IDF_TNM_TO_MM;
x *= IDF_TNM_TO_MM;
y *= IDF_TNM_TO_MM;
}
else if( aBoardUnit != UNIT_MM )
{
ostringstream ostr;
ostr << "\n* BUG: invalid UNIT type: " << aBoardUnit;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
}
return true;
}
bool IDF_DRILL_DATA::Write( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
void IDF_DRILL_DATA::write( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit )
{
std::string holestr;
std::string refstr;
......@@ -746,13 +728,13 @@ bool IDF_DRILL_DATA::Write( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit
}
else
{
aBoardFile << std::setiosflags( std::ios::fixed ) << std::setprecision( 1 ) << (dia / IDF_MM_TO_THOU) << " "
<< std::setprecision( 1 ) << (x / IDF_MM_TO_THOU) << " " << (y / IDF_MM_TO_THOU) << " "
aBoardFile << std::setiosflags( std::ios::fixed ) << std::setprecision( 1 ) << (dia / IDF_THOU_TO_MM) << " "
<< std::setprecision( 1 ) << (x / IDF_THOU_TO_MM) << " " << (y / IDF_THOU_TO_MM) << " "
<< pltstr.c_str() << " " << refstr.c_str() << " "
<< holestr.c_str() << " " << ownstr.c_str() << "\n";
}
return ! aBoardFile.fail();
return;
} // IDF_DRILL_DATA::Write( aBoardFile, unitMM )
......
......@@ -86,6 +86,16 @@ namespace IDF3 {
FILE_ERROR // other errors while processing the file
};
/**
* ENUM IDF_VERSION
* represents the supported IDF versions (3.0 and 2.0 ONLY)
*/
enum IDF_VERSION
{
IDF_V2 = 0, // version 2 has read support only; files written as IDFv3
IDF_V3 // version 3 has full read/write support
};
/**
* ENUM KEY_OWNER
* represents the type of CAD which has ownership an object
......@@ -194,6 +204,7 @@ namespace IDF3 {
{
UNIT_MM = 0, //< Units in the file are in millimeters
UNIT_THOU, //< Units in the file are in mils (aka thou)
UNIT_TNM, //< Deprecated Ten Nanometer Units from IDFv2
UNIT_INVALID
};
......@@ -261,6 +272,7 @@ namespace IDF3 {
*/
class IDF_NOTE
{
friend class IDF3_BOARD;
private:
std::string text; // note text as per IDFv3
double xpos; // text X position as per IDFv3
......@@ -268,11 +280,8 @@ private:
double height; // text height as per IDFv3
double length; // text length as per IDFv3
public:
IDF_NOTE();
/**
* Function ReadNote
* Function readNote
* reads a note entry from an IDFv3 file
*
* @param aBoardFile is an open BOARD file; the file position must be set to the start of a NOTE entry
......@@ -282,10 +291,10 @@ public:
* @return bool: true if a note item was read, false otherwise. In case of unrecoverable errors
* an exception is thrown
*/
bool ReadNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState, IDF3::IDF_UNIT aBoardUnit );
bool readNote( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState, IDF3::IDF_UNIT aBoardUnit );
/**
* Function WriteNote
* Function writeNote
* writes a note entry to an IDFv3 file
*
* @param aBoardFile is an open BOARD file; the file position must be within a NOTE section
......@@ -294,7 +303,10 @@ public:
* @return bool: true if the item was successfully written, false otherwise. In case of
* unrecoverable errors an exception is thrown
*/
bool WriteNote( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit );
bool writeNote( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit );
public:
IDF_NOTE();
/**
* Function SetText
......@@ -341,6 +353,8 @@ public:
*/
class IDF_DRILL_DATA
{
friend class IDF3_BOARD;
friend class IDF3_COMPONENT;
private:
double dia;
double x;
......@@ -352,11 +366,35 @@ private:
std::string holetype;
IDF3::KEY_OWNER owner;
/**
* Function read
* read a drill entry from an IDFv3 file
*
* @param aBoardFile is an open IDFv3 file; the file position must be within the DRILLED_HOLES section
* @param aBoardUnit is the board file's native unit (MM or THOU)
* @param aBoardState is the state value of the parser
*
* @return bool: true if data was successfully read, otherwise false. In case of an
* unrecoverable error an exception is thrown
*/
bool read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit, IDF3::FILE_STATE aBoardState,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function write
* writes a single line representing a hole within a .DRILLED_HOLES section
* In case of an unrecoverable error an exception is thrown.
*
* @param aBoardFile is an open BOARD file
* @param aBoardUnit is the native unit of the output file
*/
void write( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit );
public:
/**
* Constructor IDF_DRILL_DATA
* creates an empty drill entry which can be populated by the
* Read() function
* read() function
*/
IDF_DRILL_DATA();
......@@ -391,38 +429,12 @@ public:
*/
bool Matches( double aDrillDia, double aPosX, double aPosY );
/**
* Function Read
* read a drill entry from an IDFv3 file
*
* @param aBoardFile is an open IDFv3 file; the file position must be within the DRILLED_HOLES section
* @param aBoardUnit is the board file's native unit (MM or THOU)
* @param aBoardState is the state value of the parser
*
* @return bool: true if data was successfully read, otherwise false. In case of an
* unrecoverable error an exception is thrown
*/
bool Read( std::ifstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit, IDF3::FILE_STATE aBoardState );
/**
* Function Write
* writes a single line representing a hole within a .DRILLED_HOLES section
*
* @param aBoardFile is an open BOARD file
* @param aBoardUnit is the native unit of the output file
*
* @return bool: true if the data was successfully written, otherwise false. In case of
* an unrecoverable error an exception is thrown
*/
bool Write( std::ofstream& aBoardFile, IDF3::IDF_UNIT aBoardUnit );
/**
* Function GettDrillDia
* returns the drill diameter in mm
*/
double GetDrillDia();
/**
* Function GettDrillXPos
* returns the drill's X position in mm
......@@ -455,6 +467,11 @@ public:
* PIN, VIA, MTG, TOOL, or a user-specified string
*/
const std::string& GetDrillHoleType();
IDF3::KEY_OWNER GetDrillOwner( void )
{
return owner;
}
};
......
......@@ -229,8 +229,13 @@ bool IDF3::WriteLayersText( std::ofstream& aBoardFile, IDF3::IDF_LAYER aLayer )
break;
default:
ERROR_IDF << "Invalid IDF layer" << aLayer << "\n";
return false;
do{
std::ostringstream ostr;
ostr << "invalid IDF layer: " << aLayer;
throw( IDF_ERROR( __FILE__, __FUNCTION__, __LINE__, ostr.str() ) );
} while( 0 );
break;
}
......@@ -293,3 +298,26 @@ std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer )
return ostr.str();
}
std::string IDF3::GetOwnerString( IDF3::KEY_OWNER aOwner )
{
switch( aOwner )
{
case IDF3::UNOWNED:
return "UNOWNED";
case IDF3::MCAD:
return "MCAD";
case IDF3::ECAD:
return "ECAD";
default:
break;
}
ostringstream ostr;
ostr << "UNKNOWN: " << aOwner;
return ostr.str();
}
......@@ -59,9 +59,12 @@ static inline wxString FROM_UTF8( const char* cstring )
// minimum drill diameters / slot widths to be represented in the IDF output
#define IDF_MIN_DIA_MM ( 0.001 )
#define IDF_MIN_DIA_THOU ( 0.00039 )
#define IDF_MIN_DIA_TNM ( 100 )
// conversion between mm and thou
#define IDF_MM_TO_THOU 0.0254
// conversion from thou to mm
#define IDF_THOU_TO_MM 0.0254
// conversion from TNM to mm
#define IDF_TNM_TO_MM 0.00001
namespace IDF3
{
......@@ -166,6 +169,7 @@ std::string GetPlacementString( IDF3::IDF_PLACEMENT aPlacement );
*/
std::string GetLayerString( IDF3::IDF_LAYER aLayer );
std::string GetOwnerString( IDF3::KEY_OWNER aOwner );
}
#endif // IDF_HELPERS_H
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -91,7 +91,9 @@ class IDF3_BOARD;
*/
class BOARD_OUTLINE
{
friend class IDF3_BOARD;
protected:
std::string errormsg;
std::list< IDF_OUTLINE* > outlines;
IDF3::KEY_OWNER owner; // indicates the owner of this outline (MCAD, ECAD, UNOWNED)
IDF3::OUTLINE_TYPE outlineType;// type of IDF outline
......@@ -102,15 +104,48 @@ protected:
double thickness; // Board/Extrude Thickness or Height (IDF spec)
// Read outline data from a BOARD or LIBRARY file's outline section
bool readOutlines( std::ifstream& aBoardFile );
void readOutlines( std::ifstream& aBoardFile, IDF3::IDF_VERSION aIdfVersion );
// Write comments to a BOARD or LIBRARY file (must not be within a SECTION as per IDFv3 spec)
bool writeComments( std::ofstream& aBoardFile );
// Write the outline owner to a BOARD file
bool writeOwner( std::ofstream& aBoardFile );
// Write the data of a single outline object
bool writeOutline( std::ofstream& aBoardFile, IDF_OUTLINE* aOutline, size_t aIndex );
void writeOutline( std::ofstream& aBoardFile, IDF_OUTLINE* aOutline, size_t aIndex );
// Iterate through the outlines and write out all data
bool writeOutlines( std::ofstream& aBoardFile ); // write outline data (no headers)
void writeOutlines( std::ofstream& aBoardFile ); // write outline data (no headers)
// Clear internal list of outlines
void clearOutlines( void );
/**
* Function SetParent
* sets the parent IDF_BOARD object
*/
void setParent( IDF3_BOARD* aParent );
// Shadow routines used by friends to bypass ownership checks
bool addOutline( IDF_OUTLINE* aOutline );
virtual bool setThickness( double aThickness );
virtual void clear( void );
/**
* Function readData
* reads data from a .BOARD_OUTLINE section
* In case of an unrecoverable error an exception is thrown. On a successful
* return the file pointer will be at the line following .END_BOARD_OUTLINE
*
* @param aBoardFile is an IDFv3 file opened for reading
* @param aHeader is the ".BOARD_OUTLINE" header line as read by FetchIDFLine
*/
virtual void readData( std::ifstream& aBoardFile, const std::string& aHeader,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function writeData
* writes the comments and .BOARD_OUTLINE section to an IDFv3 file.
* Throws exceptions.
*
* @param aBoardFile is an IDFv3 file opened for writing
*/
virtual void writeData( std::ofstream& aBoardFile );
public:
BOARD_OUTLINE();
......@@ -123,7 +158,7 @@ public:
*
* @param aUnit is the native unit (UNIT_MM or UNIT_THOU)
*/
virtual void SetUnit( IDF3::IDF_UNIT aUnit );
virtual bool SetUnit( IDF3::IDF_UNIT aUnit );
/**
* Function GetUnit
......@@ -147,34 +182,13 @@ public:
*/
virtual double GetThickness( void );
/**
* Function ReadData
* reads data from a .BOARD_OUTLINE section
*
* @param aBoardFile is an IDFv3 file opened for reading
* @param aHeader is the ".BOARD_OUTLINE" header line as read by FetchIDFLine
*
* @return bool: true if the BOARD_OUTLINE section was successfully read, otherwise
* false. In case of an unrecoverable error an exception is thrown. On a successful
* return the file pointer will be at the line following .END_BOARD_OUTLINE
*/
virtual bool ReadData( std::ifstream& aBoardFile, const std::string& aHeader );
/**
* Function WriteData
* writes the comments and .BOARD_OUTLINE section to an IDFv3 file
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the data had been successfully written, otherwise false.
*/
virtual bool WriteData( std::ofstream& aBoardFile );
/**
* Function Clear
* frees memory and reinitializes all internal data except for the parent pointer
* frees memory and reinitializes all internal data except for the parent pointer.
*
* @return bool: true if OK, false on ownership violations
*/
virtual void Clear( void );
virtual bool Clear( void );
/**
* Function GetOutlineType
......@@ -182,12 +196,6 @@ public:
*/
IDF3::OUTLINE_TYPE GetOutlineType( void );
/**
* Function SetParent
* sets the parent IDF_BOARD object
*/
void SetParent( IDF3_BOARD* aParent );
/**
* Function GetParent
* returns the parent IDF_BOARD object
......@@ -202,10 +210,7 @@ public:
* @param aOutline is a valid IDF outline
*
* @return bool: true if the outline was added; false if the outline
* already existed. If the outline cannot be added due to a violation
* of the IDF specification (multiple outlines for anything other than
* a BOARD_OUTLINE, or the ownership rules are violated) an exception is
* thrown.
* already existed or an ownership violation occurs.
*/
bool AddOutline( IDF_OUTLINE* aOutline );
......@@ -221,8 +226,7 @@ public:
* @param aOutline is a pointer to the outline to remove from the list
*
* @return bool: true if the outline was found and removed; false if
* the outline was not found. If an ownership violation occurs an
* exception is thrown.
* the outline was not found or an ownership violation occurs.
*/
bool DelOutline( IDF_OUTLINE* aOutline );
......@@ -237,8 +241,8 @@ public:
* @param aIndex is an index to the outline to delete
*
* @return bool: true if the outline was found and deleted; false if
* the outline was not found. If an ownership violation or indexation
* error occurs an exception is thrown.
* the outline was not found or an ownership violation or indexation
* error occurs.
*/
bool DelOutline( size_t aIndex );
......@@ -259,8 +263,9 @@ public:
/**
* Function GetOutline
* returns a pointer to the outline as specified by aIndex.
* If the index is out of bounds an error is thrown. It is the
* responsibility of the user to observe IDF ownership rules.
* If the index is out of bounds NULL is returned and the
* error message is set. It is the responsibility of the
* user to observe IDF ownership rules.
*/
IDF_OUTLINE* GetOutline( size_t aIndex );
......@@ -331,6 +336,11 @@ public:
* deletes all comments
*/
void ClearComments( void );
const std::string& GetError( void )
{
return errormsg;
}
};
......@@ -340,19 +350,41 @@ public:
*/
class OTHER_OUTLINE : public BOARD_OUTLINE
{
friend class IDF3_BOARD;
private:
std::string uniqueID; // Outline Identifier (IDF spec)
IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM ONLY] (IDF spec)
/**
* Function readData
* reads an OTHER_OUTLINE data from an IDFv3 file.
* If an unrecoverable error occurs an exception is thrown.
*
* @param aBoardFile is an IDFv3 file open for reading
* @param aHeader is the .OTHER_OUTLINE header as read via FetchIDFLine
*/
virtual void readData( std::ifstream& aBoardFile, const std::string& aHeader,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function writeData
* writes the OTHER_OUTLINE data to an open IDFv3 file
*
* @param aBoardFile is an IDFv3 file open for writing
*
* @return bool: true if the data was successfully written, otherwise false.
*/
virtual void writeData( std::ofstream& aBoardFile );
public:
OTHER_OUTLINE();
OTHER_OUTLINE( IDF3_BOARD* aParent );
/**
* Function SetOutlineIdentifier
* sets the Outline Identifier string of this OTHER_OUTLINE object
* as per IDFv3 spec.
*/
virtual void SetOutlineIdentifier( const std::string aUniqueID );
virtual bool SetOutlineIdentifier( const std::string aUniqueID );
/**
* Function GetOutlineIdentifier
......@@ -364,8 +396,8 @@ public:
* Function SetSide
* sets the side which this outline is applicable to (TOP, BOTTOM).
*
* @return bool: true if the side was set, false if the side is invalid.
* An exception is thrown if there is a violation of IDF ownership rules.
* @return bool: true if the side was set, false if the side is invalid
* or there is a violation of IDF ownership rules.
*/
virtual bool SetSide( IDF3::IDF_LAYER aSide );
......@@ -375,33 +407,11 @@ public:
*/
virtual IDF3::IDF_LAYER GetSide( void );
/**
* Function ReadData
* reads an OTHER_OUTLINE data from an IDFv3 file.
*
* @param aBoardFile is an IDFv3 file open for reading
* @param aHeader is the .OTHER_OUTLINE header as read via FetchIDFLine
*
* @return bool: true if data was read, otherwise false. If an unrecoverable
* error occurs an exception is thrown.
*/
virtual bool ReadData( std::ifstream& aBoardFile, const std::string& aHeader );
/**
* Function WriteData
* writes the OTHER_OUTLINE data to an open IDFv3 file
*
* @param aBoardFile is an IDFv3 file open for writing
*
* @return bool: true if the data was successfully written, otherwise false.
*/
virtual bool WriteData( std::ofstream& aBoardFile );
/**
* Function Clear
* deletes internal data except for the parent object
*/
virtual void Clear( void );
virtual bool Clear( void );
};
......@@ -411,20 +421,38 @@ public:
*/
class ROUTE_OUTLINE : public BOARD_OUTLINE
{
friend class IDF3_BOARD;
private:
/**
* Function readData
* reads ROUTE_OUTLINE data from an IDFv3 file
* If an unrecoverable error occurs an exception is thrown.
*
* @param aBoardFile is an open IDFv3 board file
* @param aHeader is the .ROUTE_OUTLINE header as returned by FetchIDFLine
*/
virtual void readData( std::ifstream& aBoardFile, const std::string& aHeader,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function writeData
* writes the ROUTE_OUTLINE data to an open IDFv3 file
*/
virtual void writeData( std::ofstream& aBoardFile );
protected:
IDF3::IDF_LAYER layers; // Routing layers (IDF spec)
public:
ROUTE_OUTLINE();
ROUTE_OUTLINE( IDF3_BOARD* aParent );
/**
* Function SetLayers
* sets the layer or group of layers this outline is applicable to.
* This function is subject to IDF ownership rules. An exception is
* thrown if an invalid layer is provided or an IDF ownership violation
* occurs.
* This function is subject to IDF ownership rules; true is returned
* on success, otherwise false is returned and the error message is set.
*/
virtual void SetLayers( IDF3::IDF_LAYER aLayer );
virtual bool SetLayers( IDF3::IDF_LAYER aLayer );
/**
* Function GetLayers
......@@ -432,29 +460,11 @@ public:
*/
virtual IDF3::IDF_LAYER GetLayers( void );
/**
* Function ReadData
* reads ROUTE_OUTLINE data from an IDFv3 file
*
* @param aBoardFile is an open IDFv3 board file
* @param aHeader is the .ROUTE_OUTLINE header as returned by FetchIDFLine
*
* @return bool: true if data was read, otherwise false. If unrecoverable
* errors occur an exception is thrown.
*/
virtual bool ReadData( std::ifstream& aBoardFile, const std::string& aHeader );
/**
* Function WriteData
* writes the ROUTE_OUTLINE data to an open IDFv3 file
*/
virtual bool WriteData( std::ofstream& aBoardFile );
/**
* Function Clear
* deletes internal data except for the parent object
*/
virtual void Clear( void );
virtual bool Clear( void );
};
/**
......@@ -463,20 +473,43 @@ public:
*/
class PLACE_OUTLINE : public BOARD_OUTLINE
{
friend class IDF3_BOARD;
private:
/**
* Function readData
* reads PLACE_OUTLINE data from an open IDFv3 file.
* If an unrecoverable error occurs an exception is thrown.
*
* @param aBoardFile is an IDFv3 file opened for reading
* @param aHeader is the .PLACE_OUTLINE header as returned by FetchIDFLine
*/
virtual void readData( std::ifstream& aBoardFile, const std::string& aHeader,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function writeData
* writes the PLACE_OUTLINE data to an open IDFv3 file
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the data was successfully written, otherwise false
*/
virtual void writeData( std::ofstream& aBoardFile );
protected:
IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec)
double height; // Max Height (IDF spec)
public:
PLACE_OUTLINE();
PLACE_OUTLINE( IDF3_BOARD* aParent );
/**
* Function SetSide
* sets the side (TOP, BOTTOM, BOTH) which this outline applies to,
* subject to IDF ownership rules. An exception is thrown if there is
* an ownership violation or an invalid layer is passed.
* sets the side (TOP, BOTTOM, BOTH) which this outline applies to.
* This function is subject to IDF ownership rules; true is returned
* on success, otherwise false is returned and the error message is set.
*/
virtual void SetSide( IDF3::IDF_LAYER aSide );
virtual bool SetSide( IDF3::IDF_LAYER aSide );
/**
* Function GetSide
......@@ -486,11 +519,11 @@ public:
/**
* Function SetMaxHeight
* sets the maximum height of a component within this outline,
* subject to IDF ownership rules. An exception is thrown if
* there is an ownership violation or aHeight is negative.
* sets the maximum height of a component within this outline.
* This function is subject to IDF ownership rules; true is returned
* on success, otherwise false is returned and the error message is set.
*/
virtual void SetMaxHeight( double aHeight );
virtual bool SetMaxHeight( double aHeight );
/**
* Function GetMaxHeight
......@@ -498,33 +531,11 @@ public:
*/
virtual double GetMaxHeight( void );
/**
* Function ReadData
* reads PLACE_OUTLINE data from an open IDFv3 file.
*
* @param aBoardFile is an IDFv3 file opened for reading
* @param aHeader is the .PLACE_OUTLINE header as returned by FetchIDFLine
*
* @return bool: true if data was read, otherwise false. If there are
* unrecoverable errors an exception is thrown.
*/
virtual bool ReadData( std::ifstream& aBoardFile, const std::string& aHeader );
/**
* Function WriteData
* writes the PLACE_OUTLINE data to an open IDFv3 file
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the data was successfully written, otherwise false
*/
virtual bool WriteData( std::ofstream& aBoardFile );
/**
* Function Clear
* deletes all internal data
*/
virtual void Clear( void );
virtual bool Clear( void );
};
......@@ -535,7 +546,7 @@ public:
class ROUTE_KO_OUTLINE : public ROUTE_OUTLINE
{
public:
ROUTE_KO_OUTLINE();
ROUTE_KO_OUTLINE( IDF3_BOARD* aParent );
};
/**
......@@ -547,7 +558,7 @@ public:
class VIA_KO_OUTLINE : public OTHER_OUTLINE
{
public:
VIA_KO_OUTLINE();
VIA_KO_OUTLINE( IDF3_BOARD* aParent );
};
......@@ -559,7 +570,7 @@ public:
class PLACE_KO_OUTLINE : public PLACE_OUTLINE
{
public:
PLACE_KO_OUTLINE();
PLACE_KO_OUTLINE( IDF3_BOARD* aParent );
};
/**
......@@ -569,20 +580,42 @@ public:
*/
class GROUP_OUTLINE : public BOARD_OUTLINE
{
friend class IDF3_BOARD;
private:
IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec)
std::string groupName; // non-unique string
/**
* Function readData
* reads GROUP_OUTLINE data from an open IDFv3 file
* If an unrecoverable error occurs an exception is thrown.
*
* @param aBoardFile is an open IDFv3 file
* @param aHeader is the .PLACE_REGION header as returned by FetchIDFLine
*/
virtual void readData( std::ifstream& aBoardFile, const std::string& aHeader,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function writeData
* writes the data to a .PLACE_REGION section of an IDFv3 file
*
* @param aBoardFile is an IDFv3 file open for writing
*
* @return bool: true if the data is successfully written, otherwise false
*/
virtual void writeData( std::ofstream& aBoardFile );
public:
GROUP_OUTLINE();
GROUP_OUTLINE( IDF3_BOARD* aParent );
/**
* Function SetSide
* sets the side which this outline applies to (TOP, BOTTOM, BOTH),
* subject to IDF ownership rules. If an ownership violation occurs
* or an invalid side is specified, an exception is thrown.
* sets the side which this outline applies to (TOP, BOTTOM, BOTH).
* This function is subject to IDF ownership rules; true is returned
* on success, otherwise false is returned and the error message is set.
*/
virtual void SetSide( IDF3::IDF_LAYER aSide );
virtual bool SetSide( IDF3::IDF_LAYER aSide );
/**
* Function GetSide
......@@ -593,10 +626,10 @@ public:
/**
* Function SetGroupName
* sets the name of the group, subject to IDF ownership rules.
* An empty name or an ownership violation results in a thrown
* exception.
* This function is subject to IDF ownership rules; true is returned
* on success, otherwise false is returned and the error message is set.
*/
virtual void SetGroupName( std::string aGroupName );
virtual bool SetGroupName( std::string aGroupName );
/**
* Function GetGroupName
......@@ -604,33 +637,11 @@ public:
*/
virtual const std::string& GetGroupName( void );
/**
* Function ReadData
* reads GROUP_OUTLINE data from an open IDFv3 file
*
* @param aBoardFile is an open IDFv3 file
* @param aHeader is the .PLACE_REGION header as returned by FetchIDFLine
*
* @return bool: true if data was read, otherwise false. If an unrecoverable
* error occurs an exception is thrown.
*/
virtual bool ReadData( std::ifstream& aBoardFile, const std::string& aHeader );
/**
* Function WriteData
* writes the data to a .PLACE_REGION section of an IDFv3 file
*
* @param aBoardFile is an IDFv3 file open for writing
*
* @return bool: true if the data is successfully written, otherwise false
*/
virtual bool WriteData( std::ofstream& aBoardFile );
/**
* Function Clear
* deletes internal data, subject to IDF ownership rules
*/
virtual void Clear( void );
virtual bool Clear( void );
};
......@@ -640,6 +651,8 @@ public:
*/
class IDF3_COMP_OUTLINE : public BOARD_OUTLINE
{
friend class IDF3_BOARD;
friend class IDF3_COMP_OUTLINE_DATA;
private:
std::string uid; // unique ID
std::string geometry; // geometry name (IDF)
......@@ -649,46 +662,65 @@ private:
std::map< std::string, std::string > props; // properties list
bool readProperties( std::ifstream& aLibFile );
void readProperties( std::ifstream& aLibFile );
bool writeProperties( std::ofstream& aLibFile );
public:
IDF3_COMP_OUTLINE();
/**
* Function ReadData
* Function readData
* reads a component outline from an open IDFv3 file
* If an unrecoverable error occurs, an exception is thrown.
*
* @param aLibFile is an open IDFv3 Library file
* @param aHeader is the .ELECTRICAL or .MECHANICAL header as returned by FetchIDFLine
*
* @return bool: true if data was read, otherwise false. If unrecoverable errors
* occur, an exception is thrown.
*/
virtual bool ReadData( std::ifstream& aLibFile, const std::string& aHeader );
virtual void readData( std::ifstream& aLibFile, const std::string& aHeader,
IDF3::IDF_VERSION aIdfVersion );
/**
* Function WriteData
* Function writeData
* writes comments and component outline data to an IDFv3 Library file
*
* @param aLibFile is an IDFv3 library file open for writing
*
* @return bool: true if the data was successfully written, otherwise false
*/
virtual bool WriteData( std::ofstream& aLibFile );
virtual void writeData( std::ofstream& aLibFile );
/**
* Function incrementRef
* increments the internal reference counter to keep track of the number of
* components referring to this outline.
*
* @return int: the number of current references to this component outline
*/
int incrementRef( void );
/**
* Function decrementRef
* decrements the internal reference counter to keep track of the number of
* components referring to this outline.
*
* @return int: the number of remaining references or -1 if there were no
* references when the function was invoked, in which case the error message
* is also set.
*/
int decrementRef( void );
public:
IDF3_COMP_OUTLINE( IDF3_BOARD* aParent );
/**
* Function Clear
* deletes internal outline data
*/
virtual void Clear( void );
virtual bool Clear( void );
/**
* Function SetComponentClass
* sets the type of component outline (.ELECTRICAL or .MECHANICAL)
* If the specified class is invalid an exception is thrown.
* sets the type of component outline (.ELECTRICAL or .MECHANICAL).
* Returns true on success, otherwise false and the error message is set
*/
void SetComponentClass( IDF3::COMP_TYPE aCompClass );
bool SetComponentClass( IDF3::COMP_TYPE aCompClass );
/**
* Function GetComponentClass
......@@ -727,20 +759,6 @@ public:
*/
const std::string& GetUID( void );
/**
* Function IncrementRef
* increments the internal reference counter to keep track of the number of
* components referring to this outline.
*/
int IncrementRef( void );
/**
* Function DecrementRef
* decrements the internal reference counter to keep track of the number of
* components referring to this outline.
*/
int DecrementRef( void );
/**
* Function CreateDefaultOutline
* creates a default outline with the given Geometry and Part names.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -21,27 +21,36 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
// NOTE:
// 1. Due to the complexity of objects and the risk of accumulated
// position errors, CAD packages should only delete or add complete
// components. If a component being added already exists, it is
// replaced by the new component IF and only if the CAD type is
// permitted to make such changes.
//
// 2. Internally all units shall be in mm and by default we shall
// write files with mm units. The internal flags mm/thou shall only
// be used to translate data being read from or written to files.
// This avoids the painful management of a mixture of mm and thou.
// The API shall require all dimensions in mm; for people using any
// other unit, it is their responsibility to perform the conversion
// to mm. Conversion back to thou may incur small rounding errors.
// BUGS:
// 1. IDF compliance: On DELETE operations, ensure that the CAD
// has permission to make these deletions. This is no small task;
// however this compliance task can be deferred since it is not
// essential to the immediate needs of KiCad which are IDF
// export and IDF->VRML conversion
/*
* NOTE:
*
* Rules to ensure friendly use within a DLL:
*
* 1. all functions which throw exceptions must not be publicly available;
* they must become FRIEND functions instead.
*
* 2. All objects with PRIVATE functions which throw exceptions when
* invoked by a PUBLIC function must indicate success or failure
* and make the exception information available via a GetError()
* routine.
*
* General notes:
*
* 1. Due to the complexity of objects and the risk of accumulated
* position errors, CAD packages should only delete or add complete
* components. If a component being added already exists, it is
* replaced by the new component IF and only if the CAD type is
* permitted to make such changes.
*
* 2. Internally all units shall be in mm and by default we shall
* write files with mm units. The internal flags mm/thou shall only
* be used to translate data being read from or written to files.
* This avoids the painful management of a mixture of mm and thou.
* The API shall require all dimensions in mm; for people using any
* other unit, it is their responsibility to perform the conversion
* to mm. Conversion back to thou may incur small rounding errors.
*/
#ifndef IDF_PARSER_H
#define IDF_PARSER_H
......@@ -52,15 +61,58 @@ class IDF3_COMPONENT;
class IDF3_COMP_OUTLINE_DATA
{
friend class IDF3_BOARD;
friend class IDF3_COMPONENT;
private:
double xoff; // X offset from KiCad or X placement from IDF file
double yoff; // Y offset from KiCad or Y placement from IDF file
double zoff; // height offset (specified in IDFv3 spec, corresponds to KiCad Z offset)
double aoff; // angular offset from KiCad or Rotation Angle from IDF file
std::string errormsg;
IDF3_COMP_OUTLINE* outline; // component outline to use
IDF3_COMPONENT* parent; // associated component
#ifndef DISABLE_IDF_OWNERSHIP
bool checkOwnership( int aSourceLine, const char* aSourceFunc );
#endif
/**
* Function readPlaceData
* reads placement data from an open IDFv3 file
*
* @param aBoardFile is the open IDFv3 file
* @param aBoardState is the internal status flag of the IDF parser
* @param aIdfVersion is the version of the file currently being parsed
* @param aBoard is the IDF3_BOARD object which will store the data
*
* @return bool: true if placement data was successfully read. false if
* no placement data was read; this may happen if the end of the placement
* data was encountered or an error occurred. if an error occurred then
* an exception is thrown.
*/
bool readPlaceData( std::ifstream &aBoardFile, IDF3::FILE_STATE& aBoardState,
IDF3_BOARD *aBoard, IDF3::IDF_VERSION aIdfVersion,
bool aNoSubstituteOutlines );
/**
* Function writePlaceData
* writes RECORD 2 and RECORD 3 of a PLACEMENT section as per IDFv3 specification
*
* @param aBoardFile is the open IDFv3 file
* @param aXpos is the X location of the parent component
* @param aYpos is the Y location of the parent component
* @param aAngle is the rotation of the parent component
* @param aRefDes is the reference designator of the parent component
* @param aPlacement is the IDF Placement Status of the parent component
* @param aSide is the IDF Layer Designator (TOP or BOTTOM)
*
* @return bool: true if data was successfully written, otherwise false
*/
void writePlaceData( std::ofstream& aBoardFile, double aXpos, double aYpos, double aAngle,
const std::string aRefDes, IDF3::IDF_PLACEMENT aPlacement,
IDF3::IDF_LAYER aSide );
public:
/**
* Constructor
......@@ -102,8 +154,11 @@ public:
* @param aYoff is the Y offset of this outline in relation to its parent
* @param aZoff is the board offset of this outline as per IDFv3 specification
* @param aAoff is the rotational offset of this outline in relation to its parent
*
* @return bool: true if the operation succeeded, false if an ownership
* violation occurred
*/
void SetOffsets( double aXoff, double aYoff, double aZoff, double aAngleOff );
bool SetOffsets( double aXoff, double aYoff, double aZoff, double aAngleOff );
/**
* Function GetOffsets
......@@ -129,8 +184,11 @@ public:
* sets the outline whose position is managed by this object
*
* @param aOutline is the outline for this component
*
* @return bool: true if the operation succeeded, false if an ownership
* violation occurred
*/
void SetOutline( IDF3_COMP_OUTLINE* aOutline );
bool SetOutline( IDF3_COMP_OUTLINE* aOutline );
/**
* Function GetOutline
......@@ -143,44 +201,16 @@ public:
return outline;
}
/**
* Function ReadPlaceData
* reads placement data from an open IDFv3 file
*
* @param aBoardFile is the open IDFv3 file
* @param aBoardState is the internal status flag of the IDF parser
* @param aBoard is the IDF3_BOARD object which will store the data
*
* @return bool: true if placement data was successfully read. false if
* no placement data was read; this may happen if the end of the placement
* data was encountered or an error occurred. if an error occurred then
* aBoardState is set to IDF3::FILE_INVALID or IDF3::FILE_ERROR.
*/
bool ReadPlaceData( std::ifstream &aBoardFile, IDF3::FILE_STATE& aBoardState,
IDF3_BOARD *aBoard );
/**
* Function WritePlaceData
* writes RECORD 2 and RECORD 3 of a PLACEMENT section as per IDFv3 specification
*
* @param aBoardFile is the open IDFv3 file
* @param aXpos is the X location of the parent component
* @param aYpos is the Y location of the parent component
* @param aAngle is the rotation of the parent component
* @param aRefDes is the reference designator of the parent component
* @param aPlacement is the IDF Placement Status of the parent component
* @param aSide is the IDF Layer Designator (TOP or BOTTOM)
*
* @return bool: true if data was successfully written, otherwise false
*/
bool WritePlaceData( std::ofstream& aBoardFile, double aXpos, double aYpos, double aAngle,
const std::string aRefDes, IDF3::IDF_PLACEMENT aPlacement,
IDF3::IDF_LAYER aSide );
const std::string& GetError( void )
{
return errormsg;
}
};
class IDF3_COMPONENT
{
friend class IDF3_BOARD;
private:
std::list< IDF3_COMP_OUTLINE_DATA* > components;
std::list< IDF_DRILL_DATA* > drills;
......@@ -193,14 +223,33 @@ private:
bool hasPosition; ///< True after SetPosition is called once
std::string refdes; ///< Reference Description (MUST BE UNIQUE)
IDF3_BOARD* parent;
std::string errormsg;
public:
/**
* Constructor
* sets internal parameters to default values
* Function WriteDrillData
* writes the internal drill data to an IDFv3 .DRILLED_HOLES section
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the operation succeeded, otherwise false
*/
IDF3_COMPONENT();
bool writeDrillData( std::ofstream& aBoardFile );
/**
* Function WritePlaceData
* writes the component placement data to an IDFv3 .PLACEMENT section
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the operation succeeded, otherwise false
*/
bool writePlaceData( std::ofstream& aBoardFile );
#ifndef DISABLE_IDF_OWNERSHIP
bool checkOwnership( int aSourceLine, const char* aSourceFunc );
#endif
public:
/**
* Constructor
* sets the parent object and initializes other internal parameters to default values
......@@ -399,33 +448,22 @@ public:
* sets the placement value of the component subject to ownership rules.
* An exception is thrown if aPlacementValue is invalid or an ownership
* violation occurs.
*/
void SetPlacement( IDF3::IDF_PLACEMENT aPlacementValue );
/**
* Function WriteDrillData
* writes the internal drill data to an IDFv3 .DRILLED_HOLES section
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the operation succeeded, otherwise false
* @return bool: true if the operation succeeded, otherwise false and the
* error message is set.
*/
bool WriteDrillData( std::ofstream& aBoardFile );
bool SetPlacement( IDF3::IDF_PLACEMENT aPlacementValue );
/**
* Function WritePlaceData
* writes the component placement data to an IDFv3 .PLACEMENT section
*
* @param aBoardFile is an IDFv3 file opened for writing
*
* @return bool: true if the operation succeeded, otherwise false
*/
bool WritePlaceData( std::ofstream& aBoardFile );
const std::string& GetError( void )
{
return errormsg;
}
};
class IDF3_BOARD
{
private:
std::string errormsg; // string for passing error messages to user
std::list< IDF_NOTE* > notes; // IDF notes
std::list< std::string > noteComments; // comment list for NOTES section
std::list< std::string > drillComments; // comment list for DRILL section
......@@ -437,6 +475,7 @@ private:
IDF3::FILE_STATE state;
IDF3::CAD_TYPE cadType;
IDF3::IDF_UNIT unit;
IDF3::IDF_VERSION idfVer; // IDF version of Board or Library
std::string idfSource; // SOURCE string to use when writing BOARD and LIBRARY headers
std::string brdSource; // SOURCE string as retrieved from a BOARD file
......@@ -483,31 +522,40 @@ private:
bool delCompDrill( double aDia, double aXpos, double aYpos, std::string aRefDes );
// read the DRILLED HOLES section
bool readBrdDrills( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
void readBrdDrills( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
// read the NOTES section
bool readBrdNotes( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
void readBrdNotes( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
// read the component placement section
bool readBrdPlacement( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
void readBrdPlacement( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState,
bool aNoSubstituteOutlines );
// read the board HEADER
bool readBrdHeader( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
void readBrdHeader( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
// read individual board sections; pay attention to IDFv3 section specifications
bool readBrdSection( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
// exception thrown on unrecoverable errors. state flag set to FILE_PLACEMENT
// upon reading the PLACEMENT file; according to IDFv3 this is the final section
void readBrdSection( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState,
bool aNoSubstituteOutlines );
// read the board file data
bool readBoardFile( const std::string& aFileName );
void readBoardFile( const std::string& aFileName, bool aNoSubstituteOutlines );
// write the board file data
bool writeBoardFile( const std::string& aFileName );
void writeBoardFile( const std::string& aFileName );
// read the library sections (outlines)
bool readLibSection( std::ifstream& aLibFile, IDF3::FILE_STATE& aLibState, IDF3_BOARD* aBoard );
void readLibSection( std::ifstream& aLibFile, IDF3::FILE_STATE& aLibState, IDF3_BOARD* aBoard );
// read the library HEADER
bool readLibHeader( std::ifstream& aLibFile, IDF3::FILE_STATE& aLibState );
void readLibHeader( std::ifstream& aLibFile, IDF3::FILE_STATE& aLibState );
// read the library file data
bool readLibFile( const std::string& aFileName );
void readLibFile( const std::string& aFileName );
// write the library file data
bool writeLibFile( const std::string& aFileName );
#ifndef DISABLE_IDF_OWNERSHIP
bool checkComponentOwnership( int aSourceLine, const char* aSourceFunc,
IDF3_COMPONENT* aComponent );
#endif
public:
IDF3_BOARD( IDF3::CAD_TYPE aCadType );
virtual ~IDF3_BOARD();
......@@ -527,7 +575,7 @@ public:
bool SetBoardThickness( double aBoardThickness );
double GetBoardThickness( void );
bool ReadFile( const wxString& aFullFileName );
bool ReadFile( const wxString& aFullFileName, bool aNoSubstituteOutlines = false );
bool WriteFile( const wxString& aFullFileName, bool aUnitMM = true, bool aForceUnitFlag = false );
const std::string& GetIDFSource( void );
......@@ -557,7 +605,13 @@ public:
BOARD_OUTLINE* GetBoardOutline( void );
const std::list< IDF_OUTLINE* >*const GetBoardOutlines( void );
// Operations for OTHER OUTLINES
const std::map<std::string, OTHER_OUTLINE*>*const GetOtherOutlines( void );
/// XXX - TO BE IMPLEMENTED
//
// SetBoardOutlineOwner()
//
// AddDrillComment
// AddPlacementComment
// GetDrillComments()
......@@ -568,7 +622,7 @@ public:
// GetNoteComments
// AddNote
//
// const std::map<std::string, OTHER_OUTLINE*>*const GetOtherOutlines()
// [IMPLEMENTED] const std::map<std::string, OTHER_OUTLINE*>*const GetOtherOutlines( void )
// size_t GetOtherOutlinesSize()
// OTHER_OUTLINE* AddOtherOutline( OTHER_OUTLINE* aOtherOutline )
// bool DelOtherOutline( int aIndex )
......@@ -652,6 +706,12 @@ public:
// clears all data
void Clear( void );
// return error string
const std::string& GetError( void )
{
return errormsg;
}
};
#endif // IDF_PARSER_H
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