1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2014 Cirilo Bernardo
5  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 #include <cstdio>
26 #include <iostream>
27 #include <sstream>
28 #include <string>
29 #include <list>
30 #include <dxf2idf.h>
31 
32 using namespace std;
33 
main(int argc,char ** argv)34 int main( int argc, char **argv )
35 {
36     list< string > comments;
37     string line;
38     stringstream tstr;
39 
40     string dname;           // DXF filename
41     string gname;           // Geometry Name
42     string pname;           // Part Name
43     double height;          // extrusion height
44     bool   inch = false;    // true = inches, false = mm
45     bool   ok;
46 
47     if( argc == 1 )
48     {
49         // no arguments; print out usage information
50         cout << "dxf2idf: this program takes line, arc, and circle segments\n";
51         cout << "         from a DXF file and creates an IDF component outline file.\n\n";
52         cout << "Input:\n";
53         cout << "         DXF filename: the input file, must end in '.dxf'\n";
54         cout << "         Units: mm, in (millimeters or inches)\n";
55         cout << "         Geometry Name: string, as per IDF version 3.0 specification\n";
56         cout << "         Part Name: as per IDF version 3.0 specification of Part Number\n";
57         cout << "         Height: extruded height of the outline\n";
58         cout << "         Comments: all non-empty lines are comments to be added to\n";
59         cout << "                   the IDF file. An empty line signifies the end of\n";
60         cout << "                   the comment block.\n";
61         cout << "         File name: output filename, must end in '.idf'\n\n";
62     }
63 
64     line.clear();
65 
66     while( line.empty() || line.find( ".dxf" ) == string::npos )
67     {
68         cout << "* DXF filename: ";
69 
70         line.clear();
71         std::getline( cin, line );
72     }
73 
74     dname = line;
75 
76     line.clear();
77 
78     while( line.compare( "mm" ) && line.compare( "in" )
79         && line.compare( "MM" ) && line.compare( "IN" ) )
80     {
81         cout << "* Units (mm,in): ";
82         line.clear();
83         std::getline( cin, line );
84     }
85 
86     if( line.compare( "mm" ) && line.compare( "MM" ) )
87         inch = true;
88 
89     line.clear();
90 
91     while( line.empty() )
92     {
93         cout << "* Geometry name: ";
94         line.clear();
95         std::getline( cin, line );
96 
97         if( line.find( '\"' ) != string::npos )
98         {
99             cerr << "[INFO] geometry name may not contain quotation marks\n";
100             line.clear();
101         }
102     }
103 
104     gname = line;
105 
106     line.clear();
107 
108     while( line.empty() )
109     {
110         cout << "* Part name: ";
111         line.clear();
112         std::getline( cin, line );
113 
114         if( line.find( '\"' ) != string::npos )
115         {
116             cerr << "[INFO] part name may not contain quotation marks\n";
117             line.clear();
118         }
119     }
120 
121     pname = line;
122 
123     ok = false;
124 
125     while( !ok )
126     {
127         cout << "* Height: ";
128 
129         line.clear();
130         std::getline( cin, line );
131 
132         tstr.clear();
133         tstr.str( line );
134 
135         tstr >> height;
136 
137         if( !tstr.fail() && height > 0.001 )
138             ok = true;
139     }
140 
141     cout << "* COMMENTS: any non-blank line is a comment;\n";
142     cout << "            a blank line signifies the end of comments.\n";
143     ok = false;
144 
145     while( !ok )
146     {
147         line.clear();
148         std::getline( cin, line );
149 
150         if( line.empty() )
151         {
152             ok = true;
153         }
154         else
155         {
156             if( line[0] != '#' )
157                 line.insert( 0, "# " );
158 
159             comments.push_back( line );
160         }
161     }
162 
163     line.clear();
164 
165     while( line.empty() || line.find( ".idf" ) == string::npos )
166     {
167         cout << "* File name (*.idf): ";
168 
169         line.clear();
170         std::getline( cin, line );
171     }
172 
173     DXF2IDF dxf;
174 
175     dxf.ReadDxf( dname.c_str() );
176 
177     FILE* fp = fopen( line.c_str(), "w" );
178 
179     list< string >::const_iterator scom = comments.begin();
180     list< string >::const_iterator ecom = comments.end();
181 
182     while( scom != ecom )
183     {
184         fprintf( fp, "%s\n", (*scom).c_str() );
185         ++scom;
186     }
187 
188     fprintf( fp, ".ELECTRICAL\n" );
189 
190     if( inch )
191         fprintf( fp, "\"%s\" \"%s\" THOU %d\n", gname.c_str(), pname.c_str(),
192                  (int) ( height * 1000.0 ) );
193     else
194         fprintf( fp, "\"%s\" \"%s\" MM %.3f\n", gname.c_str(), pname.c_str(), height );
195 
196     dxf.WriteOutline( fp, inch );
197 
198     fprintf( fp, ".END_ELECTRICAL\n" );
199 
200     return 0;
201 }
202