Add patch about idf export (from cirilo_bernardo)
This commit is contained in:
parent
e585f2d205
commit
6652bcdc5f
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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";
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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
|
@ -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
|
@ -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
|
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue