2
* This program source code file is part of KiCad, a free EDA CAD application.
4
* Copyright (C) 2014 Cirilo Bernardo
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, you may find one here:
18
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19
* or you may search the http://www.gnu.org website for the version 2 license,
20
* or you may write to the Free Software Foundation, Inc.,
21
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25
* This program creates an outline for a horizontal or vertically
26
* oriented axial or radial leaded cylinder with dimensions based
27
* on the user's input.
42
void make_vcyl( bool inch, bool axial, double dia, double length,
43
double z, double wireDia );
45
void make_hcyl( bool inch, bool axial, double dia, double length,
46
double z, double wireDia );
48
void writeAxialCyl( FILE* fp, bool inch, double dia, double length, double wireDia, double pitch );
50
void writeRadialCyl( FILE* fp, bool inch, double dia, double length, double wireDia,
51
double pitch, double lead );
53
int main( int argc, char **argv )
55
// IDF implicitly requires the C locale
56
setlocale( LC_ALL, "C" );
60
cout << "idfcyl: This program generates an outline for a cylindrical component.\n";
61
cout << " The cylinder may be horizontal or vertical.\n";
62
cout << " A horizontal cylinder may have wires at one or both ends.\n";
63
cout << " A vertical cylinder may have at most one wire which may be\n";
64
cout << " placed on the left or right side.\n\n";
66
cout << " Unit: mm, in (millimeters or inches)\n";
67
cout << " Orientation: V (vertical)\n";
68
cout << " Lead type: X, R (axial, radial)\n";
69
cout << " Diameter of body\n";
70
cout << " Length of body\n";
71
cout << " Board offset\n";
72
cout << " * Wire diameter\n";
74
cout << " ** Wire side: L, R (left, right)\n";
75
cout << " *** Lead length\n";
76
cout << " File name (must end in *.idf)\n\n";
78
cout << " * only required for horizontal orientation or\n";
79
cout << " vertical orientation with axial leads\n\n";
80
cout << " ** only required for vertical orientation with axial leads\n\n";
81
cout << " *** only required for horizontal orientation with radial leads\n\n";
84
char orientation = '\0';
85
bool inch = false; // default mm
96
while( line.compare( "mm" ) && line.compare( "in" ) )
98
cout << "* Units (mm,in): ";
100
std::getline( cin, line );
103
if( line.compare( "mm" ) )
107
while( line.compare( "H" ) && line.compare( "h" )
108
&& line.compare( "V" ) && line.compare( "v" ) )
110
cout << "* Orientation (H,V): ";
112
std::getline( cin, line );
115
if( line.compare( "H" ) && line.compare( "h" ) )
124
cout << "* Axial or Radial (X,R): ";
127
std::getline( cin, line );
129
if( !line.compare( "x" ) || !line.compare( "X" ) )
134
else if( !line.compare( "r" ) || !line.compare( "R" ) )
141
// cylinder dimensions
145
cout << "* Diameter: ";
148
std::getline( cin, line );
152
if( (tstr >> dia) && dia > 0.0 )
159
cout << "* Length: ";
162
std::getline( cin, line );
166
if( (tstr >> length) && length > 0.0 )
173
cout << "* Board offset: ";
176
std::getline( cin, line );
180
if( (tstr >> extraZ) && extraZ > 0.0 )
185
while( ( axial || orientation == 'h' ) && !ok )
187
cout << "* Wire diameter: ";
190
std::getline( cin, line );
194
if( (tstr >> wireDia) && wireDia > 0.0 )
199
cout << "* WARNING: wire diameter must be < cylinder diameter\n";
203
switch( orientation )
206
make_vcyl( inch, axial, dia, length, extraZ, wireDia );
209
make_hcyl( inch, axial, dia, length, extraZ, wireDia );
215
setlocale( LC_ALL, "" );
220
void make_vcyl( bool inch, bool axial, double dia, double length,
221
double z, double wireDia )
230
while( axial && !ok )
235
std::getline( cin, line );
239
if( (tstr >> pitch) && pitch > 0.0 )
241
if( (pitch - wireDia) <= (dia / 2.0) )
243
cout << "* WARNING: Pitch must be > dia/2 + wireDia\n";
253
while( axial && !ok )
255
cout << "* Pin side (L,R): ";
258
std::getline( cin, line );
260
if( !line.compare( "l" ) || !line.compare( "L" ) )
265
else if( !line.compare( "r" ) || !line.compare( "R" ) )
270
while( line.empty() || line.find( ".idf" ) == string::npos )
272
cout << "* File name (*.idf): ";
275
std::getline( cin, line );
278
FILE* fp = fopen( line.c_str(), "w" );
282
cerr << "Could not open output file: " << line << "\n";
286
fprintf( fp, "# cylindrical outline, vertical, " );
289
fprintf( fp, "radial leads\n" );
291
fprintf( fp, "axial lead on %s\n", left ? "left" : "right" );
293
fprintf( fp, "# file: \"%s\"\n", line.c_str() );
297
fprintf( fp, "# dia: %d THOU\n", (int) (dia * 1000) );
298
fprintf( fp, "# length: %d THOU\n", (int) (length * 1000) );
299
fprintf( fp, "# board offset: %d THOU\n", (int) (z * 1000) );
303
fprintf( fp, "# wire dia: %d THOU\n", (int) (wireDia * 1000) );
304
fprintf( fp, "# pitch: %d THOU\n", (int) (pitch * 1000) );
309
fprintf( fp, "# dia: %.3f mm\n", dia );
310
fprintf( fp, "# length: %.3f mm\n", length );
311
fprintf( fp, "# board offset: %.3f mm\n", z );
315
fprintf( fp, "# wire dia: %.3f mm\n", wireDia );
316
fprintf( fp, "# pitch: %.3f mm\n", pitch );
320
fprintf( fp, ".ELECTRICAL\n" );
324
fprintf( fp, "\"CYLV_%s_RAD\" \"D%.3f_H%.3f_Z%.3f\" ", inch ? "IN" : "MM",
329
fprintf( fp, "\"CYLV_%s_AX%s\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f\" ", inch ? "IN" : "MM",
330
left ? "L" : "R", dia, length, z, wireDia, pitch );
334
fprintf( fp, "THOU %d\n", (int) ((length + z) * 1000) );
336
fprintf( fp, "MM %.3f\n", length + z );
340
fprintf( fp, "0 0 0 0\n" );
343
fprintf( fp, "0 %d 0 360\n", (int) (dia * 1000) );
345
fprintf( fp, "0 %.3f 0 360\n", dia );
347
fprintf( fp, ".END_ELECTRICAL\n" );
355
// [0] = upper point on cylinder perimeter
356
// [1] = lower point on cylinder perimeter
357
// [2] = point beneath wire center
358
// [3] = point above wire center
367
double ang = asin( wireDia / dia );
368
px[0] = dia * cos( ang ) / 2.0 - pitch / 2.0;
373
py[0] = wireDia / 2.0;
380
double fullAng = 360.0;
386
for( int i = 0; i < 4; ++i ) px[i] = -px[i];
392
fprintf( fp, "%c %d %d 0\n", li, (int) px[0], (int) py[0] );
393
fprintf( fp, "%c %d %d %.3f\n", li, (int) px[1], (int) py[1],
394
fullAng * ( 1 - ang / M_PI ) );
395
fprintf( fp, "%c %d %d 0\n", li, (int) px[2], (int) py[2] );
396
fprintf( fp, "%c %d %d %s\n", li, (int) px[3], (int) py[3],
397
left ? "-180" : "180" );
398
fprintf( fp, "%c %d %d 0\n", li, (int) px[0], (int) py[0] );
402
fprintf( fp, "%c %.3f %.3f 0\n", li, px[0], py[0] );
403
fprintf( fp, "%c %.3f %.3f %.3f\n", li, px[1], py[1], fullAng * ( 1 - ang / M_PI ) );
404
fprintf( fp, "%c %.3f %.3f 0\n", li, px[2], py[2] );
405
fprintf( fp, "%c %.3f %.3f %s\n", li, px[3], py[3],
406
left ? "-180" : "180" );
407
fprintf( fp, "%c %.3f %.3f 0\n", li, px[0], py[0] );
410
fprintf( fp, ".END_ELECTRICAL\n" );
416
void make_hcyl( bool inch, bool axial, double dia, double length,
417
double z, double wireDia )
424
double lead = 0.0; // lead length for radial leads
430
cout << "* Axial pitch: ";
432
cout << "* Radial pitch: ";
435
std::getline( cin, line );
439
if( (tstr >> pitch) && pitch > 0.0 )
443
if( (pitch - wireDia) <= length )
445
cout << "* WARNING: Axial pitch must be > length + wireDia\n";
454
if( (pitch + wireDia) >= dia )
456
cout << "* WARNING: Radial pitch must be < dia - wireDia\n";
458
else if( pitch <= wireDia )
460
cout << "* WARNING: Radial pitch must be > wireDia\n";
471
while( !axial && !ok )
473
cout << "* Lead length: ";
476
std::getline( cin, line );
480
if( (tstr >> lead) && lead > 0.0 )
483
cout << "* WARNING: lead length must be >= wireDia\n";
490
while( line.empty() || line.find( ".idf" ) == string::npos )
492
cout << "* File name (*.idf): ";
495
std::getline( cin, line );
498
FILE* fp = fopen( line.c_str(), "w" );
502
cerr << "Could not open output file: " << line << "\n";
506
fprintf( fp, "# cylindrical outline, horiz., " );
508
fprintf( fp, "%s pins\n", axial ? "axial" : "radial" );
510
fprintf( fp, "# file: \"%s\"\n", line.c_str() );
514
fprintf( fp, "# dia: %d THOU\n", (int) (dia * 1000) );
515
fprintf( fp, "# length: %d THOU\n", (int) (length * 1000) );
516
fprintf( fp, "# extra height: %d THOU\n", (int) (z * 1000) );
517
fprintf( fp, "# wire dia: %d THOU\n", (int) (wireDia * 1000) );
518
fprintf( fp, "# pitch: %d THOU\n", (int) (pitch * 1000) );
520
fprintf( fp, "# lead: %d THOU\n", (int) (lead * 1000) );
524
fprintf( fp, "# dia: %.3f mm\n", dia );
525
fprintf( fp, "# length: %.3f mm\n", length );
526
fprintf( fp, "# extra height: %.3f mm\n", z );
527
fprintf( fp, "# wire dia: %.3f mm\n", wireDia );
528
fprintf( fp, "# pitch: %.3f mm\n", pitch );
530
fprintf( fp, "# lead: %.3f mm\n", lead );
533
fprintf( fp, ".ELECTRICAL\n" );
537
fprintf( fp, "\"CYLH_%s_AXI\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f\" ",
538
inch ? "IN" : "MM", dia, length, z, wireDia, pitch );
542
fprintf( fp, "\"CYLH_%s_RAD\" \"D%.3f_H%.3f_Z%.3f_WD%.3f_P%.3f_L%.3f\" ",
543
inch ? "IN" : "MM", dia, length, z, wireDia, pitch, lead );
548
fprintf( fp, "THOU %d\n", (int) ((dia + z) * 1000) );
558
fprintf( fp, "MM %.3f\n", dia + z );
562
writeAxialCyl( fp, inch, dia, length, wireDia, pitch );
564
writeRadialCyl( fp, inch, dia, length, wireDia, pitch, lead );
566
fprintf( fp, ".END_ELECTRICAL\n" );
572
void writeAxialCyl( FILE* fp, bool inch, double dia, double length,
573
double wireDia, double pitch )
585
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y1 );
586
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y2 );
587
fprintf( fp, "0 %d %d 0\n", (int) x2, (int) y2 );
588
fprintf( fp, "0 %d %d 180\n", (int) x2, (int) -y2 );
589
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) -y2 );
590
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) -y1 );
591
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) -y1 );
592
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) -y2 );
593
fprintf( fp, "0 %d %d 0\n", (int) -x2, (int) -y2 );
594
fprintf( fp, "0 %d %d 180\n", (int) -x2, (int) y2 );
595
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y2 );
596
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y1 );
597
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y1 );
601
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
602
fprintf( fp, "0 %.3f %.3f 0\n", x1, y2 );
603
fprintf( fp, "0 %.3f %.3f 0\n", x2, y2 );
604
fprintf( fp, "0 %.3f %.3f 180\n", x2, -y2 );
605
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y2 );
606
fprintf( fp, "0 %.3f %.3f 0\n", x1, -y1 );
607
fprintf( fp, "0 %.3f %.3f 0\n", -x1, -y1 );
608
fprintf( fp, "0 %.3f %.3f 0\n", -x1, -y2 );
609
fprintf( fp, "0 %.3f %.3f 0\n", -x2, -y2 );
610
fprintf( fp, "0 %.3f %.3f 180\n", -x2, y2 );
611
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y2 );
612
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
613
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
619
void writeRadialCyl( FILE* fp, bool inch, double dia, double length,
620
double wireDia, double pitch, double lead )
626
// center is between the mounting holes
627
// which are on a horizontal line
631
x2 = ( pitch + wireDia ) /2.0;
636
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y1 );
637
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y2 );
638
fprintf( fp, "0 %d %d 0\n", (int) -x2, (int) y2 );
639
fprintf( fp, "0 %d 0 0\n", (int) -x2 );
640
fprintf( fp, "0 %d 0 180\n", (int) -x3 );
641
fprintf( fp, "0 %d %d 0\n", (int) -x3, (int) y2 );
642
fprintf( fp, "0 %d %d 0\n", (int) x3, (int) y2 );
643
fprintf( fp, "0 %d 0 0\n", (int) x3 );
644
fprintf( fp, "0 %d 0 180\n", (int) x2 );
645
fprintf( fp, "0 %d %d 0\n", (int) x2, (int) y2 );
646
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y2 );
647
fprintf( fp, "0 %d %d 0\n", (int) x1, (int) y1 );
648
fprintf( fp, "0 %d %d 0\n", (int) -x1, (int) y1 );
652
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );
653
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y2 );
654
fprintf( fp, "0 %.3f %.3f 0\n", -x2, y2 );
655
fprintf( fp, "0 %.3f 0 0\n", -x2 );
656
fprintf( fp, "0 %.3f 0 180\n", -x3 );
657
fprintf( fp, "0 %.3f %.3f 0\n", -x3, y2 );
658
fprintf( fp, "0 %.3f %.3f 0\n", x3, y2 );
659
fprintf( fp, "0 %.3f 0 0\n", x3 );
660
fprintf( fp, "0 %.3f 0 180\n", x2 );
661
fprintf( fp, "0 %.3f %.3f 0\n", x2, y2 );
662
fprintf( fp, "0 %.3f %.3f 0\n", x1, y2 );
663
fprintf( fp, "0 %.3f %.3f 0\n", x1, y1 );
664
fprintf( fp, "0 %.3f %.3f 0\n", -x1, y1 );