0b2d4d4879
Recommendation is to avoid using the year nomenclature as this information is already encoded in the git repo. Avoids needing to repeatly update. Also updates AUTHORS.txt from current repo with contributor names
443 lines
12 KiB
C++
443 lines
12 KiB
C++
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 2014 Cirilo Bernardo
|
|
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
|
*
|
|
* 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 <iostream>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <list>
|
|
#include <utility>
|
|
#include <clocale>
|
|
|
|
using namespace std;
|
|
|
|
void writeLeaded( FILE* fp, double width, double length, double wireDia, double pitch, bool inch );
|
|
|
|
void writeLeadless( FILE* fp, double width, double length, double chamfer, bool inch );
|
|
|
|
int main( int argc, char** argv )
|
|
{
|
|
// IDF implicitly requires the C locale
|
|
setlocale( LC_ALL, "C" );
|
|
|
|
if( argc == 1 )
|
|
{
|
|
cout << "idfrect: This program generates an outline for a rectangular component.\n";
|
|
cout << " The component may have a single lead (axial) or a chamfer on the\n";
|
|
cout << " upper left corner.\n";
|
|
cout << "Input:\n";
|
|
cout << " Unit: mm, in (millimeters or inches)\n";
|
|
cout << " Width:\n";
|
|
cout << " Length:\n";
|
|
cout << " Height:\n";
|
|
cout << " Chamfer: length of the 45 deg. chamfer\n";
|
|
cout << " * Leaded: Y,N (lead is always to the right)\n";
|
|
cout << " ** Wire diameter\n";
|
|
cout << " ** Pitch\n";
|
|
cout << " File name (must end in *.idf)\n\n";
|
|
cout << " NOTES:\n";
|
|
cout << " * only required if chamfer = 0\n\n";
|
|
cout << " ** only required for leaded components\n\n";
|
|
}
|
|
|
|
bool inch = false; // default mm
|
|
double width = 0.0;
|
|
double length = 0.0;
|
|
double height = 0.0;
|
|
double wireDia = 0.0;
|
|
double pitch = 0.0;
|
|
double chamfer = 0.0;
|
|
bool leaded = false;
|
|
bool ok = false;
|
|
|
|
stringstream tstr;
|
|
string line;
|
|
|
|
line.clear();
|
|
|
|
while( line.compare( "mm" ) && line.compare( "in" ) )
|
|
{
|
|
cout << "* Units (mm,in): ";
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
}
|
|
|
|
if( line.compare( "mm" ) )
|
|
inch = true;
|
|
|
|
ok = false;
|
|
|
|
while( !ok )
|
|
{
|
|
cout << "* Width: ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
tstr.clear();
|
|
tstr.str( line );
|
|
|
|
tstr >> width;
|
|
|
|
if( !tstr.fail() && width >= 0.001 )
|
|
ok = true;
|
|
}
|
|
|
|
ok = false;
|
|
|
|
while( !ok )
|
|
{
|
|
cout << "* Length: ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
tstr.clear();
|
|
tstr.str( line );
|
|
|
|
tstr >> length;
|
|
|
|
if( !tstr.fail() && length > 0.0 )
|
|
ok = true;
|
|
}
|
|
|
|
ok = false;
|
|
|
|
while( !ok )
|
|
{
|
|
cout << "* Height: ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
tstr.clear();
|
|
tstr.str( line );
|
|
|
|
tstr >> height;
|
|
|
|
if( !tstr.fail() && height >= 0.001 )
|
|
ok = true;
|
|
}
|
|
|
|
ok = false;
|
|
|
|
while( !ok )
|
|
{
|
|
cout << "* Chamfer (0 for none): ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
tstr.clear();
|
|
tstr.str( line );
|
|
|
|
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";
|
|
else
|
|
ok = true;
|
|
}
|
|
}
|
|
|
|
if( chamfer < 1e-6 )
|
|
{
|
|
ok = false;
|
|
|
|
while( !ok )
|
|
{
|
|
cout << "* Leaded: Y, N: ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
if( !line.compare( "Y" ) || !line.compare( "y" ) )
|
|
{
|
|
leaded = true;
|
|
ok = true;
|
|
}
|
|
else if( !line.compare( "N" ) || !line.compare( "n" ) )
|
|
{
|
|
leaded = false;
|
|
ok = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
ok = false;
|
|
|
|
while( leaded && !ok )
|
|
{
|
|
cout << "* Wire dia.: ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
tstr.clear();
|
|
tstr.str( line );
|
|
|
|
tstr >> wireDia;
|
|
|
|
if( !tstr.fail() && wireDia >= 0.001 )
|
|
{
|
|
if( wireDia >= length )
|
|
cout << "* WARNING: wire diameter must be < length\n";
|
|
else
|
|
ok = true;
|
|
}
|
|
}
|
|
|
|
ok = false;
|
|
|
|
while( leaded && !ok )
|
|
{
|
|
cout << "* Pitch: ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
|
|
tstr.clear();
|
|
tstr.str( line );
|
|
|
|
tstr >> pitch;
|
|
|
|
if( !tstr.fail() && pitch >= 0.001 )
|
|
{
|
|
if( pitch <= ( length + wireDia ) / 2.0 )
|
|
cout << "* WARNING: pitch must be > (length + wireDia)/2\n";
|
|
else
|
|
ok = true;
|
|
}
|
|
}
|
|
|
|
line.clear();
|
|
|
|
while( line.empty() || line.find( ".idf" ) == string::npos )
|
|
{
|
|
cout << "* File name (*.idf): ";
|
|
|
|
line.clear();
|
|
std::getline( cin, line );
|
|
}
|
|
|
|
FILE* fp = fopen( line.c_str(), "w" );
|
|
|
|
if( !fp )
|
|
{
|
|
cerr << "Could not open output file: " << line << "\n";
|
|
}
|
|
else
|
|
{
|
|
fprintf( fp, "# rectangular outline%s\n", leaded ? ", leaded" : "" );
|
|
fprintf( fp, "# file: \"%s\"\n", line.c_str() );
|
|
|
|
if( inch )
|
|
{
|
|
width *= 1000.0;
|
|
length *= 1000.0;
|
|
height *= 1000.0;
|
|
wireDia *= 1000.0;
|
|
pitch *= 1000.0;
|
|
chamfer *= 1000.0;
|
|
|
|
fprintf( fp, "# width: %d THOU\n", (int) width );
|
|
fprintf( fp, "# length: %d THOU\n", (int) length );
|
|
fprintf( fp, "# height: %d THOU\n", (int) height );
|
|
|
|
if( leaded )
|
|
{
|
|
fprintf( fp, "# wire dia: %d THOU\n", (int) wireDia );
|
|
fprintf( fp, "# pitch: %d THOU\n", (int) pitch );
|
|
}
|
|
else
|
|
{
|
|
fprintf( fp, "# chamfer: %d THOU\n", (int) chamfer );
|
|
}
|
|
|
|
fprintf( fp, ".ELECTRICAL\n" );
|
|
fprintf( fp, "\"RECT%sIN\" \"W%d_L%d_H%d", leaded ? "L" : "", (int) width, (int) length,
|
|
(int) height );
|
|
|
|
if( leaded )
|
|
fprintf( fp, "_D%d_P%d\" ", (int) wireDia, (int) pitch );
|
|
else
|
|
fprintf( fp, "_C%d\" ", (int) chamfer );
|
|
|
|
fprintf( fp, "THOU %d\n", (int) height );
|
|
}
|
|
else
|
|
{
|
|
fprintf( fp, "# width: %.3f mm\n", width );
|
|
fprintf( fp, "# length: %.3f mm\n", length );
|
|
fprintf( fp, "# height: %.3f mm\n", height );
|
|
|
|
if( leaded )
|
|
{
|
|
fprintf( fp, "# wire dia: %.3f mm\n", wireDia );
|
|
fprintf( fp, "# pitch: %.3f mm\n", pitch );
|
|
}
|
|
else
|
|
{
|
|
fprintf( fp, "# chamfer: %.3f mm\n", chamfer );
|
|
}
|
|
|
|
fprintf( fp, ".ELECTRICAL\n" );
|
|
fprintf( fp, "\"RECT%sMM\" \"W%.3f_L%.3f_H%.3f_", leaded ? "L" : "", width, length,
|
|
height );
|
|
|
|
if( leaded )
|
|
fprintf( fp, "D%.3f_P%.3f\" ", wireDia, pitch );
|
|
else
|
|
fprintf( fp, "C%.3f\" ", chamfer );
|
|
|
|
fprintf( fp, "MM %.3f\n", height );
|
|
}
|
|
|
|
if( leaded )
|
|
writeLeaded( fp, width, length, wireDia, pitch, inch );
|
|
else
|
|
writeLeadless( fp, width, length, chamfer, inch );
|
|
|
|
fprintf( fp, ".END_ELECTRICAL\n" );
|
|
fclose( fp );
|
|
}
|
|
|
|
setlocale( LC_ALL, "" );
|
|
return 0;
|
|
}
|
|
|
|
|
|
void writeLeaded( FILE* fp, double width, double length, double wireDia, double pitch, bool inch )
|
|
{
|
|
if( inch )
|
|
{
|
|
int x1, x2, x3;
|
|
int y1, y2;
|
|
|
|
x1 = static_cast<int>( pitch / 2.0 );
|
|
x2 = static_cast<int>( width / 2.0 - x1 );
|
|
x3 = static_cast<int>( x2 - width );
|
|
|
|
y1 = static_cast<int>( wireDia / 2.0 );
|
|
y2 = static_cast<int>( length / 2.0 );
|
|
|
|
fprintf( fp, "0 %d %d 0\n", x1, y1 );
|
|
fprintf( fp, "0 %d %d 0\n", x2, y1 );
|
|
fprintf( fp, "0 %d %d 0\n", x2, y2 );
|
|
fprintf( fp, "0 %d %d 0\n", x3, y2 );
|
|
fprintf( fp, "0 %d %d 0\n", x3, -y2 );
|
|
fprintf( fp, "0 %d %d 0\n", x2, -y2 );
|
|
fprintf( fp, "0 %d %d 0\n", x2, -y1 );
|
|
fprintf( fp, "0 %d %d 0\n", x1, -y1 );
|
|
fprintf( fp, "0 %d %d 180\n", x1, y1 );
|
|
}
|
|
else
|
|
{
|
|
double x1, x2, x3;
|
|
double y1, y2;
|
|
|
|
x1 = pitch / 2.0;
|
|
x2 = width / 2.0 - x1;
|
|
x3 = x2 - width;
|
|
|
|
y1 = wireDia / 2.0;
|
|
y2 = length / 2.0;
|
|
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x2, y1 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x2, y2 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x3, y2 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x3, -y2 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x2, -y2 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x2, -y1 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y1 );
|
|
fprintf( fp, "0 %.3f %.3f 180\n", x1, y1 );
|
|
}
|
|
}
|
|
|
|
|
|
void writeLeadless( FILE* fp, double width, double length, double chamfer, bool inch )
|
|
{
|
|
if( chamfer < 0.001 )
|
|
{
|
|
if( inch )
|
|
{
|
|
int x = static_cast<int>( width / 2.0 );
|
|
int y = static_cast<int>( length / 2.0 );
|
|
|
|
fprintf( fp, "0 %d %d 0\n", x, y );
|
|
fprintf( fp, "0 %d %d 0\n", -x, y );
|
|
fprintf( fp, "0 %d %d 0\n", -x, -y );
|
|
fprintf( fp, "0 %d %d 0\n", x, -y );
|
|
fprintf( fp, "0 %d %d 0\n", x, y );
|
|
}
|
|
else
|
|
{
|
|
double x = width / 2.0;
|
|
double y = length / 2.0;
|
|
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", -x, y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", -x, -y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x, -y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if( inch )
|
|
{
|
|
int x = static_cast<int>( width / 2.0 );
|
|
int y = static_cast<int>( length / 2.0 );
|
|
int x1 = static_cast<int>( x - chamfer );
|
|
int y1 = static_cast<int>( y - chamfer );
|
|
|
|
fprintf( fp, "0 %d %d 0\n", x, y );
|
|
fprintf( fp, "0 %d %d 0\n", -x1, y );
|
|
fprintf( fp, "0 %d %d 0\n", -x, y1 );
|
|
fprintf( fp, "0 %d %d 0\n", -x, -y );
|
|
fprintf( fp, "0 %d %d 0\n", x, -y );
|
|
fprintf( fp, "0 %d %d 0\n", x, y );
|
|
}
|
|
else
|
|
{
|
|
double x = width / 2.0;
|
|
double y = length / 2.0;
|
|
double x1 = x - chamfer;
|
|
double y1 = y - chamfer;
|
|
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", -x, y1 );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", -x, -y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x, -y );
|
|
fprintf( fp, "0 %.3f %.3f 0\n", x, y );
|
|
}
|
|
}
|