Add patch about idf export (from cirilo_bernardo)

This commit is contained in:
unknown 2014-05-28 08:26:46 +02:00 committed by jean-pierre charras
parent e585f2d205
commit 6652bcdc5f
21 changed files with 14152 additions and 30 deletions

View File

@ -1,29 +1,32 @@
include_directories(
"${CMAKE_SOURCE_DIR}/include"
"${CMAKE_SOURCE_DIR}/lib_dxf"
"${CMAKE_SOURCE_DIR}/pcbnew/exporters"
"${CMAKE_SOURCE_DIR}/utils/idftools"
)
link_directories(
"${CMAKE_BINARY_DIR}/lib_dxf"
)
add_executable( idfcyl idf_cylinder.cpp )
add_executable( idfrect idf_rect.cpp )
add_executable( dxf2idf dxf2idfmain.cpp dxf2idf.cpp
"${CMAKE_SOURCE_DIR}/pcbnew/exporters/idf_common.cpp"
"${CMAKE_SOURCE_DIR}/common/richio.cpp"
)
add_dependencies( idfcyl lib-dependencies )
add_dependencies( idfrect lib-dependencies )
add_dependencies( dxf2idf lib-dependencies )
add_library( idf3 STATIC
idf_helpers.cpp idf_common.cpp idf_outlines.cpp
idf_parser.cpp vrml_layer.cpp )
target_link_libraries( dxf2idf lib_dxf ${wxWidgets_LIBRARIES} )
add_executable( idfcyl idf_cylinder.cpp )
add_executable( idfrect idf_rect.cpp )
add_executable( dxf2idf dxf2idfmain.cpp dxf2idf.cpp )
add_executable( idf2vrml idf2vrml.cpp )
install( TARGETS idfcyl idfrect dxf2idf
target_link_libraries( dxf2idf lib_dxf idf3 ${wxWidgets_LIBRARIES} )
if( WIN32 )
set ( LIB_GLU glu32 )
else()
set ( LIB_GLU GLU )
endif()
target_link_libraries( idf2vrml idf3 ${LIB_GLU} ${wxWidgets_LIBRARIES} )
install( TARGETS idfcyl idfrect dxf2idf idf2vrml
DESTINATION ${KICAD_BIN}
COMPONENT binary )

View File

@ -123,7 +123,8 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> height ) && height > 0.001 )
tstr >> height;
if( !tstr.fail() && height > 0.001 )
ok = true;
}

842
utils/idftools/idf2vrml.cpp Normal file
View File

@ -0,0 +1,842 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* This program takes an IDF base name, loads the board outline
* and component outine files, and creates a single VRML file.
* The VRML file can be used to visually verify the IDF files
* before sending them to a mechanical designer. The output scale
* is 10:1; this scale was chosen because VRML was originally
* intended to describe large virtual worlds and rounding errors
* would be more likely if we used a 1:1 scale.
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cerrno>
#include <list>
#include <utility>
#include <clocale>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <libgen.h>
#include <unistd.h>
#include <idf_helpers.h>
#include <idf_common.h>
#include <idf_parser.h>
#include <vrml_layer.h>
#ifndef MIN_ANG
#define MIN_ANG 0.01
#endif
extern char* optarg;
extern int optopt;
using namespace std;
#define CLEANUP do { \
setlocale( LC_ALL, "C" ); \
} while( 0 );
// define colors
struct VRML_COLOR
{
double diff[3];
double emis[3];
double spec[3];
double ambi;
double tran;
double shin;
};
struct VRML_IDS
{
int colorIndex;
std::string objectName;
bool used;
bool bottom;
double dX, dY, dZ, dA;
VRML_IDS()
{
colorIndex = 0;
used = false;
bottom = false;
dX = 0.0;
dY = 0.0;
dZ = 0.0;
dA = 0.0;
}
};
#define NCOLORS 7
VRML_COLOR colors[NCOLORS] = { \
{ 0, 0.82, 0.247, 0, 0, 0, 0, 0.82, 0.247, 0.9, 0, 0.1}, \
{ 1, 0, 0, 1, 0, 0, 1, 0, 0, 0.9, 0, 0.1}, \
{ 0.659, 0, 0.463, 0, 0, 0, 0.659, 0, 0.463, 0.9, 0, 0.1}, \
{ 0.659, 0.294, 0, 0, 0, 0, 0.659, 0.294, 0, 0.9, 0, 0.1}, \
{ 0, 0.918, 0.659, 0, 0, 0, 0, 0.918, 0.659, 0.9, 0, 0.1}, \
{ 0.808, 0.733 , 0.071, 0, 0, 0, 0.808, 0.733 , 0.071, 0.9, 0, 0.1}, \
{ 0.102, 1, 0.984, 0, 0, 0, 0.102, 1, 0.984, 0.9, 0, 0.1}
};
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 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 );
bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool plane,
bool top, double top_z, double bottom_z, int precision, bool compact );
inline void TransformPoint( IDF_SEGMENT& seg, double frac, bool bottom,
double dX, double dY, double angle );
VRML_IDS* GetColor( std::map<std::string, VRML_IDS*>& cmap,
int& index, const std::string& uid );
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 << "example to produce a model for use by KiCad: idf2vrml -f input.emn -s 0.3937008 -k\n\n";
return;
}
int main( int argc, char **argv )
{
// IDF implicitly requires the C locale
setlocale( LC_ALL, "C" );
// Essential inputs:
// 1. IDF file
// 2. Output scale: internal IDF units are mm, so 1 = 1mm per VRML unit,
// 0.1 = 1cm per VRML unit, 0.01 = 1m per VRML unit,
// 1/25.4 = 1in per VRML unit, 1/2.54 = 0.1in per VRML unit (KiCad model)
// 3. KiCad-friendly output (do not reuse features via DEF+USE)
// Render each component to VRML; if the user wants
// a KiCad friendly output then we must avoid DEF+USE;
// otherwise we employ DEF+USE to minimize file size
std::string inputFilename;
double scaleFactor = 1.0;
bool compact = true;
int ichar;
while( ( ichar = getopt( argc, argv, ":f:s:k" ) ) != -1 )
{
switch( ichar )
{
case 'f':
inputFilename = optarg;
break;
case 's':
do
{
errno = 0;
char* cp = NULL;
scaleFactor = strtod( optarg, &cp );
if( errno || cp == optarg )
{
cerr << "* invalid scale factor: '" << optarg << "'\n";
return -1;
}
if( scaleFactor < 0.001 || scaleFactor > 10 )
{
cerr << "* scale factor out of range (" << scaleFactor << "); range is 0.001 to 10.0\n";
return -1;
}
} while( 0 );
break;
case 'k':
compact = false;
break;
case ':':
cerr << "* Missing parameter to option '-" << ((char) optopt) << "'\n";
PrintUsage();
return -1;
break;
default:
cerr << "* Unexpected option: '-";
if( ichar == '?' )
cerr << ((char) optopt) << "'\n";
else
cerr << ((char) ichar) << "'\n";
PrintUsage();
return -1;
break;
}
}
if( inputFilename.empty() )
{
cerr << "* no IDF filename supplied\n";
PrintUsage();
return -1;
}
IDF3_BOARD pcb( IDF3::CAD_ELEC );
cout << "** Reading file: " << inputFilename << "\n";
if( !pcb.ReadFile( FROM_UTF8( inputFilename.c_str() ) ) )
{
CLEANUP;
cerr << "* Could not read file: " << inputFilename << "\n";
return -1;
}
// set the scale and output precision ( scale 1 == precision 5)
pcb.SetUserScale( scaleFactor );
if( scaleFactor < 0.01 )
pcb.SetUserPrecision( 8 );
else if( scaleFactor < 0.1 )
pcb.SetUserPrecision( 7 );
else if( scaleFactor < 1.0 )
pcb.SetUserPrecision( 6 );
else if( scaleFactor < 10.0 )
pcb.SetUserPrecision( 5 );
else
pcb.SetUserPrecision( 4 );
// Create the VRML file and write the header
char* bnp = (char*) malloc( inputFilename.size() + 1 );
strcpy( bnp, inputFilename.c_str() );
std::string fname = basename( bnp );
free( bnp );
std::string::iterator itf = fname.end();
*(--itf) = 'l';
*(--itf) = 'r';
*(--itf) = 'w';
cout << "Writing file: '" << fname << "'\n";
std::ofstream ofile;
ofile.open( fname.c_str(), std::ios_base::out );
ofile << fixed; // do not use exponents in VRML output
WriteHeader( pcb, ofile );
// STEP 1: Render the PCB alone
MakeBoard( pcb, ofile );
// STEP 2: Render the components
MakeComponents( pcb, ofile, compact );
ofile << "]\n}\n";
ofile.close();
// restore the locale
setlocale( LC_ALL, "" );
return 0;
}
bool WriteHeader( IDF3_BOARD& board, std::ofstream& file )
{
std::string bname = board.GetBoardName();
if( bname.empty() )
{
bname = "BoardWithNoName";
}
else
{
std::string::iterator ss = bname.begin();
std::string::iterator se = bname.end();
while( ss != se )
{
if( *ss == '/' || *ss == ' ' || *ss == ':' )
*ss = '_';
++ss;
}
}
file << "#VRML V2.0 utf8\n\n";
file << "WorldInfo {\n";
file << " title \"" << bname << "\"\n}\n\n";
file << "Transform {\n";
file << "children [\n";
return !file.fail();
}
bool MakeBoard( IDF3_BOARD& board, std::ofstream& file )
{
VRML_LAYER vpcb;
if( board.GetBoardOutlinesSize() < 1 )
{
ERROR_IDF << "\n";
cerr << "* Cannot proceed; no board outline in IDF object\n";
return false;
}
double scale = board.GetUserScale();
// 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 );
if( !PopulateVRML( vpcb, board.GetBoardOutline()->GetOutlines(), false, board.GetUserScale() ) )
{
return false;
}
vpcb.EnsureWinding( 0, false );
int nvcont = vpcb.GetNContours();
while( nvcont > 0 )
vpcb.EnsureWinding( nvcont--, true );
// Add the drill holes
const std::list<IDF_DRILL_DATA*>* drills = &board.GetBoardDrills();
std::list<IDF_DRILL_DATA*>::const_iterator sd = drills->begin();
std::list<IDF_DRILL_DATA*>::const_iterator ed = drills->end();
while( sd != ed )
{
vpcb.AddCircle( (*sd)->GetDrillXPos() * scale, (*sd)->GetDrillYPos() * scale,
(*sd)->GetDrillDia() * scale / 2.0, true );
++sd;
}
std::map< std::string, IDF3_COMPONENT* >*const comp = board.GetComponents();
std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
while( sc != ec )
{
drills = sc->second->GetDrills();
sd = drills->begin();
ed = drills->end();
while( sd != ed )
{
vpcb.AddCircle( (*sd)->GetDrillXPos() * scale, (*sd)->GetDrillYPos() * scale,
(*sd)->GetDrillDia() * scale / 2.0, true );
++sd;
}
++sc;
}
// tesselate and write out
vpcb.Tesselate( NULL );
double thick = board.GetBoardThickness() / 2.0 * scale;
VRML_IDS tvid;
tvid.colorIndex = 0;
WriteTriangles( file, &tvid, &vpcb, false, false,
thick, -thick, board.GetUserPrecision(), false );
return true;
}
bool PopulateVRML( VRML_LAYER& model, const std::list< IDF_OUTLINE* >* items, bool bottom, double scale,
double dX, double dY, double angle )
{
// empty outlines are not unusual so we fail quietly
if( items->size() < 1 )
return false;
int nvcont = 0;
int iseg = 0;
std::list< IDF_OUTLINE* >::const_iterator scont = items->begin();
std::list< IDF_OUTLINE* >::const_iterator econt = items->end();
std::list<IDF_SEGMENT*>::iterator sseg;
std::list<IDF_SEGMENT*>::iterator eseg;
IDF_SEGMENT lseg;
while( scont != econt )
{
nvcont = model.NewContour();
if( nvcont < 0 )
{
ERROR_IDF << "\n";
cerr << "* cannot create an outline\n";
return false;
}
if( (*scont)->size() < 1 )
{
ERROR_IDF << "invalid contour: no vertices\n";
return false;
}
sseg = (*scont)->begin();
eseg = (*scont)->end();
iseg = 0;
while( sseg != eseg )
{
lseg = **sseg;
TransformPoint( lseg, scale, bottom, dX, dY, angle );
if( !AddSegment( model, &lseg, nvcont, iseg ) )
return false;
++iseg;
++sseg;
}
++scont;
}
return true;
}
bool AddSegment( VRML_LAYER& model, IDF_SEGMENT* seg, int icont, int iseg )
{
// note: in all cases we must add all but the last point in the segment
// to avoid redundant points
if( seg->angle != 0.0 )
{
if( seg->IsCircle() )
{
if( iseg != 0 )
{
ERROR_IDF << "adding a circle to an existing vertex list\n";
return false;
}
return model.AppendCircle( seg->center.x, seg->center.y, seg->radius, icont );
}
else
{
return model.AppendArc( seg->center.x, seg->center.y, seg->radius,
seg->offsetAngle, seg->angle, icont );
}
}
if( !model.AddVertex( icont, seg->startPoint.x, seg->startPoint.y ) )
return false;
return true;
}
bool WriteTriangles( std::ofstream& file, VRML_IDS* vID, VRML_LAYER* layer, bool plane,
bool top, double top_z, double bottom_z, int precision, bool compact )
{
if( vID == NULL || layer == NULL )
return false;
file << "Transform {\n";
if( compact && !vID->objectName.empty() )
{
file << "translation " << setprecision( precision ) << vID->dX;
file << " " << vID->dY << " ";
if( vID->bottom )
{
file << -vID->dZ << "\n";
double tx, ty;
// calculate the rotation axis and angle
tx = cos( M_PI2 - vID->dA / 2.0 );
ty = sin( M_PI2 - vID->dA / 2.0 );
file << "rotation " << setprecision( precision );
file << tx << " " << ty << " 0 ";
file << setprecision(5) << M_PI << "\n";
}
else
{
file << vID->dZ << "\n";
file << "rotation 0 0 1 " << setprecision(5) << vID->dA << "\n";
}
file << "children [\n";
if( vID->used )
{
file << "USE " << vID->objectName << "\n";
file << "]\n";
file << "}\n";
return true;
}
file << "DEF " << vID->objectName << " Transform {\n";
if( !plane && top_z <= bottom_z )
{
// the height specification is faulty; make the component
// a bright red to highlight it
vID->colorIndex = 1;
// we don't know the scale, but 5 units is huge in most situations
top_z = bottom_z + 5.0;
}
}
VRML_COLOR* color = &colors[vID->colorIndex];
vID->used = true;
file << "children [\n";
file << "Group {\n";
file << "children [\n";
file << "Shape {\n";
file << "appearance Appearance {\n";
file << "material Material {\n";
// material definition
file << "diffuseColor " << setprecision(3) << color->diff[0] << " ";
file << color->diff[1] << " " << color->diff[2] << "\n";
file << "specularColor " << color->spec[0] << " " << color->spec[1];
file << " " << color->spec[2] << "\n";
file << "emissiveColor " << color->emis[0] << " " << color->emis[1];
file << " " << color->emis[2] << "\n";
file << "ambientIntensity " << color->ambi << "\n";
file << "transparency " << color->tran << "\n";
file << "shininess " << color->shin << "\n";
file << "}\n";
file << "}\n";
file << "geometry IndexedFaceSet {\n";
file << "solid TRUE\n";
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 ) )
{
cerr << "* errors writing planar vertices to " << vID->objectName << "\n";
cerr << "** " << layer->GetError() << "\n";
}
}
else
{
if( ! layer->Write3DVertices( top_z, bottom_z, file, precision ) )
{
cerr << "* errors writing 3D vertices to " << vID->objectName << "\n";
cerr << "** " << layer->GetError() << "\n";
}
}
file << "\n";
file << "]\n";
file << "}\n";
file << "coordIndex [\n";
// Indices
if( plane )
layer->WriteIndices( top, file );
else
layer->Write3DIndices( file );
file << "\n";
file << "]\n";
file << "}\n";
file << "}\n";
file << "]\n";
file << "}\n";
file << "]\n";
file << "}\n";
if( compact && !vID->objectName.empty() )
{
file << "]\n";
file << "}\n";
}
return !file.fail();
}
inline void TransformPoint( IDF_SEGMENT& seg, double frac, bool bottom,
double dX, double dY, double angle )
{
dX *= frac;
dY *= frac;
if( bottom )
{
// mirror points on the Y axis
seg.startPoint.x = -seg.startPoint.x;
seg.endPoint.x = -seg.endPoint.x;
seg.center.x = -seg.center.x;
angle = -angle;
}
seg.startPoint.x *= frac;
seg.startPoint.y *= frac;
seg.endPoint.x *= frac;
seg.endPoint.y *= frac;
seg.center.x *= frac;
seg.center.y *= frac;
double tsin = 0.0;
double tcos = 0.0;
if( angle > MIN_ANG || angle < -MIN_ANG )
{
double ta = angle * M_PI / 180.0;
double tx, ty;
tsin = sin( ta );
tcos = cos( ta );
tx = seg.startPoint.x * tcos - seg.startPoint.y * tsin;
ty = seg.startPoint.x * tsin + seg.startPoint.y * tcos;
seg.startPoint.x = tx;
seg.startPoint.y = ty;
tx = seg.endPoint.x * tcos - seg.endPoint.y * tsin;
ty = seg.endPoint.x * tsin + seg.endPoint.y * tcos;
seg.endPoint.x = tx;
seg.endPoint.y = ty;
if( seg.angle != 0 )
{
tx = seg.center.x * tcos - seg.center.y * tsin;
ty = seg.center.x * tsin + seg.center.y * tcos;
seg.center.x = tx;
seg.center.y = ty;
}
}
seg.startPoint.x += dX;
seg.startPoint.y += dY;
seg.endPoint.x += dX;
seg.endPoint.y += dY;
seg.center.x += dX;
seg.center.y += dY;
if( seg.angle != 0 )
{
seg.radius *= frac;
if( bottom )
{
if( !seg.IsCircle() )
{
seg.angle = -seg.angle;
if( seg.offsetAngle > 0.0 )
seg.offsetAngle = 180 - seg.offsetAngle;
else
seg.offsetAngle = -seg.offsetAngle - 180;
}
}
if( angle > MIN_ANG || angle < -MIN_ANG )
seg.offsetAngle += angle;
}
return;
}
bool MakeComponents( IDF3_BOARD& board, std::ofstream& file, bool compact )
{
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, IDF3_COMPONENT* >*const comp = board.GetComponents();
std::map< std::string, IDF3_COMPONENT* >::const_iterator sc = comp->begin();
std::map< std::string, IDF3_COMPONENT* >::const_iterator ec = comp->end();
std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator so;
std::list< IDF3_COMP_OUTLINE_DATA* >::const_iterator eo;
double vX, vY, vA;
double tX, tY, tZ, tA;
double top, bot;
bool bottom;
IDF3::IDF_LAYER lyr;
std::map< std::string, VRML_IDS*> cmap; // map colors by outline UID
VRML_IDS* vcp;
while( sc != ec )
{
sc->second->GetPosition( vX, vY, vA, lyr );
if( lyr == IDF3::LYR_BOTTOM )
bottom = true;
else
bottom = false;
so = sc->second->GetOutlinesData()->begin();
eo = sc->second->GetOutlinesData()->end();
while( so != eo )
{
(*so)->GetOffsets( tX, tY, tZ, tA );
tX += vX;
tY += vY;
tA += vA;
vcp = GetColor( cmap, cidx, ((IDF3_COMP_OUTLINE*)((*so)->GetOutline()))->GetUID() );
if( !compact )
{
if( !PopulateVRML( vpcb, (*so)->GetOutline()->GetOutlines(), bottom,
board.GetUserScale(), tX, tY, tA ) )
{
return false;
}
}
else
{
if( !vcp->used && !PopulateVRML( vpcb, (*so)->GetOutline()->GetOutlines(), false,
board.GetUserScale() ) )
{
return false;
}
vcp->dX = tX * scale;
vcp->dY = tY * scale;
vcp->dZ = tZ * scale;
vcp->dA = tA * M_PI / 180.0;
}
if( !compact || !vcp->used )
{
vpcb.EnsureWinding( 0, false );
vpcb.Tesselate( NULL );
}
if( !compact )
{
if( bottom )
{
top = -thick - tZ;
bot = (top - (*so)->GetOutline()->GetThickness() ) * scale;
top *= scale;
}
else
{
bot = thick + tZ;
top = (bot + (*so)->GetOutline()->GetThickness() ) * scale;
bot *= scale;
}
}
else
{
bot = thick;
top = (bot + (*so)->GetOutline()->GetThickness() ) * scale;
bot *= scale;
}
vcp = GetColor( cmap, cidx, ((IDF3_COMP_OUTLINE*)((*so)->GetOutline()))->GetUID() );
vcp->bottom = bottom;
WriteTriangles( file, vcp, &vpcb, false,
false, top, bot, board.GetUserPrecision(), compact );
vpcb.Clear();
++so;
}
++sc;
}
return true;
}
VRML_IDS* GetColor( std::map<std::string, VRML_IDS*>& cmap, int& index, const std::string& uid )
{
static int refnum = 0;
if( index < 2 )
index = 2; // 0 and 1 are special (BOARD, UID=NOGEOM_NOPART)
std::map<std::string, VRML_IDS*>::iterator cit = cmap.find( uid );
if( cit == cmap.end() )
{
VRML_IDS* id = new VRML_IDS;
if( !uid.compare( "NOGEOM_NOPART" ) )
id->colorIndex = 1;
else
id->colorIndex = index++;
std::ostringstream ostr;
ostr << "OBJECTn" << refnum++;
id->objectName = ostr.str();
cout << "* " << ostr.str() << " = '" << uid << "'\n";
cmap.insert( std::pair<std::string, VRML_IDS*>(uid, id) );
if( index >= NCOLORS )
index = 2;
return id;
}
return cit->second;
}

File diff suppressed because it is too large Load Diff

705
utils/idftools/idf_common.h Normal file
View File

@ -0,0 +1,705 @@
/**
* @file idf_common.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef IDF_COMMON_H
#define IDF_COMMON_H
#include <list>
#include <fstream>
#include <exception>
#include <string>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841
#endif
#ifndef M_PI2
#define M_PI2 ( M_PI / 2.0 )
#endif
#ifndef M_PI4
#define M_PI4 ( M_PI / 4.0 )
#endif
// differences in angle smaller than MIN_ANG are considered equal
#define MIN_ANG (0.01)
class IDF_POINT;
class IDF_SEGMENT;
class IDF_DRILL_DATA;
class IDF_OUTLINE;
class IDF_LIB;
struct IDF_ERROR : std::exception
{
std::string message;
IDF_ERROR( const char* aSourceFile,
const char* aSourceMethod,
int aSourceLine,
const std::string& aMessage ) throw();
virtual ~IDF_ERROR() throw();
virtual const char* what() const throw();
};
namespace IDF3 {
/**
* ENUM FILE_STATE
* represents state values for the IDF parser's input
*/
enum FILE_STATE
{
FILE_START = 0, // no data has been read; expecting .HEADER
FILE_HEADER, // header has been read; expecting .BOARD_OUTLINE
FILE_OUTLINE, // board outline has been read; most sections can be accepted
FILE_PLACEMENT, // placement has been read; no further sections can be accepted
FILE_INVALID, // file is invalid
FILE_ERROR // other errors while processing the file
};
/**
* ENUM KEY_OWNER
* represents the type of CAD which has ownership an object
*/
enum KEY_OWNER
{
UNOWNED = 0, //< either MCAD or ECAD may modify a feature
MCAD, //< only MCAD may modify a feature
ECAD //< only ECAD may modify a feature
};
/**
* ENUM KEY_HOLETYPE
* represents the purpose of an IDF hole
*/
enum KEY_HOLETYPE
{
PIN = 0, //< drill hole is for a pin
VIA, //< drill hole is for a via
MTG, //< drill hole is for mounting
TOOL, //< drill hole is for tooling
OTHER //< user has specified a custom type
};
/**
* ENUM KEY_PLATING
* represents the plating condition of a hole
*/
enum KEY_PLATING
{
PTH = 0, //< Plate-Through Hole
NPTH //< Non-Plate-Through Hole
};
/**
* ENUM KEY_REFDES
* represents a component's Reference Designator
*/
enum KEY_REFDES
{
BOARD = 0, //< feature is associated with the board
NOREFDES, //< feature is associated with a component with no RefDes
PANEL, //< feature is associated with an IDF panel
REFDES //< reference designator as assigned by the CAD software
};
/**
* ENUM CAD_TYPE
* represents the class of CAD program which is opening or modifying a file
*/
enum CAD_TYPE
{
CAD_ELEC = 0, //< An Electrical CAD is opening/modifying the file
CAD_MECH, //< A Mechanical CAD is opening/modifying the file
CAD_INVALID
};
/**
* ENUM IDF_LAYER
* represents the various IDF layer classes and groupings
*/
enum IDF_LAYER
{
LYR_TOP = 0,
LYR_BOTTOM,
LYR_BOTH,
LYR_INNER,
LYR_ALL,
LYR_INVALID
};
/**
* ENUM OUTLINE_TYPE
* identifies the class of outline
*/
enum OUTLINE_TYPE
{
OTLN_BOARD = 0,
OTLN_OTHER,
OTLN_PLACE,
OTLN_ROUTE,
OTLN_PLACE_KEEPOUT,
OTLN_ROUTE_KEEPOUT,
OTLN_VIA_KEEPOUT,
OTLN_GROUP_PLACE,
OTLN_COMPONENT,
OTLN_INVALID
};
/**
* ENUM COMP_TYPE
* identifies whether a component is a mechanical or electrical part
*/
enum COMP_TYPE
{
COMP_ELEC = 0, //< Component library object is an electrical part
COMP_MECH, //< Component library object is a mechanical part
COMP_INVALID
};
/**
* ENUM IDF_UNIT
* represents the native unit of the board and of component outlines
*/
enum IDF_UNIT
{
UNIT_MM = 0, //< Units in the file are in millimeters
UNIT_THOU, //< Units in the file are in mils (aka thou)
UNIT_INVALID
};
/**
* ENUM IDF_PLACEMENT
* represents the placement status of a component
*/
enum IDF_PLACEMENT
{
PS_UNPLACED = 0, //< component location on the board has not been specified
PS_PLACED, //< component location has been specified and may be modified by ECAD or MCAD
PS_MCAD, //< component location has been specified and may only be modified by MCAD
PS_ECAD, //< component location has been specified and may only be modified by ECAD
PS_INVALID
};
/**
* Function CalcAngleRad
* calculates the angle (radians) between the horizon and the segment aStartPoint to aEndPoint
*
* @param aStartPoint is the start point of a line segment
* @param aEndPoint is the end point of a line segment
*
* @return double: the angle in radians
*/
double CalcAngleRad( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
/**
* Function CalcAngleDeg
* calculates the angle (degrees) between the horizon and the segment aStartPoint to aEndPoint
*
* @param aStartPoint is the start point of a line segment
* @param aEndPoint is the end point of a line segment
*
* @return double: the angle in degrees
*/
double CalcAngleDeg( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
/**
* Function GetOutline
* takes contiguous elements from 'aLines' and stuffs them into 'aOutline'; elements put
* into the outline are deleted from aLines. This function is useful for sorting the jumbled
* mess of line segments and arcs which represent a board outline and cutouts in KiCad.
* The function will determine which segment element within aLines contains the leftmost
* point and retrieve the outline of which that segment is part.
*
* @param aLines (input/output) is a list of IDF segments which comprise an outline and
* cutouts.
* @param aOutline (output) is the ordered set of segments
*/
void GetOutline( std::list<IDF_SEGMENT*>& aLines,
IDF_OUTLINE& aOutline );
#ifdef DEBUG_IDF
// prints out segment information for debug purposes
void PrintSeg( IDF_SEGMENT* aSegment );
#endif
}
/**
* Class IDF_NOTE
* represents an entry in the NOTE section of an IDF file
*/
class IDF_NOTE
{
private:
std::string text; // note text as per IDFv3
double xpos; // text X position as per IDFv3
double ypos; // text Y position as per IDFv3
double height; // text height as per IDFv3
double length; // text length as per IDFv3
public:
IDF_NOTE();
/**
* 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
* @param aBoardState is the parser's current state value
* @param aBoardUnit is the BOARD file's native units (MM or THOU)
*
* @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 );
/**
* 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
* @param aBoardUnit is the BOARD file's native units (MM or THOU)
*
* @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 );
/**
* Function SetText
* sets the text to be stored as a NOTE entry
*/
void SetText( const std::string& aText );
/**
* Function SetPosition
* sets the position (mm) of the NOTE entry
*/
void SetPosition( double aXpos, double aYpos );
/**
* Function SetSize
* sets the height and length (mm) of the NOTE entry
*/
void SetSize( double aHeight, double aLength );
/**
* Function GetText
* returns the string stored in the note entry
*/
const std::string& GetText( void );
/**
* Function GetText
* returns the position (mm) of the note entry
*/
void GetPosition( double& aXpos, double& aYpos );
/**
* Function GetText
* returns the height and length (mm) of the note entry
*/
void GetSize( double& aHeight, double& aLength );
};
/**
* @Class IDF_DRILL_DATA
* contains information describing a drilled hole and is responsible for
* writing this information to a file in compliance with the IDFv3 specification.
*/
class IDF_DRILL_DATA
{
private:
double dia;
double x;
double y;
IDF3::KEY_PLATING plating;
IDF3::KEY_REFDES kref;
IDF3::KEY_HOLETYPE khole;
std::string refdes;
std::string holetype;
IDF3::KEY_OWNER owner;
public:
/**
* Constructor IDF_DRILL_DATA
* creates an empty drill entry which can be populated by the
* Read() function
*/
IDF_DRILL_DATA();
/**
* Constructor IDF_DRILL_DATA
* creates a drill entry with information compliant with the
* IDFv3 specifications.
* @param aDrillDia : drill diameter
* @param aPosX : X coordinate of the drill center
* @param aPosY : Y coordinate of the drill center
* @param aPlating : flag, PTH or NPTH
* @param aRefDes : component Reference Designator
* @param aHoleType : purpose of hole
* @param aOwner : one of MCAD, ECAD, UNOWNED
*/
IDF_DRILL_DATA( double aDrillDia, double aPosX, double aPosY,
IDF3::KEY_PLATING aPlating,
const std::string aRefDes,
const std::string aHoleType,
IDF3::KEY_OWNER aOwner );
/**
* Function Matches
* returns true if the given drill diameter and location
* matches the diameter and location of this IDF_DRILL_DATA object
*
* @param aDrillDia is the drill diameter (mm)
* @param aPosX is the X position (mm) of the drilled hole
* @param aPosY is the Y position (mm) of the drilled hole
*
* @return bool: true if the diameter and position match this object
*/
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
*/
double GetDrillXPos();
/**
* Function GettDrillYPos
* returns the drill's Y position in mm
*/
double GetDrillYPos();
/**
* Function GetDrillPlating
* returns the plating value (PTH, NPTH)
*/
IDF3::KEY_PLATING GetDrillPlating();
/**
* Function GetDrillRefDes
* returns the reference designator of the hole; this
* may be a component reference designator, BOARD, or
* NOREFDES as per IDFv3.
*/
const std::string& GetDrillRefDes();
/**
* Function GetDrillHoleType
* returns the classification of the hole; this may be one of
* PIN, VIA, MTG, TOOL, or a user-specified string
*/
const std::string& GetDrillHoleType();
};
/**
* @Class IDF_POINT
* represents a point as used by the various IDF related classes
*/
class IDF_POINT
{
public:
double x; // < X coordinate
double y; // < Y coordinate
IDF_POINT()
{
x = 0.0;
y = 0.0;
}
/**
* Function Matches()
* returns true if the given coordinate point is within the given radius
* of the point.
*
* @param aPoint : coordinates of the point being compared
* @param aRadius : radius (mm) within which the points are considered the same
*
* @return bool: true if this point matches the given point
*/
bool Matches( const IDF_POINT& aPoint, double aRadius = 1e-5 );
/**
* Function CalcDistance()
* returns the Euclidean distance between this point and the given point
*
* @param aPoint : coordinates of the point whose distance is to be determined
*
* @return double: distance between this point and aPoint
*/
double CalcDistance( const IDF_POINT& aPoint ) const;
};
/**
* @Class IDF_SEGMENT
* represents a geometry segment as used in IDFv3 outlines; it may be any of
* an arc, line segment, or circle
*/
class IDF_SEGMENT
{
private:
/**
* Function CalcCenterAndRadius()
* Calculates the center, radius, and angle between center and start point given the
* IDF compliant points and included angle.
*
* @var startPoint, @var endPoint, and @var angle must be set prior as per IDFv3
*/
void CalcCenterAndRadius( void );
public:
IDF_POINT startPoint; ///< starting point coordinates in mm
IDF_POINT endPoint; ///< end point coordinates in mm
IDF_POINT center; ///< center of an arc or circle; internally calculated and not to be set by the user
double angle; ///< included angle (degrees) according to IDFv3 specification
double offsetAngle; ///< angle between center and start of arc; internally calculated
double radius; ///< radius of the arc or circle; internally calculated
/**
* Constructor IDF_SEGMENT
* initializes the internal variables
*/
IDF_SEGMENT();
/**
* Function IDF_SEGMENT
* creates a straight segment
*/
IDF_SEGMENT( const IDF_POINT& aStartPoint, const IDF_POINT& aEndPoint );
/**
* Constructor IDF_SEGMENT
* creates a straight segment, arc, or circle depending on the angle
*
* @param aStartPoint : start point (center if using KiCad convention, otherwise IDF convention)
* @param aEndPoint : end point (start of arc if using KiCad convention, otherwise IDF convention)
* @param aAngle : included angle; the KiCad convention is equivalent to the IDF convention
* @param fromKicad : set true if we need to convert from KiCad to IDF convention
*/
IDF_SEGMENT( const IDF_POINT& aStartPoint,
const IDF_POINT& aEndPoint,
double aAngle,
bool aFromKicad );
/**
* Function MatchesStart
* returns true if the given coordinate is within a radius 'rad'
* of the start point.
*
* @param aPoint : coordinates of the point (mm) being compared
* @param aRadius : radius (mm) within which the points are considered the same
*
* @return bool: true if the given point matches the start point of this segment
*/
bool MatchesStart( const IDF_POINT& aPoint, double aRadius = 1e-3 );
/**
* Function MatchesEnd
* returns true if the given coordinate is within a radius 'rad'
* of the end point.
*
* @param aPoint : coordinates (mm) of the point being compared
* @param aRadius : radius (mm) within which the points are considered the same
*
* @return bool: true if the given point matches the end point of this segment
*/
bool MatchesEnd( const IDF_POINT& aPoint, double aRadius = 1e-3 );
/**
* Function IsCircle
* returns true if this segment is a circle
*/
bool IsCircle( void );
/**
* Function GetMinX()
* returns the minimum X coordinate of this segment
*/
double GetMinX( void );
/**
* Function SwapEnds()
* Swaps the start and end points and alters internal
* variables as necessary for arcs
*/
void SwapEnds( void );
};
/**
* @Class IDF_OUTLINE
* contains segment and winding information for an IDF outline
*/
class IDF_OUTLINE
{
private:
double dir; // accumulator to help determine winding direction
std::list<IDF_SEGMENT*> outline; // sequential segments comprising an outline
public:
IDF_OUTLINE() { dir = 0.0; }
~IDF_OUTLINE() { Clear(); }
/**
* Function IsCCW
* returns true if the current list of points represents a counterclockwise winding
*/
bool IsCCW( void );
/**
* Function IsCircle
* returns true if this outline is a circle
*/
bool IsCircle( void );
/**
* Function Clear
* clears the internal list of outline segments
*/
void Clear( void )
{
dir = 0.0;
while( !outline.empty() )
{
delete outline.front();
outline.pop_front();
}
}
/**
* Function size
* returns the size of the internal segment list
*/
size_t size( void )
{
return outline.size();
}
/**
* Function empty
* returns true if the internal segment list is empty
*/
bool empty( void )
{
return outline.empty();
}
/**
* Function front
* returns the front() iterator of the internal segment list
*/
IDF_SEGMENT*& front( void )
{
return outline.front();
}
/**
* Function back
* returns the back() iterator of the internal segment list
*/
IDF_SEGMENT*& back( void )
{
return outline.back();
}
/**
* Function begin
* returns the begin() iterator of the internal segment list
*/
std::list<IDF_SEGMENT*>::iterator begin( void )
{
return outline.begin();
}
/**
* Function end
* returns the end() iterator of the internal segment list
*/
std::list<IDF_SEGMENT*>::iterator end( void )
{
return outline.end();
}
/**
* Function push
* adds a segment to the internal segment list; segments must be added
* in order so that startPoint[N] == endPoint[N - 1]
*
* @param item is a pointer to the segment to add to the outline
*
* @return bool: true if the segment was added, otherwise false
* (outline restrictions have been violated)
*/
bool push( IDF_SEGMENT* item );
};
#endif // IDF_COMMON_H

View File

@ -149,7 +149,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> dia) && dia > 0.0 )
tstr >> dia;
if( !tstr.fail() && dia > 0.0 )
ok = true;
}
@ -163,7 +165,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> length) && length > 0.0 )
tstr >> length;
if( !tstr.fail() && length > 0.0 )
ok = true;
}
@ -177,7 +181,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> extraZ) && extraZ >= 0.0 )
tstr >> extraZ;
if( !tstr.fail() && extraZ >= 0.0 )
ok = true;
}
@ -191,7 +197,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> wireDia) && wireDia > 0.0 )
tstr >> wireDia;
if( !tstr.fail() && wireDia > 0.0 )
{
if( wireDia < dia )
ok = true;
@ -236,7 +244,9 @@ void make_vcyl( bool inch, bool axial, double dia, double length,
tstr.clear();
tstr.str( line );
if( (tstr >> pitch) && pitch > 0.0 )
tstr >> pitch;
if( !tstr.fail() && pitch > 0.0 )
{
if( (pitch - wireDia) <= (dia / 2.0) )
{
@ -436,7 +446,9 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
tstr.clear();
tstr.str( line );
if( (tstr >> pitch) && pitch > 0.0 )
tstr >> pitch;
if( !tstr.fail() && pitch > 0.0 )
{
if( axial )
{
@ -477,7 +489,9 @@ void make_hcyl( bool inch, bool axial, double dia, double length,
tstr.clear();
tstr.str( line );
if( (tstr >> lead) && lead > 0.0 )
tstr >> lead;
if( !tstr.fail() && lead > 0.0 )
{
if( lead < wireDia )
cout << "* WARNING: lead length must be >= wireDia\n";

View File

@ -0,0 +1,149 @@
.HEADER
BOARD_FILE 3.0 "Created by KiCad (2014-01-21 BZR 4629)-product" 2014/01/23.09:19:46 1
"Arduino_MEGA_2560-Rev3.kicad_pcb" MM
.END_HEADER
.BOARD_OUTLINE ECAD
1.60000
0 246.20220 -25.67000 0
0 247.20220 -26.67000 0
0 344.26220 -26.67000 0
0 345.26220 -25.67000 0
0 345.26220 -25.40000 0
0 347.80220 -22.86000 0
0 347.80220 11.43000 0
0 345.26220 13.97000 0
0 345.26220 24.13000 0
0 342.72220 26.67000 0
0 247.20220 26.67000 0
0 246.20220 25.67000 0
0 246.20220 -25.67000 0
.END_BOARD_OUTLINE
.DRILLED_HOLES
3.200 342.72220 -24.13000 NPTH "@HOLE0" MTG ECAD
3.200 261.44220 24.13000 NPTH "@HOLE1" MTG ECAD
3.200 336.37220 24.13000 NPTH "@HOLE2" MTG ECAD
3.200 260.17220 -24.13000 NPTH "@HOLE3" MTG ECAD
3.200 312.24220 8.89000 NPTH "@HOLE4" MTG ECAD
3.200 312.24220 -19.05000 NPTH "@HOLE5" MTG ECAD
0.950 309.82920 3.81000 PTH "ICSP" PIN ECAD
0.950 312.36920 3.81000 PTH "ICSP" PIN ECAD
0.950 309.82920 1.27000 PTH "ICSP" PIN ECAD
0.950 312.36920 1.27000 PTH "ICSP" PIN ECAD
0.950 309.82920 -1.27000 PTH "ICSP" PIN ECAD
0.950 312.36920 -1.27000 PTH "ICSP" PIN ECAD
0.850 309.70220 24.13000 PTH "PWML" PIN ECAD
0.850 307.16220 24.13000 PTH "PWML" PIN ECAD
0.850 304.62220 24.13000 PTH "PWML" PIN ECAD
0.850 302.08220 24.13000 PTH "PWML" PIN ECAD
0.850 299.54220 24.13000 PTH "PWML" PIN ECAD
0.850 297.00220 24.13000 PTH "PWML" PIN ECAD
0.850 294.46220 24.13000 PTH "PWML" PIN ECAD
0.850 291.92220 24.13000 PTH "PWML" PIN ECAD
1.400 254.88900 -23.36800 PTH "X1" PIN ECAD
1.400 257.88620 -18.36420 PTH "X1" PIN ECAD
1.400 251.89180 -18.36420 PTH "X1" PIN ECAD
1.400 255.65100 -23.36800 PTH "X1" PIN ECAD
1.400 254.12700 -23.36800 PTH "X1" PIN ECAD
1.400 251.89180 -19.12620 PTH "X1" PIN ECAD
1.400 251.89180 -17.60220 PTH "X1" PIN ECAD
1.400 257.88620 -19.12620 PTH "X1" PIN ECAD
1.400 257.88620 -17.60220 PTH "X1" PIN ECAD
0.850 297.00220 -24.13000 PTH "ADCL" PIN ECAD
0.850 299.54220 -24.13000 PTH "ADCL" PIN ECAD
0.850 302.08220 -24.13000 PTH "ADCL" PIN ECAD
0.850 304.62220 -24.13000 PTH "ADCL" PIN ECAD
0.850 307.16220 -24.13000 PTH "ADCL" PIN ECAD
0.850 309.70220 -24.13000 PTH "ADCL" PIN ECAD
0.850 312.24220 -24.13000 PTH "ADCL" PIN ECAD
0.850 314.78220 -24.13000 PTH "ADCL" PIN ECAD
0.850 332.56220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 330.02220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 327.48220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 324.94220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 322.40220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 319.86220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 317.32220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 314.78220 24.13000 PTH "COMMUNICATION" PIN ECAD
0.850 319.86220 -24.13000 PTH "ADCH" PIN ECAD
0.850 322.40220 -24.13000 PTH "ADCH" PIN ECAD
0.850 324.94220 -24.13000 PTH "ADCH" PIN ECAD
0.850 327.48220 -24.13000 PTH "ADCH" PIN ECAD
0.850 330.02220 -24.13000 PTH "ADCH" PIN ECAD
0.850 332.56220 -24.13000 PTH "ADCH" PIN ECAD
0.850 335.10220 -24.13000 PTH "ADCH" PIN ECAD
0.850 337.64220 -24.13000 PTH "ADCH" PIN ECAD
0.950 254.72220 10.18000 PTH "X2" PIN ECAD
0.950 254.72220 12.68000 PTH "X2" PIN ECAD
0.950 252.72220 12.68000 PTH "X2" PIN ECAD
0.950 252.72220 10.18000 PTH "X2" PIN ECAD
2.200 250.01220 17.43000 PTH "X2" PIN ECAD
2.200 250.01220 5.43000 PTH "X2" PIN ECAD
0.950 267.03020 20.82800 PTH "ICSP1" PIN ECAD
0.950 267.03020 18.28800 PTH "ICSP1" PIN ECAD
0.950 264.49020 20.82800 PTH "ICSP1" PIN ECAD
0.950 264.49020 18.28800 PTH "ICSP1" PIN ECAD
0.950 261.95020 20.82800 PTH "ICSP1" PIN ECAD
0.950 261.95020 18.28800 PTH "ICSP1" PIN ECAD
0.850 267.15720 -0.63500 PTH "Y2" PIN ECAD
0.850 262.07720 -0.63500 PTH "Y2" PIN ECAD
0.950 267.03020 13.20800 PTH "JP5" PIN ECAD
0.950 264.49020 13.20800 PTH "JP5" PIN ECAD
0.950 267.03020 15.74800 PTH "JP5" PIN ECAD
0.950 264.49020 15.74800 PTH "JP5" PIN ECAD
0.950 340.18220 24.13000 PTH "XIO" PIN ECAD
0.950 342.72220 24.13000 PTH "XIO" PIN ECAD
0.950 340.18220 21.59000 PTH "XIO" PIN ECAD
0.950 342.72220 21.59000 PTH "XIO" PIN ECAD
0.950 340.18220 19.05000 PTH "XIO" PIN ECAD
0.950 342.72220 19.05000 PTH "XIO" PIN ECAD
0.950 340.18220 16.51000 PTH "XIO" PIN ECAD
0.950 342.72220 16.51000 PTH "XIO" PIN ECAD
0.950 340.18220 13.97000 PTH "XIO" PIN ECAD
0.950 342.72220 13.97000 PTH "XIO" PIN ECAD
0.950 340.18220 11.43000 PTH "XIO" PIN ECAD
0.950 342.72220 11.43000 PTH "XIO" PIN ECAD
0.950 340.18220 8.89000 PTH "XIO" PIN ECAD
0.950 342.72220 8.89000 PTH "XIO" PIN ECAD
0.950 340.18220 6.35000 PTH "XIO" PIN ECAD
0.950 342.72220 6.35000 PTH "XIO" PIN ECAD
0.950 340.18220 3.81000 PTH "XIO" PIN ECAD
0.950 342.72220 3.81000 PTH "XIO" PIN ECAD
0.950 340.18220 1.27000 PTH "XIO" PIN ECAD
0.950 342.72220 1.27000 PTH "XIO" PIN ECAD
0.950 340.18220 -1.27000 PTH "XIO" PIN ECAD
0.950 342.72220 -1.27000 PTH "XIO" PIN ECAD
0.950 340.18220 -3.81000 PTH "XIO" PIN ECAD
0.950 342.72220 -3.81000 PTH "XIO" PIN ECAD
0.950 340.18220 -6.35000 PTH "XIO" PIN ECAD
0.950 342.72220 -6.35000 PTH "XIO" PIN ECAD
0.950 340.18220 -8.89000 PTH "XIO" PIN ECAD
0.950 342.72220 -8.89000 PTH "XIO" PIN ECAD
0.950 340.18220 -11.43000 PTH "XIO" PIN ECAD
0.950 342.72220 -11.43000 PTH "XIO" PIN ECAD
0.950 340.18220 -13.97000 PTH "XIO" PIN ECAD
0.950 342.72220 -13.97000 PTH "XIO" PIN ECAD
0.950 340.18220 -16.51000 PTH "XIO" PIN ECAD
0.950 342.72220 -16.51000 PTH "XIO" PIN ECAD
0.950 340.18220 -19.05000 PTH "XIO" PIN ECAD
0.950 342.72220 -19.05000 PTH "XIO" PIN ECAD
0.850 264.99820 24.13000 PTH "JP6" PIN ECAD
0.850 267.53820 24.13000 PTH "JP6" PIN ECAD
0.850 270.07820 24.13000 PTH "JP6" PIN ECAD
0.850 272.61820 24.13000 PTH "JP6" PIN ECAD
0.850 275.15820 24.13000 PTH "JP6" PIN ECAD
0.850 277.69820 24.13000 PTH "JP6" PIN ECAD
0.850 280.23820 24.13000 PTH "JP6" PIN ECAD
0.850 282.77820 24.13000 PTH "JP6" PIN ECAD
0.850 285.31820 24.13000 PTH "JP6" PIN ECAD
0.850 287.85820 24.13000 PTH "JP6" PIN ECAD
0.850 274.14220 -24.13000 PTH "POWER" PIN ECAD
0.850 276.68220 -24.13000 PTH "POWER" PIN ECAD
0.850 279.22220 -24.13000 PTH "POWER" PIN ECAD
0.850 281.76220 -24.13000 PTH "POWER" PIN ECAD
0.850 284.30220 -24.13000 PTH "POWER" PIN ECAD
0.850 286.84220 -24.13000 PTH "POWER" PIN ECAD
0.850 289.38220 -24.13000 PTH "POWER" PIN ECAD
0.850 291.92220 -24.13000 PTH "POWER" PIN ECAD
.END_DRILLED_HOLES

View File

@ -0,0 +1,4 @@
.HEADER
LIBRARY_FILE 3.0 "Created by KiCad (2014-01-21 BZR 4629)-product" 2014/01/23.09:19:46 1
.END_HEADER

View File

@ -0,0 +1,269 @@
.HEADER
BOARD_FILE 3.0 "Sample File Generator" 10/22/96.16:02:44 1
sample_board THOU
.END_HEADER
# This is the first BOARD section
# SEC1-0
# SEC1-1
.BOARD_OUTLINE MCAD
62.0
0 5030.5 -120.0 0.0
0 5187.5 -120.0 0.0
0 5187.5 2130.0 0.0
0 5155.0 2130.0 0.0
0 5155.0 2550.0 -180.0
0 5187.5 2550.0 0.0
0 5187.5 4935.0 0.0
0 4945.0 5145.0 0.0
0 4945.0 5420.0 0.0
0 4865.0 5500.0 0.0
0 210.0 5500.0 0.0
0 130.0 5420.0 0.0
0 130.0 5145.0 0.0
0 -112.5 4935.0 0.0
0 -112.5 2550.0 0.0
0 -80.0 2550.0 0.0
0 -80.0 2130.0 -180.0
0 -112.5 2130.0 0.0
0 -112.5 -140.0 0.0
0 45.5 -140.0 0.0
0 45.5 -400.0 0.0
0 2442.5 -400.0 0.0
0 2442.5 -140.0 0.0
0 2631.5 -140.0 0.0
0 2631.5 -400.0 0.0
0 5030.5 -400.0 0.0
0 5030.5 -120.0 0.0
1 2650.0 2350.0 0.0
1 3000.0 2350.0 360.0
.END_BOARD_OUTLINE
# This is the second BOARD section
# SEC2-0
# SEC2-1
# NOT SEC1-1
.ROUTE_OUTLINE ECAD
ALL
0 5112.5 150.0 0.0
0 5112.5 2058.2 0.0
0 5112.5 2621.8 -162.9
0 5112.5 4863.2 0.0
0 4878.8 5075.0 0.0
0 226.4 5075.0 0.0
0 138.0 4910.3 0.0
0 138.0 4800.0 0.0
0 -37.5 4662.5 0.0
0 -37.5 2621.8 0.0
0 -37.5 2058.2 -162.9
0 -37.5 150.0 0.0
0 162.5 0.0 0.0
0 4912.5 0.0 0.0
0 5112.5 150.0 0.0
.END_ROUTE_OUTLINE
# This is the third BOARD section
# SEC3-0
# SEC3-1
.PLACE_OUTLINE MCAD
TOP 1000.0
0 5080.0 2034.9 0.0
0 5080.0 2645.1 -152.9
0 5080.0 4837.3 0.0
0 4855.3 5042.5 0.0
0 252.9 5042.5 0.0
0 170.5 4896.9 0.0
0 170.5 4798.4 0.0
0 -5.0 4659.0 0.0
0 -5.0 2645.1 0.0
0 -5.0 2034.9 -152.9
0 -5.0 182.5 0.0
0 192.0 32.5 0.0
0 4883.1 32.5 0.0
0 5080.0 182.5 0.0
0 5080.0 2034.9 0.0
.END_PLACE_OUTLINE
# This is the fourth BOARD section
# SEC4-0
# SEC4-1
.PLACE_OUTLINE UNOWNED
BOTTOM 200.0
0 300.0 200.0 0.0
0 4800.0 200.0 0.0
0 4800.0 4800.0 0.0
0 300.0 4800.0 0.0
0 300.0 200.0 0.0
.END_PLACE_OUTLINE
# This is the fifth BOARD section
# SEC5-0
# SEC5-1
.ROUTE_KEEPOUT ECAD
ALL
0 2650.0 2350.0 0.0
0 3100.0 2350.0 360.0
.END_ROUTE_KEEPOUT
# This is the sixth BOARD section
# SEC6-0
# SEC6-1
.PLACE_KEEPOUT MCAD
BOTH 0.0
0 2650.0 2350.0 0.0
0 3100.0 2350.0 360.0
.END_PLACE_KEEPOUT
# This is the seventh BOARD section
# SEC7-0
# SEC7-1
.PLACE_KEEPOUT MCAD
TOP 300.0
0 3700.0 5000.0 0.0
0 3700.0 4300.0 0.0
0 4000.0 4300.0 0.0
0 4000.0 3700.0 0.0
0 5000.0 3700.0 0.0
0 5000.0 4800.0 0.0
0 4800.0 5000.0 0.0
0 3700.0 5000.0 0.0
.END_PLACE_KEEPOUT
# This is the eighth BOARD section
# SEC8-0
# SEC8-1
.DRILLED_HOLES
30.0 1800.0 100.0 PTH J1 PIN ECAD
30.0 1700.0 100.0 PTH J1 PIN ECAD
30.0 1600.0 100.0 PTH J1 PIN ECAD
30.0 1500.0 100.0 PTH J1 PIN ECAD
30.0 1400.0 100.0 PTH J1 PIN ECAD
30.0 1300.0 100.0 PTH J1 PIN ECAD
30.0 1200.0 100.0 PTH J1 PIN ECAD
30.0 1100.0 100.0 PTH J1 PIN ECAD
30.0 1000.0 100.0 PTH J1 PIN ECAD
30.0 0900.0 100.0 PTH J1 PIN ECAD
30.0 0800.0 100.0 PTH J1 PIN ECAD
30.0 0700.0 100.0 PTH J1 PIN ECAD
30.0 0700.0 200.0 PTH J1 PIN ECAD
30.0 0800.0 200.0 PTH J1 PIN ECAD
30.0 0900.0 200.0 PTH J1 PIN ECAD
30.0 1000.0 200.0 PTH J1 PIN ECAD
30.0 1100.0 200.0 PTH J1 PIN ECAD
30.0 1200.0 200.0 PTH J1 PIN ECAD
30.0 1300.0 200.0 PTH J1 PIN ECAD
30.0 1400.0 200.0 PTH J1 PIN ECAD
30.0 1500.0 200.0 PTH J1 PIN ECAD
30 1600 200 PTH J1 PIN ECAD
30 1700 200 PTH J1 PIN ECAD
30 1800 200 PTH J1 PIN ECAD
30 4400 100 PTH J2 PIN ECAD
30 4300 100 PTH J2 PIN ECAD
30 4200 100 PTH J2 PIN ECAD
30 4100 100 PTH J2 PIN ECAD
30 4000 100 PTH J2 PIN ECAD
30 3900 100 PTH J2 PIN ECAD
30 3800 100 PTH J2 PIN ECAD
30 3700 100 PTH J2 PIN ECAD
30 3600 100 PTH J2 PIN ECAD
30 3500 100 PTH J2 PIN ECAD
30 3400 100 PTH J2 PIN ECAD
30 3300 100 PTH J2 PIN ECAD
30 3300 200 PTH J2 PIN ECAD
30 3400 200 PTH J2 PIN ECAD
30 3500 200 PTH J2 PIN ECAD
30 3600 200 PTH J2 PIN ECAD
30 3700 200 PTH J2 PIN ECAD
30 3800 200 PTH J2 PIN ECAD
30 3900 200 PTH J2 PIN ECAD
30 4000 200 PTH J2 PIN ECAD
30 4100 200 PTH J2 PIN ECAD
30 4200 200 PTH J2 PIN ECAD
30 4300 200 PTH J2 PIN ECAD
30 4400 200 PTH J2 PIN ECAD
30 3000 3300 PTH U3 PIN ECAD
30 3024.2 3203 PTH U3 PIN ECAD
30 3048.4 3105.9 PTH U3 PIN ECAD
30 3072.6 3008.9 PTH U3 PIN ECAD
30 3096.8 2911.9 PTH U3 PIN ECAD
30 3121 2814.9 PTH U3 PIN ECAD
30 3145.2 2717.8 PTH U3 PIN ECAD
30 3436.2 2790.4 PTH U3 PIN ECAD
30 3412.1 2887.4 PTH U3 PIN ECAD
30 3387.9 2984.5 PTH U3 PIN ECAD
30 3363.7 3081.5 PTH U3 PIN ECAD
30 3339.5 3178.5 PTH U3 PIN ECAD
30 3315.3 3275.6 PTH U3 PIN ECAD
30 3291.1 3372.6 PTH U3 PIN ECAD
30 2200 2500 PTH U4 PIN ECAD
30 2100 2500 PTH U4 PIN ECAD
30 2000 2500 PTH U4 PIN ECAD
30 1900 2500 PTH U4 PIN ECAD
30 1800 2500 PTH U4 PIN ECAD
30 1700 2500 PTH U4 PIN ECAD
30 1600 2500 PTH U4 PIN ECAD
30 1600 2200 PTH U4 PIN ECAD
30 1700 2200 PTH U4 PIN ECAD
30 1800 2200 PTH U4 PIN ECAD
30 1900 2200 PTH U4 PIN ECAD
30 2000 2200 PTH U4 PIN ECAD
30 2100 2200 PTH U4 PIN ECAD
30 2200 2200 PTH U4 PIN ECAD
20 2500 3100 PTH BOARD VIA ECAD
20 2500 3200 PTH BOARD VIA ECAD
20 2500 3300 PTH BOARD VIA ECAD
20 2000 1600 PTH BOARD VIA ECAD
20 1100 900 PTH BOARD VIA ECAD
20 1200 1600 PTH BOARD VIA ECAD
20 3900 3800 PTH BOARD VIA ECAD
20 3900 2300 PTH BOARD VIA ECAD
100.0 3100.0 -50.0 NPTH J2 MTG ECAD
100.0 4600.0 -50.0 NPTH J2 MTG ECAD
100.0 500.0 -50.0 NPTH J1 MTG ECAD
100.0 2000.0 -50.0 NPTH J1 MTG ECAD
93.0 5075.0 0.0 PTH BOARD MTG UNOWNED
93.0 0.0 4800.0 NPTH BOARD TOOL MCAD
93.0 0.0 0.0 PTH BOARD MTG UNOWNED
.END_DRILLED_HOLES
# This is the ninth BOARD section
# SEC9-0
# SEC9-1
.NOTES
3500.0 3300.0 75.0 2500.0 "This component rotated 14 degrees"
400.0 4400.0 75.0 3200.0 "Component height limited by enclosure latch"
1800.0 300.0 75.0 1700.0 "Do not move connectors!"
.END_NOTES
# This is the tenth and ALWAYS FINAL BOARD section
# SEC10-0
# SEC10-1
.PLACEMENT
cs13_a pn-cap C1
4000.0 1000.0 100.0 0.0 TOP PLACED
cc1210 pn-cc1210 C2
3000.0 3500.0 0.0 0.0 TOP PLACED
cc1210 pn-cc1210 C3
3200.0 1800.0 0.0 0.0 BOTTOM PLACED
cc1210 pn-cc1210 C4
1400.0 2300.0 0.0 270.0 TOP PLACED
cc1210 pn-cc1210 C5
1799.5 3518.1 0.0 0.0 BOTTOM PLACED
conn_din24 connector J1
1800.0 100.0 0.0 0.0 TOP MCAD
conn_din24 connector J2
4400.0 100.0 0.0 0.0 TOP MCAD
plcc_20 pn-pal16l8-plcc U1
1800.0 3200.0 0.0 0.0 BOTTOM ECAD
plcc_20 pn-pal16l8-plcc U2
3200.0 1800.0 0.0 0.0 TOP PLACED
dip_14w pn-hs346-dip U3
3000.0 3300.0 0.0 14.0 TOP PLACED
dip_14w pn-hs346-dip U4
2200.0 2500.0 0.0 270.0 TOP PLACED
.END_PLACEMENT

View File

@ -0,0 +1,69 @@
.HEADER
LIBRARY_file 3.0 "Sample File Generator" 10/22/96.16:41:37 1
.END_HEADER
# Component #1/5
.ELECTRICAL
cs13_a pn-cap THOU 150.0
0 -55.0 55.0 0.0
0 -55.0 -55.0 0.0
0 135.0 -55.0 0.0
0 135.0 -80.0 0.0
0 565.0 -80.0 0.0
0 565.0 -55.0 0.0
0 755.0 -55.0 0.0
0 755.0 55.0 0.0
0 565.0 55.0 0.0
0 565.0 80.0 0.0
0 135.0 80.0 0.0
0 135.0 55.0 0.0
0 -55.0 55.0 0.0
PROP CAPACITANCE 100.0
PROP TOLERANCE 5.0
.END_ELECTRICAL
# Component #2/5
.ELECTRICAL
cc1210 pn-cc1210 THOU 67.0
0 -40.0 56.0 0.0
0 -40.0 -56.0 0.0
0 182.0 -56.0 0.0
0 182.0 56.0 0.0
0 -40.0 56.0 0.0
PROP CAPACITANCE 0.1
PROP TOLERANCE 5.0
.END_ELECTRICAL
# Component #3/5
.ELECTRICAL
conn_din24 connector THOU 435.0
0 -1400.0 -500.0 0.0
0 300.0 -500.0 0.0
0 300.0 150.0 0.0
0 -1400.0 150.0 0.0
0 -1400.0 -500.0 0.0
.END_ELECTRICAL
# Component #4/5
.ELECTRICAL
dip_14w pn-hs346-dip THOU 200.0
0 350.0 50.0 0.0
0 -50.0 50.0 0.0
0 -50.0 -650.0 0.0
0 350.0 -650.0 0.0
0 350.0 50.0 0.0
.END_ELECTRICAL
# Component #5/5
.ELECTRICAL
plcc_20 pn-pal16l8-plcc THOU 14.0
0 -200.0 240.0 0.0
0 -240.0 200.0 0.0
0 -240.0 -240.0 0.0
0 240.0 -240.0 0.0
0 240.0 240.0 0.0
0 -200.0 240.0 0.0
.END_ELECTRICAL

View File

@ -0,0 +1,71 @@
.HEADER
BOARD_FILE 3.0 "Created by KiCad (2014-01-25 BZR 4633)-product" 2014/02/01.15:09:15 1
"test_idf2.kicad_pcb" MM
.END_HEADER
.BOARD_OUTLINE ECAD
1.60000
0 -86.00000 42.00000 0
0 -86.00000 -42.00000 0
0 86.00000 -42.00000 0
0 86.00000 42.00000 0
0 -86.00000 42.00000 0
.END_BOARD_OUTLINE
.DRILLED_HOLES
0.800 -74.00000 16.00000 PTH BOARD PIN ECAD
0.800 -74.00000 -28.00000 PTH BOARD PIN ECAD
0.850 -55.75000 16.00000 PTH BOARD PIN ECAD
0.850 -52.25000 16.00000 PTH BOARD PIN ECAD
0.850 -35.75000 16.00000 PTH BOARD PIN ECAD
0.850 -32.25000 16.00000 PTH BOARD PIN ECAD
1.575 -57.17500 -28.00000 PTH BOARD PIN ECAD
1.575 -50.82500 -28.00000 PTH BOARD PIN ECAD
1.575 -37.17500 -28.00000 PTH BOARD PIN ECAD
1.575 -30.82500 -28.00000 PTH BOARD PIN ECAD
0.800 -14.00000 16.00000 PTH BOARD PIN ECAD
0.800 -14.00000 -28.00000 PTH BOARD PIN ECAD
0.800 6.00000 16.00000 PTH BOARD PIN ECAD
0.800 6.00000 -28.00000 PTH BOARD PIN ECAD
0.800 26.00000 16.00000 PTH BOARD PIN ECAD
0.800 26.00000 -28.00000 PTH BOARD PIN ECAD
0.800 46.00000 16.00000 PTH BOARD PIN ECAD
0.800 46.00000 -28.00000 PTH BOARD PIN ECAD
0.800 66.00000 16.00000 PTH BOARD PIN ECAD
0.800 66.00000 -28.00000 PTH BOARD PIN ECAD
.END_DRILLED_HOLES
.PLACEMENT
"CYLV_MM" "D5.000_H8.000_Z3.000" "NOREFDES_0"
-74.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLV_IN" "D0.250_H0.250_Z0.127" "NOREFDES_1"
-74.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLV_MM_L" "D5.000_H8.000_Z3.000_WD0.800_P3.500" "NOREFDES_2"
-54.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLV_MM_R" "D5.000_H8.000_Z3.000_WD0.800_P3.500" "NOREFDES_3"
-34.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLV_IN_L" "D0.250_H0.250_Z0.127_WD0.062_P0.250" "NOREFDES_4"
-54.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLV_IN_R" "D0.250_H0.250_Z0.127_WD0.062_P0.250" "NOREFDES_5"
-34.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLH_MM_AXI" "D2.500_H4.000_Z0.500_WD0.600_P8.000" "NOREFDES_6"
-14.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLH_IN_AXI" "D0.098_H0.157_Z0.020_WD0.024_P0.315" "NOREFDES_7"
-14.000000 -28.000000 0.000000 0.000 TOP ECAD
"CYLH_MM_RAD" "D5.000_H6.000_Z0.200_WD0.600_P2.500_L3.000" "NOREFDES_8"
6.000000 16.000000 0.000000 0.000 TOP ECAD
"CYLH_IN_RAD" "D0.197_H0.236_Z0.008_WD0.024_P0.098_L0.118" "NOREFDES_9"
6.000000 -28.000000 0.000000 0.000 TOP ECAD
"RECTMM" "W10.000_L10.000_H6.000_C0.000" "NOREFDES_10"
26.000000 16.000000 0.000000 0.000 TOP ECAD
"RECTIN" "W393_L393_H236_C0" "NOREFDES_11"
26.000000 -28.000000 0.000000 0.000 TOP ECAD
"RECTMM" "W10.000_L10.000_H2.000_C0.500" "NOREFDES_12"
46.000000 16.000000 0.000000 0.000 TOP ECAD
"RECTIN" "W393_L393_H78_C19" "NOREFDES_13"
46.000000 -28.000000 0.000000 0.000 TOP ECAD
"RECTLMM" "W10.000_L10.000_H12.000_D0.800_P6.000" "NOREFDES_14"
66.000000 16.000000 0.000000 0.000 TOP ECAD
"RECTLIN" "W393_L393_H472_D31_P236" "NOREFDES_15"
66.000000 -28.000000 0.000000 0.000 TOP ECAD
.END_PLACEMENT

View File

@ -0,0 +1,290 @@
.HEADER
LIBRARY_FILE 3.0 "Created by KiCad (2014-01-25 BZR 4633)-product" 2014/02/01.15:09:15 1
.END_HEADER
# cylindrical outline, vertical, no pins
# file: "cylvmm_0_D5_L8_Z3.idf"
# dia: 5.000 mm
# length: 8.000 mm
# extra height: 3.000 mm
.ELECTRICAL
"CYLV_MM" "D5.000_H8.000_Z3.000" MM 11.000
0 0 0 0
0 5.000 0 360
.END_ELECTRICAL
# cylindrical outline, vertical, no pins
# file: "cylvin_0_D0.25_L0.25_Z0.127.idf"
# dia: 250 THOU
# length: 250 THOU
# extra height: 127 THOU
.ELECTRICAL
"CYLV_IN" "D0.250_H0.250_Z0.127" THOU 377
0 0 0 0
0 250 0 360
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on left
# file: "cylvmm_1L_D5_L8_Z3_WD0.8_P3.5.idf"
# dia: 5.000 mm
# length: 8.000 mm
# extra height: 3.000 mm
# wire dia: 0.800 mm
# pitch: 3.500 mm
.ELECTRICAL
"CYLV_MM_L" "D5.000_H8.000_Z3.000_WD0.800_P3.500" MM 11.000
1 -0.718 0.400 0
1 -0.718 -0.400 -341.586
1 -1.750 -0.400 0
1 -1.750 0.400 -180
1 -0.718 0.400 0
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on right
# file: "cylvmm_1R_D5_L8_Z3_WD0.8_P3.5.idf"
# dia: 5.000 mm
# length: 8.000 mm
# extra height: 3.000 mm
# wire dia: 0.800 mm
# pitch: 3.500 mm
.ELECTRICAL
"CYLV_MM_R" "D5.000_H8.000_Z3.000_WD0.800_P3.500" MM 11.000
0 0.718 0.400 0
0 0.718 -0.400 341.586
0 1.750 -0.400 0
0 1.750 0.400 180
0 0.718 0.400 0
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on left
# file: "cylvin_1L_D0.25_L0.25_Z0.127_WD0.062_P0.25.idf"
# dia: 250 THOU
# length: 250 THOU
# extra height: 127 THOU
# wire dia: 62 THOU
# pitch: 250 THOU
.ELECTRICAL
"CYLV_IN_L" "D0.250_H0.250_Z0.127_WD0.062_P0.250" THOU 377
1 3 31 0
1 3 -31 -331.282
1 -125 -31 0
1 -125 31 -180
1 3 31 0
.END_ELECTRICAL
# cylindrical outline, vertical, 1 pin on right
# file: "cylvin_1R_D0.25_L0.25_Z0.127_WD0.062_P0.25.idf"
# dia: 250 THOU
# length: 250 THOU
# extra height: 127 THOU
# wire dia: 62 THOU
# pitch: 250 THOU
.ELECTRICAL
"CYLV_IN_R" "D0.250_H0.250_Z0.127_WD0.062_P0.250" THOU 377
0 -3 31 0
0 -3 -31 331.282
0 125 -31 0
0 125 31 180
0 -3 31 0
.END_ELECTRICAL
# cylindrical outline, horiz., axial pins
# file: "resistor.idf"
# dia: 2.500 mm
# length: 4.000 mm
# extra height: 0.500 mm
# wire dia: 0.600 mm
# pitch: 8.000 mm
.ELECTRICAL
"CYLH_MM_AXI" "D2.500_H4.000_Z0.500_WD0.600_P8.000" MM 3.000
0 -2.000 1.250 0
0 -2.000 0.300 0
0 -4.000 0.300 0
0 -4.000 -0.300 180
0 -2.000 -0.300 0
0 -2.000 -1.250 0
0 2.000 -1.250 0
0 2.000 -0.300 0
0 4.000 -0.300 0
0 4.000 0.300 180
0 2.000 0.300 0
0 2.000 1.250 0
0 -2.000 1.250 0
.END_ELECTRICAL
# cylindrical outline, horiz., axial pins
# file: "resistor_in.idf"
# dia: 98 THOU
# length: 157 THOU
# extra height: 20 THOU
# wire dia: 24 THOU
# pitch: 315 THOU
.ELECTRICAL
"CYLH_IN_AXI" "D0.098_H0.157_Z0.020_WD0.024_P0.315" THOU 118
0 -78 49 0
0 -78 12 0
0 -157 12 0
0 -157 -12 180
0 -78 -12 0
0 -78 -49 0
0 78 -49 0
0 78 -12 0
0 157 -12 0
0 157 12 180
0 78 12 0
0 78 49 0
0 -78 49 0
.END_ELECTRICAL
# cylindrical outline, horiz., radial pins
# file: "capacitor.idf"
# dia: 5.000 mm
# length: 6.000 mm
# extra height: 0.200 mm
# wire dia: 0.600 mm
# pitch: 2.500 mm
# lead: 3.000 mm
.ELECTRICAL
"CYLH_MM_RAD" "D5.000_H6.000_Z0.200_WD0.600_P2.500_L3.000" MM 5.200
0 -2.500 9.000 0
0 -2.500 3.000 0
0 -1.550 3.000 0
0 -1.550 0 0
0 -0.950 0 180
0 -0.950 3.000 0
0 0.950 3.000 0
0 0.950 0 0
0 1.550 0 180
0 1.550 3.000 0
0 2.500 3.000 0
0 2.500 9.000 0
0 -2.500 9.000 0
.END_ELECTRICAL
# cylindrical outline, horiz., radial pins
# file: "capacitor_in.idf"
# dia: 197 THOU
# length: 236 THOU
# extra height: 8 THOU
# wire dia: 24 THOU
# pitch: 98 THOU
# lead: 118 THOU
.ELECTRICAL
"CYLH_IN_RAD" "D0.197_H0.236_Z0.008_WD0.024_P0.098_L0.118" THOU 205
0 -98 354 0
0 -98 118 0
0 -61 118 0
0 -61 0 0
0 -37 0 180
0 -37 118 0
0 37 118 0
0 37 0 0
0 61 0 180
0 61 118 0
0 98 118 0
0 98 354 0
0 -98 354 0
.END_ELECTRICAL
# rectangular outline
# file: "rectMM_10x10x6_C0.idf"
# width: 10.000 mm
# length: 10.000 mm
# height: 6.000 mm
# chamfer: 0.000 mm
.ELECTRICAL
"RECTMM" "W10.000_L10.000_H6.000_C0.000" MM 6.000
0 5.000 5.000 0
0 -5.000 5.000 0
0 -5.000 -5.000 0
0 5.000 -5.000 0
0 5.000 5.000 0
.END_ELECTRICAL
# rectangular outline
# file: "rectIN_10x10x6mm_C0mm.idf"
# width: 393 THOU
# length: 393 THOU
# height: 236 THOU
# chamfer: 0 THOU
.ELECTRICAL
"RECTIN" "W393_L393_H236_C0" THOU 236
0 196 196 0
0 -196 196 0
0 -196 -196 0
0 196 -196 0
0 196 196 0
.END_ELECTRICAL
# rectangular outline
# file: "rectMM_10x10x2_C0.5.idf"
# width: 10.000 mm
# length: 10.000 mm
# height: 2.000 mm
# chamfer: 0.500 mm
.ELECTRICAL
"RECTMM" "W10.000_L10.000_H2.000_C0.500" MM 2.000
0 5.000 5.000 0
0 -4.500 5.000 0
0 -5.000 4.500 0
0 -5.000 -5.000 0
0 5.000 -5.000 0
0 5.000 5.000 0
.END_ELECTRICAL
# rectangular outline
# file: "rectIN_10x10x2mm_C0.5mm.idf"
# width: 393 THOU
# length: 393 THOU
# height: 78 THOU
# chamfer: 19 THOU
.ELECTRICAL
"RECTIN" "W393_L393_H78_C19" THOU 78
0 196 196 0
0 -176 196 0
0 -196 176 0
0 -196 -196 0
0 196 -196 0
0 196 196 0
.END_ELECTRICAL
# rectangular outline, leaded
# file: "rectLMM_10x10x12_D0.8_P6.0.idf"
# width: 10.000 mm
# length: 10.000 mm
# height: 12.000 mm
# wire dia: 0.800 mm
# pitch: 6.000 mm
.ELECTRICAL
"RECTLMM" "W10.000_L10.000_H12.000_D0.800_P6.000" MM 12.000
0 3.000 0.400 0
0 2.000 0.400 0
0 2.000 5.000 0
0 -8.000 5.000 0
0 -8.000 -5.000 0
0 2.000 -5.000 0
0 2.000 -0.400 0
0 3.000 -0.400 0
0 3.000 0.400 180
.END_ELECTRICAL
# rectangular outline, leaded
# file: "rectLIN_10x10x12mm_D0.8mm_P6.0mm.idf"
# width: 393 THOU
# length: 393 THOU
# height: 472 THOU
# wire dia: 31 THOU
# pitch: 236 THOU
.ELECTRICAL
"RECTLIN" "W393_L393_H472_D31_P236" THOU 472
0 118 15 0
0 78 15 0
0 78 196 0
0 -315 196 0
0 -315 -196 0
0 78 -196 0
0 78 -15 0
0 118 -15 0
0 118 15 180
.END_ELECTRICAL

View File

@ -0,0 +1,295 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <cctype>
#include <iostream>
#include <sstream>
#include <idf_common.h>
#include <idf_helpers.h>
using namespace std;
using namespace IDF3;
// fetch a line from the given input file and trim the ends
bool IDF3::FetchIDFLine( std::ifstream& aModel, std::string& aLine, bool& isComment, std::streampos& aFilePos )
{
aLine = "";
aFilePos = aModel.tellg();
if( aFilePos == -1 )
return false;
std::getline( aModel, aLine );
isComment = false;
// A comment begins with a '#' and must be the first character on the line
if( aLine[0] == '#' )
{
// opening '#' is stripped
isComment = true;
aLine.erase( aLine.begin() );
}
// strip leading and trailing spaces
while( !aLine.empty() && isspace( *aLine.begin() ) )
aLine.erase( aLine.begin() );
while( !aLine.empty() && isspace( *aLine.rbegin() ) )
aLine.erase( --aLine.end() );
// a comment line may be empty to improve human readability
if( aLine.empty() && !isComment )
return false;
return true;
}
// extract an IDF string and move the index to point to the character after the substring
bool IDF3::GetIDFString( const std::string& aLine, std::string& aIDFString,
bool& hasQuotes, int& aIndex )
{
// 1. drop all leading spaces
// 2. if the first character is '"', read until the next '"',
// otherwise read until the next space or EOL.
std::ostringstream ostr;
int len = aLine.length();
int idx = aIndex;
if( idx < 0 || idx >= len )
return false;
while( isspace( aLine[idx] ) && idx < len ) ++idx;
if( idx == len )
{
aIndex = idx;
return false;
}
if( aLine[idx] == '"' )
{
hasQuotes = true;
++idx;
while( aLine[idx] != '"' && idx < len )
ostr << aLine[idx++];
if( idx == len )
{
ERROR_IDF << "unterminated quote mark in line:\n";
std::cerr << "LINE: " << aLine << "\n";
aIndex = idx;
return false;
}
++idx;
}
else
{
hasQuotes = false;
while( !isspace( aLine[idx] ) && idx < len )
ostr << aLine[idx++];
}
aIDFString = ostr.str();
aIndex = idx;
return true;
}
// perform a comparison between a fixed token string and an input string.
// the token is assumed to be an upper case IDF token and the input string
// is data from an IDF file. Since IDF tokens are case-insensitive, we cannot
// assume anything about the case of the input string.
bool IDF3::CompareToken( const char* aTokenString, const std::string& aInputString )
{
std::string::size_type i, j;
std::string bigToken = aInputString;
j = aInputString.length();
for( i = 0; i < j; ++i )
bigToken[i] = std::toupper( bigToken[i] );
if( !bigToken.compare( aTokenString ) )
return true;
return false;
}
// parse a string for an IDF3::KEY_OWNER
bool IDF3::ParseOwner( const std::string& aToken, IDF3::KEY_OWNER& aOwner )
{
if( CompareToken( "UNOWNED", aToken ) )
{
aOwner = UNOWNED;
return true;
}
else if( CompareToken( "ECAD", aToken ) )
{
aOwner = ECAD;
return true;
}
else if( CompareToken( "MCAD", aToken ) )
{
aOwner = MCAD;
return true;
}
ERROR_IDF << "unrecognized IDF OWNER: '" << aToken << "'\n";
return false;
}
bool IDF3::ParseIDFLayer( const std::string& aToken, IDF3::IDF_LAYER& aLayer )
{
if( CompareToken( "TOP", aToken ) )
{
aLayer = LYR_TOP;
return true;
}
else if( CompareToken( "BOTTOM", aToken ) )
{
aLayer = LYR_BOTTOM;
return true;
}
else if( CompareToken( "BOTH", aToken ) )
{
aLayer = LYR_BOTH;
return true;
}
else if( CompareToken( "INNER", aToken ) )
{
aLayer = LYR_INNER;
return true;
}
else if( CompareToken( "ALL", aToken ) )
{
aLayer = LYR_ALL;
return true;
}
ERROR_IDF << "unrecognized IDF LAYER: '" << aToken << "'\n";
aLayer = LYR_INVALID;
return false;
}
bool IDF3::WriteLayersText( std::ofstream& aBoardFile, IDF3::IDF_LAYER aLayer )
{
switch( aLayer )
{
case LYR_TOP:
aBoardFile << "TOP";
break;
case LYR_BOTTOM:
aBoardFile << "BOTTOM";
break;
case LYR_BOTH:
aBoardFile << "BOTH";
break;
case LYR_INNER:
aBoardFile << "INNER";
break;
case LYR_ALL:
aBoardFile << "ALL";
break;
default:
ERROR_IDF << "Invalid IDF layer" << aLayer << "\n";
return false;
break;
}
return !aBoardFile.fail();
}
std::string IDF3::GetPlacementString( IDF3::IDF_PLACEMENT aPlacement )
{
switch( aPlacement )
{
case PS_UNPLACED:
return "UNPLACED";
case PS_PLACED:
return "PLACED";
case PS_MCAD:
return "MCAD";
case PS_ECAD:
return "ECAD";
default:
break;
}
std::ostringstream ostr;
ostr << "[INVALID PLACEMENT VALUE]:" << aPlacement;
return ostr.str();
}
std::string IDF3::GetLayerString( IDF3::IDF_LAYER aLayer )
{
switch( aLayer )
{
case LYR_TOP:
return "TOP";
case LYR_BOTTOM:
return "BOTTOM";
case LYR_BOTH:
return "BOTH";
case LYR_INNER:
return "INNER";
case LYR_ALL:
return "ALL";
default:
break;
}
std::ostringstream ostr;
ostr << "[INVALID LAYER VALUE]:" << aLayer;
return ostr.str();
}

View File

@ -0,0 +1,171 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef IDF_HELPERS_H
#define IDF_HELPERS_H
#include <wx/wx.h>
#include <fstream>
#include <string>
#include <idf_common.h>
/**
* Macro TO_UTF8
* converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
* wxstring is a wxString, not a wxT() or _(). The scope of the return value
* is very limited and volatile, but can be used with printf() style functions well.
* NOTE: Taken from KiCad include/macros.h
*/
#define TO_UTF8( wxstring ) ( (const char*) (wxstring).utf8_str() )
/**
* function FROM_UTF8
* converts a UTF8 encoded C string to a wxString for all wxWidgets build modes.
* NOTE: Taken from KiCad include/macros.h
*/
static inline wxString FROM_UTF8( const char* cstring )
{
wxString line = wxString::FromUTF8( cstring );
if( line.IsEmpty() ) // happens when cstring is not a valid UTF8 sequence
line = wxConvCurrent->cMB2WC( cstring ); // try to use locale conversion
return line;
}
#define ERROR_IDF std::cerr << "* " << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "(): "
// 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 )
// conversion between mm and thou
#define IDF_MM_TO_THOU 0.0254
namespace IDF3
{
/**
* Function FetchIDFLine
* retrieves a single line from an IDF file and performs minimal processing. If a comment symbol
* is encountered then it is removed and a single leading space is removed if present; all trailing
* spaces are removed. If the line is not a comment then all leading and trailing spaces are stripped.
*
* @param aModel is an open IDFv3 file
* @param aLine (output) is the line retrieved from the file
* @param isComment (output) is set to true if the line is a comment
* @param aFilePos (output) is set to the beginning of the line in case the file needs to be rewound
*
* @return bool: true if a line was read and was not empty; otherwise false
*/
bool FetchIDFLine( std::ifstream& aModel, std::string& aLine, bool& isComment, std::streampos& aFilePos );
/**
* Function GetIDFString
* parses a line retrieved via FetchIDFLine() and returns the first IDF string found from the starting
* point aIndex
*
* @param aLine is the line to parse
* @param aIDFString (output) is the IDF string retrieved
* @param hasQuotes (output) is true if the string was in quotation marks
* @param aIndex (input/output) is the index into the input line
*
* @return bool: true if a string was retrieved, otherwise false
*/
bool GetIDFString( const std::string& aLine, std::string& aIDFString,
bool& hasQuotes, int& aIndex );
/**
* Function CompareToken
* performs a case-insensitive comparison of a token string and an input string
*
* @param aToken is an IDF token such as ".HEADER"
* @param aInputString is a string typically retrieved via GetIDFString
*
* @return bool: true if the token and input string match
*/
bool CompareToken( const char* aTokenString, const std::string& aInputString );
/**
* Function ParseOwner
* parses the input string for a valid IDF Owner type
*
* @param aToken is the string to be parsed
* @param aOwner (output) is the IDF Owner class
*
* @return bool: true if a valid OWNER was found, otherwise false
*/
bool ParseOwner( const std::string& aToken, IDF3::KEY_OWNER& aOwner );
/**
* Function ParseIDFLayer
* parses an input string for a valid IDF layer specification
*
* @param aToken is the string to be parsed
* @param aLayer (output) is the IDF Layer type or group
*
* @return bool: true if a valid IDF Layer type was found, otherwise false
*/
bool ParseIDFLayer( const std::string& aToken, IDF3::IDF_LAYER& aLayer );
/**
* Function WriteLayersText
* writes out text corresponding to the given IDF Layer type
*
* @param aBoardFile is an IDFv3 file open for output
* @param aLayer is the IDF Layer type
*
* @return bool: true if the data was successfully written, otherwise false
*/
bool WriteLayersText( std::ofstream& aBoardFile, IDF3::IDF_LAYER aLayer );
/**
* Function GetPlacementString
* returns a string representing the given IDF Placement type
*
* @param aPlacement is the IDF placement type to encode as a string
*
* @return string: the string representation of aPlacement
*/
std::string GetPlacementString( IDF3::IDF_PLACEMENT aPlacement );
/**
* Function GetLayerString
* returns a string representing the given IDF Layer type
*
* @param aLayer is the IDF layer type to encode as a string
*
* @return string: the string representation of aLayer
*/
std::string GetLayerString( IDF3::IDF_LAYER aLayer );
}
#endif // IDF_HELPERS_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,754 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef IDF_OUTLINES_H
#define IDF_OUTLINES_H
#include <string>
#include <list>
#include <map>
#include <wx/string.h>
#include <wx/filename.h>
#include <idf_common.h>
/*
* NOTES ON OUTLINE TYPES:
*
* BOARD_OUTLINE (PANEL_OUTLINE)
* .BOARD_OUTLINE [OWNER]
* [thickness]
* [outlines]
*
* OTHER_OUTLINE
* .OTHER_OUTLINE [OWNER]
* [outline identifier] [thickness] [board side: Top/Bot]
* [outline]
*
* ROUTE_OUTLINE
* .ROUTE_OUTLINE [OWNER]
* [layers]
* [outline]
*
* PLACE_OUTLINE
* .PLACE_OUTLINE [OWNER]
* [board side: Top/Bot/Both] [height]
* [outline]
*
* ROUTE_KEEPOUT
* .ROUTE_KEEPOUT [OWNER]
* [layers]
* [outline]
*
* VIA_KEEPOUT
* .VIA_KEEPOUT [OWNER]
* [outline]
*
* PLACE_KEEPOUT
* .PLACE_KEEPOUT [OWNER]
* [board side: Top/Bot/Both] [height]
* [outline]
*
* Placement Group
* .PLACE_REGION [OWNER]
* [side: Top/Bot/Both ] [component group name]
* [outline]
*
* Component Outline:
* .ELECTRICAL/.MECHANICAL
* [GEOM] [PART] [UNIT] [HEIGHT]
* [outline]
* [PROP] [prop name] [prop value]
*/
class IDF3_BOARD;
/**
* Class BOARD_OUTLINE
* supports the IDFv3 BOARD OUTLINE data and is the basis of other IDFv3 outline classes
*/
class BOARD_OUTLINE
{
protected:
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
bool single; // true if only a single outline is accepted
std::list< std::string > comments; // associated comment list
IDF3::IDF_UNIT unit; // outline's native unit (MM or THOU)
IDF3_BOARD* parent; // BOARD which contains this outline
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 );
// 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 );
// Iterate through the outlines and write out all data
bool writeOutlines( std::ofstream& aBoardFile ); // write outline data (no headers)
public:
BOARD_OUTLINE();
virtual ~BOARD_OUTLINE();
/**
* Function SetUnit
* sets the native unit of the outline; except for component outlines this must
* be the same as the native unit of the parent IDF_BOARD object
*
* @param aUnit is the native unit (UNIT_MM or UNIT_THOU)
*/
virtual void SetUnit( IDF3::IDF_UNIT aUnit );
/**
* Function GetUnit
* returns the native unit type of the outline
*
* @return IDF_UNIT is the native unit (UNIT_MM or UNIT_THOU)
*/
virtual IDF3::IDF_UNIT GetUnit( void );
/**
* Function SetThickness
* sets the thickness or height of the outline (mm)
*
* @param aThickness is the thickness or height of the outline in mm
*/
virtual bool SetThickness( double aThickness );
/**
* Function GetThickness
* returns the thickness or height of an outline (mm)
*/
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
*/
virtual void Clear( void );
/**
* Function GetOutlineType
* returns the type of outline according to the IDFv3 classification
*/
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
*/
IDF3_BOARD* GetParent( void );
/**
* Function AddOutline
* adds the specified outline to this object.
*
* @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.
*/
bool AddOutline( IDF_OUTLINE* aOutline );
/**
* Function DelOutline( IDF_OUTLINE* aOutline )
* removes the given outline, subject to IDF ownership rules,
* if it is owned by this object. The outline pointer remains
* valid and it is the user's responsibility to delete the object.
* The first outline in the list will never be deleted unless it
* is the sole remaining outline; this is to ensure that a board
* outline is not removed while the cutouts remain.
*
* @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.
*/
bool DelOutline( IDF_OUTLINE* aOutline );
/**
* Function DelOutline( IDF_OUTLINE* aOutline )
* deletes the outline specified by the given index, subject to
* IDF ownership rules. The outline data is destroyed.
* The first outline in the list will never be deleted unless it
* is the sole remaining outline; this is to ensure that a board
* outline is not removed while the cutouts remain.
*
* @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.
*/
bool DelOutline( size_t aIndex );
/**
* Function GetOutlines
* returns a pointer to the internal outlines list. It is up to the
* user to respect the IDFv3 specification and avoid changes to this
* list which are in violation of the specification.
*/
const std::list< IDF_OUTLINE* >*const GetOutlines( void );
/**
* Function OutlinesSize
* returns the number of items in the internal outline list
*/
size_t OutlinesSize( void );
/**
* 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.
*/
IDF_OUTLINE* GetOutline( size_t aIndex );
/**
* Function GetOwner
* returns the ownership status of the outline ( ECAD, MCAD, UNOWNED)
*/
IDF3::KEY_OWNER GetOwner( void );
/**
* Function SetOwner
* sets the ownership status of the outline subject to IDF
* ownership rules. The return value is true if the ownership
* was changed and false if a specification violation occurred.
*/
bool SetOwner( IDF3::KEY_OWNER aOwner );
/**
* Function IsSingle
* return true if this type of outline only supports a single
* outline. All outlines except for BOARD_OUTLINE are single.
*/
bool IsSingle( void );
/**
* Function ClearOutlines
* clears internal data except for the parent pointer
*/
void ClearOutlines( void );
/**
* Function AddComment
* adds a comment to the outline data; this function is not
* subject to IDF ownership rules.
*/
void AddComment( const std::string& aComment );
/**
* Function CommentSize
* returns the number of comments in the internal list
*/
size_t CommentsSize( void );
/**
* Function GetComments
* returns a pointer to the internal list of comments
*/
std::list< std::string >* GetComments( void );
/**
* Function GetComment
* returns the string representing the indexed comment or
* NULL if the index is out of bounds
*/
const std::string* GetComment( size_t aIndex );
/**
* Function DeleteComment
* deletes a comment based on the given index.
*
* @return bool: true if a comment was deleted, false if
* the index is out of bounds.
*/
bool DeleteComment( size_t aIndex );
/**
* Function ClearComments
* deletes all comments
*/
void ClearComments( void );
};
/**
* Class OTHER_OUTLINE
* describes miscellaneous extrusions on the board
*/
class OTHER_OUTLINE : public BOARD_OUTLINE
{
private:
std::string uniqueID; // Outline Identifier (IDF spec)
IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM ONLY] (IDF spec)
public:
OTHER_OUTLINE();
/**
* Function SetOutlineIdentifier
* sets the Outline Identifier string of this OTHER_OUTLINE object
* as per IDFv3 spec.
*/
virtual void SetOutlineIdentifier( const std::string aUniqueID );
/**
* Function GetOutlineIdentifier
* returns the object's Outline Identifier
*/
virtual const std::string& GetOutlineIdentifier( void );
/**
* 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.
*/
virtual bool SetSide( IDF3::IDF_LAYER aSide );
/**
* Function GetSide
* returns the side which this outline is applicable to
*/
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 );
};
/**
* Class ROUTE_OUTLINE
* describes routing areas on the board
*/
class ROUTE_OUTLINE : public BOARD_OUTLINE
{
protected:
IDF3::IDF_LAYER layers; // Routing layers (IDF spec)
public:
ROUTE_OUTLINE();
/**
* 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.
*/
virtual void SetLayers( IDF3::IDF_LAYER aLayer );
/**
* Function GetLayers
* returns the layer or group of layers which this outline is applicable to
*/
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 );
};
/**
* Class PLACE_OUTLINE
* describes areas on the board for placing components
*/
class PLACE_OUTLINE : public BOARD_OUTLINE
{
protected:
IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec)
double height; // Max Height (IDF spec)
public:
PLACE_OUTLINE();
/**
* 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.
*/
virtual void SetSide( IDF3::IDF_LAYER aSide );
/**
* Function GetSide
* returns the side which this outline is applicable to
*/
virtual IDF3::IDF_LAYER GetSide( void );
/**
* 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.
*/
virtual void SetMaxHeight( double aHeight );
/**
* Function GetMaxHeight
* returns the maximum allowable height for a component in this region
*/
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 );
};
/**
* Class ROUTE_KO_OUTLINE
* describes regions and layers where no electrical routing is permitted
*/
class ROUTE_KO_OUTLINE : public ROUTE_OUTLINE
{
public:
ROUTE_KO_OUTLINE();
};
/**
* Class VIA_KO_OUTLINE
* describes regions in which vias are prohibited. Note: IDFv3 only considers
* thru-hole vias and makes no statement regarding behavior with blind or buried
* vias.
*/
class VIA_KO_OUTLINE : public OTHER_OUTLINE
{
public:
VIA_KO_OUTLINE();
};
/**
* Class PLACE_KO_OUTLINE
* represents regions and layers in which no component may
* be placed or on which a maximum component height is in effect.
*/
class PLACE_KO_OUTLINE : public PLACE_OUTLINE
{
public:
PLACE_KO_OUTLINE();
};
/**
* Class GROUP_OUTLINE
* represents regions and layers in which user-specified features or components
* may be placed.
*/
class GROUP_OUTLINE : public BOARD_OUTLINE
{
private:
IDF3::IDF_LAYER side; // Board Side [TOP/BOTTOM/BOTH ONLY] (IDF spec)
std::string groupName; // non-unique string
public:
GROUP_OUTLINE();
/**
* 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.
*/
virtual void SetSide( IDF3::IDF_LAYER aSide );
/**
* Function GetSide
* returns the side which this outline applies to
*/
virtual IDF3::IDF_LAYER GetSide( void );
/**
* 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.
*/
virtual void SetGroupName( std::string aGroupName );
/**
* Function GetGroupName
* returns a reference to the (non-unique) group name
*/
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 );
};
/**
* class IDF3_COMP_OUTLINE
* represents a component's outline as stored in an IDF library file
*/
class IDF3_COMP_OUTLINE : public BOARD_OUTLINE
{
private:
std::string uid; // unique ID
std::string geometry; // geometry name (IDF)
std::string part; // part name (IDF)
IDF3::COMP_TYPE compType; // component type
int refNum; // number of components referring to this outline
std::map< std::string, std::string > props; // properties list
bool readProperties( std::ifstream& aLibFile );
bool writeProperties( std::ofstream& aLibFile );
public:
IDF3_COMP_OUTLINE();
/**
* Function ReadData
* reads a component outline from an open IDFv3 file
*
* @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 );
/**
* 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 );
/**
* Function Clear
* deletes internal outline data
*/
virtual void Clear( void );
/**
* Function SetComponentClass
* sets the type of component outline (.ELECTRICAL or .MECHANICAL)
* If the specified class is invalid an exception is thrown.
*/
void SetComponentClass( IDF3::COMP_TYPE aCompClass );
/**
* Function GetComponentClass
* returns the class of component represented by this outline
*/
IDF3::COMP_TYPE GetComponentClass( void );
/**
* Function SetGeomName
* sets the Geometry Name (Package Name, IDFv3 spec) of the component outline
*/
void SetGeomName( const std::string& aGeomName );
/**
* Function GetGeomName
* returns the Geometry Name (Package Name) of the component outline
*/
const std::string& GetGeomName( void );
/**
* Function SetPartName
* sets the Part Name (Part Number, IDFv3 spec) of the component outline
*/
void SetPartName( const std::string& aPartName );
/**
* Function GetPartName
* returns the Part Name (Part Number) of the component outline
*/
const std::string& GetPartName( void );
/**
* Function GetUID
* returns the unique identifier for this component outline;
* this is equal to GEOM_NAME + "_" + PART_NAME
*/
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 outline is a star with outer radius 5mm and inner radius 2.5mm.
*/
bool CreateDefaultOutline( const std::string &aGeom, const std::string &aPart );
// XXX: property manipulators
};
#endif // IDF_OUTLINES_H

File diff suppressed because it is too large Load Diff

657
utils/idftools/idf_parser.h Normal file
View File

@ -0,0 +1,657 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 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
#ifndef IDF_PARSER_H
#define IDF_PARSER_H
#include <idf_outlines.h>
class IDF3_COMPONENT;
class IDF3_COMP_OUTLINE_DATA
{
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
IDF3_COMP_OUTLINE* outline; // component outline to use
IDF3_COMPONENT* parent; // associated component
public:
/**
* Constructor
* creates an object with default settings and no parent or associated outline
*/
IDF3_COMP_OUTLINE_DATA();
/**
* Constructor
* creates an object with default settings and the specified parent and associated outline
*
* @param aParent is the owning IDF3_COMPONENT object
* @param aOutline is the outline for this placed component
*/
IDF3_COMP_OUTLINE_DATA( IDF3_COMPONENT* aParent, IDF3_COMP_OUTLINE* aOutline );
/**
* Constructor
* creates an object the specified parent and associated outline and the specified
* data.
*
* @param aParent is the owning IDF3_COMPONENT object
* @param aOutline is the outline for this placed component
* @param aXoff is the X offset of this outline in relation to its parent
* @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
*/
IDF3_COMP_OUTLINE_DATA( IDF3_COMPONENT* aParent, IDF3_COMP_OUTLINE* aOutline,
double aXoff, double aYoff, double aZoff, double aAngleOff );
~IDF3_COMP_OUTLINE_DATA();
/**
* Function SetOffsets
* sets the position and orientation of this outline item in relation to its parent
*
* @param aXoff is the X offset of this outline in relation to its parent
* @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
*/
void SetOffsets( double aXoff, double aYoff, double aZoff, double aAngleOff );
/**
* Function GetOffsets
* retrieves the position and orientation of this outline item in relation to its parent
*
* @param aXoff is the X offset of this outline in relation to its parent
* @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
*/
void GetOffsets( double& aXoff, double& aYoff, double& aZoff, double& aAngleOff );
/**
* Function SetParent
* sets the parent object
*
* @param aParent is the owning IDF3_COMPONENT object
*/
void SetParent( IDF3_COMPONENT* aParent );
/**
* Function SetOutline
* sets the outline whose position is managed by this object
*
* @param aOutline is the outline for this component
*/
void SetOutline( IDF3_COMP_OUTLINE* aOutline );
/**
* Function GetOutline
* retrieves the outline whose position is managed by this object
*
* @return IDF3_COMP_OUTLINE*: the outline for this component
*/
IDF3_COMP_OUTLINE* GetOutline( void )
{
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 );
};
class IDF3_COMPONENT
{
private:
std::list< IDF3_COMP_OUTLINE_DATA* > components;
std::list< IDF_DRILL_DATA* > drills;
double xpos;
double ypos;
double angle;
IDF3::IDF_PLACEMENT placement;
IDF3::IDF_LAYER layer; // [TOP/BOTTOM ONLY as per IDF spec]
bool hasPosition; ///< True after SetPosition is called once
std::string refdes; ///< Reference Description (MUST BE UNIQUE)
IDF3_BOARD* parent;
public:
/**
* Constructor
* sets internal parameters to default values
*/
IDF3_COMPONENT();
/**
* Constructor
* sets the parent object and initializes other internal parameters to default values
*
* @param aParent is the owning IDF3_BOARD object
*/
IDF3_COMPONENT( IDF3_BOARD* aParent );
~IDF3_COMPONENT();
/**
* Function SetParent
* sets the parent object
*
* @param aParent is the owning IDF3_BOARD object
*/
void SetParent( IDF3_BOARD* aParent );
/**
* Function GetCadType
* returns the type of CAD (IDF3::CAD_ELEC, IDF3::CAD_MECH) which instantiated this object
*
* @return IDF3::CAD_TYPE
*/
IDF3::CAD_TYPE GetCadType( void );
/**
* Function GetCadType
* returns the IDF UNIT type of the parent object or IDF3::UNIT_INVALID if
* the parent was not set
*
* @return IDF3::IDF_UNIT
*/
IDF3::IDF_UNIT GetUnit( void );
/**
* Function SetRefDes
* sets the Reference Designator (RefDes) of this component; the RefDes is shared
* by all outlines associated with this component.
*
* @return bool: true if the RefDes was accepted, otherwise false. Prohibited
* values include empty strings and the word PANEL.
*/
bool SetRefDes( const std::string& aRefDes );
/**
* Function GetRefDes
* Retrieves the Reference Designator (RefDes) of this component
*
* @return string: the Reference Designator
*/
const std::string& GetRefDes( void );
/**
* Function AddDrill
* adds a drill entry to the component and returns its pointer
*
* @param aDia diameter of the drill (mm)
* @param aXpos X position of the drill (mm)
* @param aYpos Y position of the drill (mm)
* @param aPlating plating type (PTH, NPTH)
* @param aHoleType hole class (PIN, VIA, MTG, TOOL, etc)
* @param aOwner owning CAD system (ECAD, MCAD, UNOWNED)
*
* @return pointer: a pointer to the newly created drill entry or NULL
*/
IDF_DRILL_DATA* AddDrill( double aDia, double aXpos, double aYpos,
IDF3::KEY_PLATING aPlating,
const std::string aHoleType,
IDF3::KEY_OWNER aOwner );
/**
* Function AddDrill
* adds the given drill entry to the component and returns the pointer
* to indicate success. A return value of NULL indicates that the item
* was not added and it is the user's responsibility to delete the
* object if necessary.
*
* @param aDrilledHole pointer to a drill entry
*
* @return pointer: aDrilledHole if the function succeeds, otherwise NULL
*/
IDF_DRILL_DATA* AddDrill( IDF_DRILL_DATA* aDrilledHole );
/**
* Function DelDrill( double aDia, double aXpos, double aYpos )
* deletes a drill entry based on its size and location. This operation is
* subject to IDF ownership rules.
*
* @param aDia diameter (mm) of the drilled hole to be deleted
* @param aXpos X position (mm) of the hole to be deleted
* @param aYpos X position (mm) of the hole to be deleted
*
* @return bool: true if a drill was found and deleted, otherwise false.
* If an ownership violation occurs an exception is thrown.
*/
bool DelDrill( double aDia, double aXpos, double aYpos );
/**
* Function DelDrill( IDF_DRILL_DATA* aDrill )
* deletes a drill entry based on pointer. This operation is
* subject to IDF ownership rules.
*
* @param aDrill the pointer associated with the drill entry to be deleted
*
* @return bool: true if a drill was found and deleted, otherwise false.
* If an ownership violation occurs an exception is thrown.
*/
bool DelDrill( IDF_DRILL_DATA* aDrill );
/**
* Function GetDrills
* returns a pointer to the internal list of drills. To avoid IDF
* violations, the user should not alter these entries.
*/
const std::list< IDF_DRILL_DATA* >*const GetDrills( void );
/**
* Function AddOutlineData
* adds the given component outline data to this component
*
* @param aComponentOutline is a pointer to the outline data to be added
*
* @return true if the operation succeedes, otherwise false
*/
bool AddOutlineData( IDF3_COMP_OUTLINE_DATA* aComponentOutline );
/**
* Function DeleteOutlineData( IDF3_COMP_OUTLINE_DATA* aComponentOutline )
* removes outline data based on the pointer provided.
*
* @param aComponentOutline is a pointer to be deleted from the internal list
*
* @return bool: true if the data was found and deleted, otherwise false
*/
bool DeleteOutlineData( IDF3_COMP_OUTLINE_DATA* aComponentOutline );
/**
* Function DeleteOutlineData( size_t aIndex )
* removes outline data based on the provided index.
*
* @param aIndex is an index to the internal outline list
*
* @return bool: true if the data was deleted, false if the
* index was out of bounds.
*/
bool DeleteOutlineData( size_t aIndex );
/**
* Function GetOutlineSize
* returns the number of outlines in the internal list
*/
size_t GetOutlinesSize( void );
/**
* Function GetOutlinesData
* returns a pointer to the internal list of outline data
*/
const std::list< IDF3_COMP_OUTLINE_DATA* >*const GetOutlinesData( void );
/**
* Function GetPosition
* retrieves the internal position parameters and returns true if the
* position was previously set, otherwise false.
*/
bool GetPosition( double& aXpos, double& aYpos, double& aAngle, IDF3::IDF_LAYER& aLayer );
// NOTE: it may be possible to extend this so that internal drills and outlines
// are moved when the component is moved. However there is always a danger of
// position creep due to the relative position updates.
/**
* Function SetPosition
* sets the internal position parameters and returns true if the
* position was set, false if the position was previously set. This object
* does not allow modification of the position once it is set since this may
* adversely affect the relationship with its internal objects.
*
* @param aXpos is the X position (mm) of the component
* @param aYpos is the Y position (mm) of the component
* @param aAngle is the rotation of the component (degrees)
* @param aLayer is the layer on which the component is places (TOP, BOTTOM)
*
* @return bool: true if the position was set, otherwise false
*/
bool SetPosition( double aXpos, double aYpos, double aAngle, IDF3::IDF_LAYER aLayer );
/**
* Function GetPlacement
* returns the IDF placement value of this component (UNPLACED, PLACED, ECAD, MCAD)
*/
IDF3::IDF_PLACEMENT GetPlacement( void );
/**
* Function SetPlacement
* 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
*/
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 );
};
class IDF3_BOARD
{
private:
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
std::list< std::string > placeComments; // comment list for PLACEMENT section
std::list<IDF_DRILL_DATA*> board_drills;
std::map< std::string, IDF3_COMPONENT*> components; // drill and placement data for components
std::map< std::string, IDF3_COMP_OUTLINE*> compOutlines; // component outlines (data for library file)
std::string boardName;
IDF3::FILE_STATE state;
IDF3::CAD_TYPE cadType;
IDF3::IDF_UNIT unit;
std::string idfSource; // SOURCE string to use when writing BOARD and LIBRARY headers
std::string brdSource; // SOURCE string as retrieved from a BOARD file
std::string libSource; // SOURCE string as retrieved from a LIBRARY file
std::string brdDate; // DATE string from BOARD file
std::string libDate; // DATE string from LIBRARY file
int brdFileVersion; // File Version from BOARD file
int libFileVersion; // File Version from LIBRARY file
int userPrec; // user may store any integer here
double userScale; // user may store a scale for translating to arbitrary units
double userXoff; // user may specify an arbitrary X/Y offset
double userYoff;
// main board outline and cutouts
BOARD_OUTLINE olnBoard;
// OTHER outlines
std::map<std::string, OTHER_OUTLINE*> olnOther;
// ROUTE outlines
std::list<ROUTE_OUTLINE*> olnRoute;
// PLACEMENT outlines
std::list<PLACE_OUTLINE*> olnPlace;
// ROUTE KEEPOUT outlines
std::list<ROUTE_KO_OUTLINE*> olnRouteKeepout;
// VIA KEEPOUT outlines
std::list<VIA_KO_OUTLINE*> olnViaKeepout;
// PLACE KEEPOUT outlines
std::list<PLACE_KO_OUTLINE*> olnPlaceKeepout;
// PLACEMENT GROUP outlines
std::multimap<std::string, GROUP_OUTLINE*> olnGroup;
// Set the unit; this can only be done internally upon
// reading a file or saving
bool setUnit( IDF3::IDF_UNIT aUnit, bool convert = false );
IDF_DRILL_DATA* addCompDrill( double aDia, double aXpos, double aYpos,
IDF3::KEY_PLATING aPlating,
const std::string aHoleType,
IDF3::KEY_OWNER aOwner,
const std::string& aRefDes );
IDF_DRILL_DATA* addCompDrill( IDF_DRILL_DATA* aDrilledHole );
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 );
// read the NOTES section
bool readBrdNotes( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
// read the component placement section
bool readBrdPlacement( std::ifstream& aBoardFile, IDF3::FILE_STATE& aBoardState );
// read the board HEADER
bool 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 );
// read the board file data
bool readBoardFile( const std::string& aFileName );
// write the board file data
bool writeBoardFile( const std::string& aFileName );
// read the library sections (outlines)
bool readLibSection( std::ifstream& aLibFile, IDF3::FILE_STATE& aLibState, IDF3_BOARD* aBoard );
// read the library HEADER
bool readLibHeader( std::ifstream& aLibFile, IDF3::FILE_STATE& aLibState );
// read the library file data
bool readLibFile( const std::string& aFileName );
// write the library file data
bool writeLibFile( const std::string& aFileName );
public:
IDF3_BOARD( IDF3::CAD_TYPE aCadType );
virtual ~IDF3_BOARD();
IDF3::CAD_TYPE GetCadType( void );
// retrieve the nominal unit used in reading/writing
// data. This is primarily for use by owned objects
// and is only of informational use for the end user.
// Internally all data is represented in mm and the
// end user must use only mm in the API.
IDF3::IDF_UNIT GetUnit( void );
void SetBoardName( std::string aBoardName );
const std::string& GetBoardName( void );
bool SetBoardThickness( double aBoardThickness );
double GetBoardThickness( void );
bool ReadFile( const wxString& aFullFileName );
bool WriteFile( const wxString& aFullFileName, bool aUnitMM = true, bool aForceUnitFlag = false );
const std::string& GetIDFSource( void );
void SetIDFSource( const std::string& aIDFSource);
const std::string& GetBoardSource( void );
const std::string& GetLibrarySource( void );
const std::string& GetBoardDate( void );
const std::string& GetLibraryDate( void );
int GetBoardVersion( void );
bool SetBoardVersion( int aVersion );
int GetLibraryVersion( void );
bool SetLibraryVersion( int aVersion );
double GetUserScale( void );
bool SetUserScale( double aScaleFactor );
int GetUserPrecision( void );
bool SetUserPrecision( int aPrecision );
void GetUserOffset( double& aXoff, double& aYoff );
void SetUserOffset( double aXoff, double aYoff );
bool AddBoardOutline( IDF_OUTLINE* aOutline );
bool DelBoardOutline( IDF_OUTLINE* aOutline );
bool DelBoardOutline( size_t aIndex );
size_t GetBoardOutlinesSize( void );
BOARD_OUTLINE* GetBoardOutline( void );
const std::list< IDF_OUTLINE* >*const GetBoardOutlines( void );
/// XXX - TO BE IMPLEMENTED
// AddDrillComment
// AddPlacementComment
// GetDrillComments()
// GetPlacementComments()
// ClearDrillComments()
// ClearPlacementComments()
// AddNoteComment
// GetNoteComments
// AddNote
//
// const std::map<std::string, OTHER_OUTLINE*>*const GetOtherOutlines()
// size_t GetOtherOutlinesSize()
// OTHER_OUTLINE* AddOtherOutline( OTHER_OUTLINE* aOtherOutline )
// bool DelOtherOutline( int aIndex )
// bool DelOtherOutline( OTHER_OUTLINE* aOtherOutline )
//
// const std::list<ROUTE_OUTLINE*>*const GetRouteOutlines()
// size_t GetRouteOutlinesSize()
// ROUTE_OUTLINE* AddRouteOutline( ROUTE_OUTLINE* aRouteOutline )
// bool DelRouteOutline( int aIndex )
// bool DelRouteOutline( ROUTE_OUTLINE* aRouteOutline )
//
// const std::list<PLACE_OUTLINE*>*const GetPlacementOutlines()
// size_t GetPlacementOutlinesSize()
// PLACE_OUTLINE* AddPlacementOutline( PLACE_OUTLINE* aPlaceOutline )
// bool DelPlacementOutline( int aIndex )
// bool DelPlacementOutline( PLACE_OUTLINE* aPlaceOutline )
//
// const std::list<ROUTE_KO_OUTLINE*>*const GetRouteKeepOutOutlines()
// size_t GetRouteKeepOutOutlinesSize()
// ROUTE_KO_OUTLINE* AddRouteKeepoutOutline( ROUTE_KO_OUTLINE* aRouteKeepOut )
// bool DelRouteKeepOutOutline( int aIndex )
// bool DelRouteKeepOutOutline( ROUTE_KO_OUTLINE* aRouteKeepOut )
//
// const std::list<VIA_KO_OUTLINE*>*const GetViaKeepOutOutlines()
// size_t GetViaKeepOutOutlinesSize()
// VIA_KO_OUTLINE* AddViaKeepoutOutline( VIA_KO_OUTLINE* aViaKeepOut )
// bool DelViaKeepOutOutline( int aIndex )
// bool DelViaKeepOutOutline( VIA_KO_OUTLINE* aViaKeepOut )
//
// const std::list<PLACE_KO_OUTLINE*>*const GetPlacementKeepOutOutlines()
// size_t GetPlacementKeepOutOutlinesSize()
// PLACE_KO_OUTLINE* AddPlacementKeepoutOutline( PLACE_KO_OUTLINE* aPlaceKeepOut )
// bool DelPlacementKeepOutOutline( int aIndex )
// bool DelPlacementKeepOutOutline( PLACE_KO_OUTLINE* aPlaceKeepOut )
//
// const std::multimap<std::string, GROUP_OUTLINE*>*const GetGroupOutlines()
// size_t GetGroupOutlinesSize()
// GROUP_OUTLINE* AddGroupOutline( GROUP_OUTLINE* aGroupOutline )
// bool DelGroupOutline( int aIndex )
// bool DelGroupOutline( GROUP_OUTLINE* aGroupOutline )
std::list<IDF_DRILL_DATA*>& GetBoardDrills( void )
{
return board_drills;
}
IDF_DRILL_DATA* AddBoardDrill( double aDia, double aXpos, double aYpos,
IDF3::KEY_PLATING aPlating,
const std::string aHoleType,
IDF3::KEY_OWNER aOwner );
IDF_DRILL_DATA* AddDrill( IDF_DRILL_DATA* aDrilledHole );
bool DelBoardDrill( double aDia, double aXpos, double aYpos );
// a slot is a deficient representation of a kicad slotted hole;
// it is usually associated with a component but IDFv3 does not
// provide for such an association.
bool AddSlot( double aWidth, double aLength, double aOrientation, double aX, double aY );
bool AddComponent( IDF3_COMPONENT* aComponent );
bool DelComponent( IDF3_COMPONENT* aComponent );
bool DelComponent( size_t aIndex );
size_t GetComponentsSize( void );
std::map< std::string, IDF3_COMPONENT* >*const GetComponents( void );
IDF3_COMPONENT* FindComponent( std::string aRefDes );
// returns a pointer to a component outline object or NULL
// if the object doesn't exist
IDF3_COMP_OUTLINE* GetComponentOutline( const std::string aGeomName,
const std::string aPartName,
wxString aFullFileName );
// returns a pointer to the component outline object with the
// unique ID aComponentID
IDF3_COMP_OUTLINE* GetComponentOutline( std::string aComponentID );
// returns a pointer to the outline "NOGEOM NOPART" which is substituted
// whenever a true outline cannot be found or is defective
IDF3_COMP_OUTLINE* GetInvalidOutline( const std::string& aGeomName, const std::string& aPartName );
// clears all data
void Clear( void );
};
#endif // IDF_PARSER_H

View File

@ -98,7 +98,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> width) && width >= 0.001 )
tstr >> width;
if( !tstr.fail() && width >= 0.001 )
ok = true;
}
@ -112,7 +114,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> length) && length > 0.0 )
tstr >> length;
if( !tstr.fail() && length > 0.0 )
ok = true;
}
@ -126,7 +130,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> height) && height >= 0.001 )
tstr >> height;
if( !tstr.fail() && height >= 0.001 )
ok = true;
}
@ -140,7 +146,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> chamfer) && chamfer >= 0.0 )
tstr >> chamfer;
if( !tstr.fail() && chamfer >= 0.0 )
{
if( chamfer > width / 3.0 || chamfer > length / 3.0 )
cout << "* WARNING: chamfer must be <= MIN( width, length )/3\n";
@ -182,7 +190,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> wireDia) && wireDia >= 0.001 )
tstr >> wireDia;
if( !tstr.fail() && wireDia >= 0.001 )
{
if( wireDia >= length )
cout << "* WARNING: wire diameter must be < length\n";
@ -201,7 +211,9 @@ int main( int argc, char **argv )
tstr.clear();
tstr.str( line );
if( (tstr >> pitch) && pitch >= 0.001 )
tstr >> pitch;
if( !tstr.fail() && pitch >= 0.001 )
{
if( pitch <= ( length + wireDia ) / 2.0 )
cout << "* WARNING: pitch must be > (length + wireDia)/2\n";

File diff suppressed because it is too large Load Diff

429
utils/idftools/vrml_layer.h Normal file
View File

@ -0,0 +1,429 @@
/*
* file: vrml_layer.h
*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 Cirilo Bernardo
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vrml_layer.h
*/
/*
* Classes and structures to support the tesselation of a
* PCB for VRML output.
*/
#ifndef VRML_BOARD_H
#define VRML_BOARD_H
#ifdef __WXMAC__
# ifdef __DARWIN__
# include <OpenGL/glu.h>
# else
# include <glu.h>
# endif
#else
# include <GL/glu.h>
#endif
#include <fstream>
#include <vector>
#include <list>
#include <utility>
#ifndef M_PI2
#define M_PI2 ( M_PI / 2.0 )
#endif
#ifndef M_PI4
#define M_PI4 ( M_PI / 4.0 )
#endif
struct GLUtesselator;
struct VERTEX_3D
{
double x;
double y;
int i; // vertex index
int o; // vertex order
};
struct TRIPLET_3D
{
int i1, i2, i3;
TRIPLET_3D( int p1, int p2, int p3 )
{
i1 = p1;
i2 = p2;
i3 = p3;
}
};
class VRML_LAYER
{
private:
// Arc parameters
int maxArcSeg; // maximum number of arc segments in a small circle
double minSegLength; // min. segment length
double maxSegLength; // max. segment length
bool fix; // when true, no more vertices may be added by the user
int idx; // vertex index (number of contained vertices)
int ord; // vertex order (number of ordered vertices)
std::vector<VERTEX_3D*> vertices; // vertices of all contours
std::vector<std::list<int>*> contours; // lists of vertices for each contour
std::vector< double > areas; // area of the contours (positive if winding is CCW)
std::list<TRIPLET_3D> triplets; // output facet triplet list (triplet of ORDER values)
std::list<std::list<int>*> outline; // indices for outline outputs (index by ORDER values)
std::vector<int> ordmap; // mapping of ORDER to INDEX
std::string error; // error message
int hidx; // number of vertices in the holes
int eidx; // index for extra vertices
std::vector<VERTEX_3D*> extra_verts; // extra vertices added for outlines and facets
std::vector<VERTEX_3D*> vlist; // vertex list for the GL command in progress
VRML_LAYER* pholes; // pointer to another layer object used for tesselation;
// this object is normally expected to hold only holes
GLUtesselator* tess; // local instance of the GLU tesselator
GLenum glcmd; // current GL command type ( fan, triangle, tri-strip, loop )
void clearTmp( void ); // clear ephemeral data used by the tesselation routine
// add a triangular facet (triplet) to the output index list
bool addTriplet( VERTEX_3D* p0, VERTEX_3D* p1, VERTEX_3D* p2 );
// retrieve a vertex given its index; the vertex may be contained in the
// vertices vector, extra_verts vector, or foreign VRML_LAYER object
VERTEX_3D* getVertexByIndex( int aPointIndex, VRML_LAYER* holes );
void processFan( void ); // process a GL_TRIANGLE_FAN list
void processStrip( void ); // process a GL_TRIANGLE_STRIP list
void processTri( void ); // process a GL_TRIANGLES list
void pushVertices( bool holes ); // push the internal vertices
bool pushOutline( VRML_LAYER* holes ); // push the outline vertices
// calculate number of sides on an arc (angle is in radians)
int calcNSides( double aRadius, double aAngle );
public:
/// set to true when a fault is encountered during tesselation
bool Fault;
VRML_LAYER();
virtual ~VRML_LAYER();
/**
* Function GetArcParams
* retieves the parameters used in calculating the number of vertices in an arc
*
* @param aMaxSeg is the maximum number of segments for an arc with cords of length aMinLength
* @param aMinLength is the minimum length of cords in an arc
* @param aMaxLength is the maximum length of cords in an arc
*/
void GetArcParams( int& aMaxSeg, double& aMinLength, double& aMaxLength );
/**
* Function SetArcParams
* sets the parameters used in calculating the number of vertices in an arc.
* The default settings are reasonable for rendering for unit lengths of 1mm
*
* @param aMaxSeg is the maximum number of segments for an arc with cords of length aMinLength
* @param aMinLength is the minimum length of cords in an arc
* @param aMaxLength is the maximum length of cords in an arc
*
* @return bool: true if the parameters were accepted
*/
bool SetArcParams( int aMaxSeg, double aMinLength, double aMaxLength );
/**
* Function Clear
* erases all data except for arc parameters.
*/
void Clear( void );
/**
* Function GetSize
* returns the total number of vertices indexed
*/
int GetSize( void );
/**
* Function GetNConours
* returns the number of stored contours
*/
int GetNContours( void )
{
return contours.size();
}
/**
* Function NewContour
* creates a new list of vertices and returns an index to the list
*
* @return int: index to the list or -1 if the operation failed
*/
int NewContour( void );
/**
* Function AddVertex
* adds a point to the requested contour
*
* @param aContour is an index previously returned by a call to NewContour()
* @param aXpos is the X coordinate of the vertex
* @param aYpos is the Y coordinate of the vertex
*
* @return bool: true if the vertex was added
*/
bool AddVertex( int aContourID, double aXpos, double aYpos );
/**
* Function EnsureWinding
* checks the winding of a contour and ensures that it is a hole or
* a solid depending on the value of @param hole
*
* @param aContour is an index to a contour as returned by NewContour()
* @param aHoleFlag determines if the contour must be a hole
*
* @return bool: true if the operation suceeded
*/
bool EnsureWinding( int aContourID, bool aHoleFlag );
/**
* Function AppendCircle
* adds a circular contour to the specified (empty) contour
*
* @param aXpos is the X coordinate of the hole center
* @param aYpos is the Y coordinate of the hole center
* @param aRadius is the radius of the hole
* @param aContourID is the contour index
* @param aHoleFlag determines if the contour to be created is a cutout
*
* @return bool: true if the new contour was successfully created
*/
bool AppendCircle( double aXpos, double aYpos, double aRadius, int aContourID, bool aHoleFlag = false );
/**
* Function AddCircle
* creates a circular contour and adds it to the internal list
*
* @param aXpos is the X coordinate of the hole center
* @param aYpos is the Y coordinate of the hole center
* @param aRadius is the radius of the hole
* @param aHoleFlag determines if the contour to be created is a cutout
*
* @return bool: true if the new contour was successfully created
*/
bool AddCircle( double aXpos, double aYpos, double aRadius, bool aHoleFlag = false );
/**
* Function AddSlot
* creates and adds a slot feature to the list of contours
*
* @param aCenterX is the X coordinate of the slot's center
* @param aCenterY is the Y coordinate of the slot's center
* @param aSlotLength is the length of the slot along the major axis
* @param aSlotWidth is the width of the slot along the minor axis
* @param aAngle (degrees) is the orientation of the slot
* @param aHoleFlag determines whether the slot is a hole or a solid
*
* @return bool: true if the slot was successfully created
*/
bool AddSlot( double aCenterX, double aCenterY, double aSlotLength, double aSlotWidth,
double aAngle, bool aHoleFlag = false );
/**
* Function AppendArc
* adds an arc to the specified contour
*
* @param aCenterX is the X coordinate of the arc's center
* @param aCenterY is the Y coordinate of the arc's center
* @param aRadius is the radius of the arc
* @param aStartAngle (degrees) is the starting angle of the arc
* @param aAngle (degrees) is the measure of the arc
* @param aContourID is the contour's index
*
* @return bool: true if the slot was successfully created
*/
bool AppendArc( double aCenterX, double aCenterY, double aRadius,
double aStartAngle, double aAngle, int aContourID );
/**
* Function AddArc
* creates a slotted arc and adds it to the internal list of contours
*
* @param aCenterX is the X coordinate of the arc's center
* @param aCenterY is the Y coordinate of the arc's center
* @param aStartX is the X coordinate of the starting point
* @param aStartY is the Y coordinate of the starting point
* @param aArcWidth is the width of the arc
* @param aAngle is the included angle (degrees)
* @param aHoleFlag determines whether the arc is to be a hole or a solid
*
* @return bool: true if the feature was successfully created
*/
bool AddArc( double aCenterX, double aCenterY, double aStartX, double aStartY,
double aArcWidth, double aAngle, bool aHoleFlag = false );
/**
* Function Tesselate
* creates a list of outline vertices as well as the
* vertex sets required to render the surface.
*
* @param holes is an optional pointer to cutouts to be imposed on the
* surface.
*
* @return bool: true if the operation succeeded
*/
bool Tesselate( VRML_LAYER* holes = NULL );
/**
* Function WriteVertices
* writes out the list of vertices required to render a
* planar surface.
*
* @param aZcoord is the Z coordinate of the plane
* @param aOutFile is the file to write to
* @param aPrecision is the precision of the output coordinates
*
* @return bool: true if the operation succeeded
*/
bool WriteVertices( double aZcoord, std::ofstream& aOutFile, int aPrecision );
/**
* Function Write3DVertices
* writes out the list of vertices required to render an extruded solid
*
* @param aTopZ is the Z coordinate of the top plane
* @param aBottomZ is the Z coordinate of the bottom plane
* @param aOutFile is the file to write to
* @param aPrecision is the precision of the output coordinates
*
* @return bool: true if the operation succeeded
*/
bool Write3DVertices( double aTopZ, double aBottomZ, std::ofstream& aOutFile, int aPrecision );
/**
* Function WriteIndices
* writes out the vertex sets required to render a planar
* surface.
*
* @param aTopFlag is true if the surface is to be visible from above;
* if false the surface will be visible from below.
* @param aOutFile is the file to write to
*
* @return bool: true if the operation succeeded
*/
bool WriteIndices( bool aTopFlag, std::ofstream& aOutFile );
/**
* Function Write3DIndices
* writes out the vertex sets required to render an extruded solid
*
* @param aOutFile is the file to write to
*
* @return bool: true if the operation succeeded
*/
bool Write3DIndices( std::ofstream& aOutFile );
/**
* Function AddExtraVertex
* adds an extra vertex as required by the GLU tesselator
*
* @return VERTEX_3D*: is the new vertex or NULL if a vertex
* could not be created.
*/
VERTEX_3D* AddExtraVertex( double aXpos, double aYpos );
/**
* Function glStart
* is invoked by the GLU tesselator callback to notify this object
* of the type of GL command which is applicable to the upcoming
* vertex list.
*
* @param cmd is the GL command
*/
void glStart( GLenum cmd );
/**
* Function glPushVertex
* is invoked by the GLU tesselator callback; the supplied vertex is
* added to the internal list of vertices awaiting processing upon
* execution of glEnd()
*
* @param vertex is a vertex forming part of the GL command as previously
* set by glStart
*/
void glPushVertex( VERTEX_3D* vertex );
/**
* Function glEnd
* is invoked by the GLU tesselator callback to notify this object
* that the vertex list is complete and ready for processing
*/
void glEnd( void );
/**
* Function SetGLError
* sets the error message according to the specified OpenGL error
*/
void SetGLError( GLenum error_id );
/**
* Function Import
* inserts all contours into the given tesselator; this
* results in the renumbering of all vertices from @param start.
* Take care when using this call since tesselators cannot work on
* the internal data concurrently.
*
* @param start is the starting number for vertex indices
* @param tess is a pointer to a GLU Tesselator object
*
* @return int: the number of vertices exported
*/
int Import( int start, GLUtesselator* tess );
/**
* Function GetVertexByIndex
* returns a pointer to the requested vertex or
* NULL if no such vertex exists.
*
* @param aPointIndex is a vertex index
*
* @return VERTEX_3D*: the requested vertex or NULL
*/
VERTEX_3D* GetVertexByIndex( int aPointIndex );
/*
* Function GetError
* Returns the error message related to the last failed operation
*/
const std::string& GetError( void );
};
#endif // VRML_BOARD_H