Last active
January 7, 2021 10:45
-
-
Save kaysond/9d6f1a648098ed2c4d6fc179952db29f to your computer and use it in GitHub Desktop.
import-dxf-v2.1.ulp - an updated Eagle ULP for DXF imports that supports multiple output layers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#usage "<b>DXFimport</b> V2.1<p>" | |
"This ULP can import DXF files that include polylines.<br>" | |
"Browse to the DXF file, setup your origins, input units, scale factor and linewidth then click convert. " | |
"The ULP will then show you the script in case you want to change the layer the input will be written to.<br>" | |
"Tested in version 5, 6, 7, and Autodesk EAGLE.<br><br>" | |
"Command line syntax:<br> run import-dxf.ulp filename TargetLayer Units [options]<br><br>" | |
"TargetLayer is number from 1-255 that corresponds to the layer that you want the imported features to be drawn on." | |
"If TargetLayer is set to '0 MultiLayer', StartLayer is a number from 1-255 that corresponds to the first layer to be drawn on. Each different layer in the DXF will be drawn on subsequent EAGLE layers" | |
"Units is a number where 0 means imperial units and 1 means metric units." | |
"[options] contains 5 additional arguments that are optional and not required by default." | |
"Xorg is the origin X coordinate of the new location you want the drawing to import to." | |
"Yorg is the origin Y coordinate of the new location you want the drawing to import to." | |
"lwidth is the width of the lines used to draw the dxf objects." | |
"scale allows you increase or decrease the dimensions of the dxf by a user defined factor." | |
"The second to last argument is a three digit number indicating if the Xorg, Yorg, and width should be scaled. The value for each is" | |
"either zero or 1 where zero means don't scale and 1 means scale." | |
"The last argument is the StartLayer, which is used only if TargetLayer is 0 (defaults to 200).<br><br>" | |
"A complete example would be:<br>" | |
"run import-dxf.ulp C:\\myfile.dxf 20 0 1.2 3.1 0.001 1.5 001<br><br>" | |
"myfile.dxf is being imported to layer 20 with imperial units, the new origin is at (1.2 3.1) the linewidth is 0.001 inches." | |
"The dxf file is being scaled by a factor of 1.5 with the Xorg and Yorg not being scaled but the linewidth being scaled by 1.5 also." | |
"When running the ULP through the command line the previous settings are not loaded." | |
"<author>Written by Jorge Garcia of Cadsoft Computer, heavily based off of Hank Wallace's DXF2SCR program.</author><br>" | |
"With special thanks to Robert Starr, Alfred Zaffran, Billy Coleman, Holger Moessinger." | |
string Version = "2.1"; | |
string Help = "<b>DXFimport "+Version+ "</b>\n <p>This ULP will import a DXF \ | |
file into EAGLE (Board, Schematic, Package or Symbol-Editor). \ | |
Use the browse button to find the DXF file, make sure to set \ | |
the units to whatever units are used by the DXF file. Set the width, Xorg, and \ | |
Yorg in whatever units you selected. Then set an appropriate scale factor and \ | |
click the OK button, the generated script will be shown for editing. Once \ | |
it's adjusted to your liking click Run.</p>\n run import-dxf.ulp filename TargetLayer Units [options]\n \ | |
<p>TargetLayer is number from 1-255 that corresponds to the layer that you want the imported features to be drawn on. \ | |
If TargetLayer is set to '0 MultiLayer', StartLayer is a number from 1-255 that corresponds to the first layer to be drawn on. Each different layer in the DXF will be drawn on subsequent EAGLE layers. \ | |
Units is a number 0 means imperial units and 1 means metric units. \ | |
[options] contains 5 additional arguments that are optional and not required by default. \ | |
Xorg is the X coordinate of the new location you want the drawing to import to. \ | |
Yorg is the Y coordinate of the new location you want the drawing to import to. Linewidth allows you to \ | |
pick the width of the lines used to draw the dxf objects. Scale allows you increase or decrease the dimensions of the dxf by a user defined factor. \ | |
The second to last argument is a three digit number indicating if the Xorg, Yorg, and width should be scaled. The value for each is \ | |
either zero or 1 where zero means don't scale and 1 means scale. \ | |
The last argument is the StartLayer, which is used only if TargetLayer is 0 (defaults to 200).</p>\n \ | |
A complete example would be:\n \ | |
run import-dxf.ulp C:\\myfile.dxf 20 0 1.2 3.1 0.001 1.5 001\n \ | |
myfile.dxf is being imported to layer 20 with imperial units, the new origin is at (1.2 3.1) the linewidth is 0.001 inches. \ | |
The dxf file is being scaled by a factor of 1.5 with the Xorg and Yorg not being scaled but the linewidth being scaled by 1.5 also. \ | |
When running from the command line settings are not stored."; | |
/* ******************************************************************* | |
REVISION HISTORY | |
2012-03-03 Initial Release. | |
2012-06-19 Finally incorporated Holger Moessinger's improvements to | |
the polygon import, added him to special thanks section. | |
2012-07-10 Added support for LWPOLYLINE. | |
2013-02-13 Check maximum coodinate of eagle, Alfred Zaffran. This | |
feature keeps track of the size of the DXF file, if it's | |
outside the drawing limits of EAGLE the ULP will recognize | |
this and suggest a corrective offset which the user can | |
approve. | |
2013-06-12 Discovered that some files don't implement the proper | |
spacing so I modified the ULP to cope with that. | |
2014-03-12 Implemented the ability to skip the section search state. | |
Some DXF files don't have an ENTITIES section which the old | |
ULP expected. This allows the ULP to try going through the | |
file again without expecting an ENTITIES section. The | |
downside is that some extraneous stuff may come in on the | |
import but usually the user will be able to tell and remove | |
those features. The generated script file has a comment | |
added to it when EAGLE uses that feature. | |
2014-03-12 Assimilated Billy Coleman's scaling functionality. Added | |
him to the thank you list in the description. | |
2014-03-13 Implemented a flag in the LWPOLYLINE state of dxf() to | |
make sure the state isn't exited, before processing the | |
object. Similar improvements where made in the VERTEX | |
state of DXF. | |
2015-02-10 make target layer selectable [email protected] | |
2017-04-06 fixed critical LWPOLYLINE bug JG | |
2017-06-05 fixed subtle LWPOLYLINE bug where a value of 0 causes | |
the LWPOLYLINE object to be exited early. JG | |
2017-08-18 Added command line support. JG | |
2019-03-07 Added MultiLayer support. Aram Akhavan | |
********************************************************************* */ | |
/* *********************************************************************** | |
Below I have retained Mr. Wallace's original "licensing" statement for two | |
reasons: | |
1. As a sign of respect for the original author of the code from which this | |
ULP was developed and without which it would have not been possible to | |
develop this ULP. | |
2. This is quite possibly the funniest licensing statement any one will | |
ever read. | |
Officially though, I will license this under the MIT open software license | |
copied below: | |
Copyright (c) 2012 Newark, Premier Farnell DBA Cadsoft Computer | |
Permission is hereby granted, free of charge, to any person obtaining a copy of | |
this software and associated documentation files (the "Software"), to deal in | |
the Software without restriction, including without limitation the rights to | |
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | |
of the Software, and to permit persons to whom the Software is furnished to | |
do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | |
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | |
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
Jorge Garcia | |
03-Mar-2012 | |
---------------------------------------------------------------------- | |
DXF2SCR.C | |
Program that crunches a DXF file with circles, arcs and lines into an | |
Eagle script file, useful for translating board outlines. | |
Hank Wallace 20-Mar-03 | |
Revision 20-Mar-03 | |
There are two licensing options for this program: | |
1. If you are a fan of the GNU license, and you think you | |
understand it, and you think it is reasonable, and you believe | |
that 'free to download' means 'high quality' or 'low maintenance | |
cost', and you are a computer geek who cannot get a date who | |
measures the value of his/her existence by the number of | |
marginally useful command line options you can stuff into one | |
program on a lonely Friday night, and you write C source code in | |
such a manner that there are more #define'd constants and | |
conditional compilation directives than there are actual C | |
source statements, and you attempt to make your programs so | |
'portable' that they runs on no machine whatsoever without | |
modification, then you have no license to use this software. Get | |
a life. | |
2. If you one of the other 6 billion people on planet Earth, | |
this program source code and executable is free for your use | |
without restriction, but NO WARRANTY OR SUPPORT IS GIVEN. | |
This program compiles under Microsoft's command line compiler, version 12.00. | |
----------------------------------------------------------------------------- | |
************************************************************************** */ | |
/* ************************************************************************ | |
* GLOBAL VARIABLES | |
************************************************************************** */ | |
//include "debug.ulp" | |
string ConfigFileName = filesetext(argv[0], ".cfg"); | |
real XMax; /* Maximum dimensions of DXF file */ | |
real YMax; | |
real XMin; | |
real YMin; | |
real Exmax = REAL_MAX; /* Maximum dimensions EAGLE can draw in um */ | |
real Eymax = REAL_MAX; | |
real Exmin = -REAL_MAX; | |
real Eymin = -REAL_MAX; | |
real S_factor; | |
real GUI_scale = 1.0; /* Additional scale factor that can be used to resize dxf */ | |
int GUI_in_unit = 0; | |
int GUI_scaled_Xorg = 0; /* Checkbox variables */ | |
int GUI_scaled_Yorg = 0; | |
int GUI_scaled_lwidth = 0; | |
string GUI_script; | |
string GUI_fileName; | |
real GUI_Xorg = 0.0; | |
real GUI_Yorg = 0.0; | |
real GUI_lwidth = 0.001; | |
string GUI_layers[]; | |
GUI_layers[0] = "0 MultiLayer"; | |
int GUI_layerselect = 0; | |
int GUI_layerstart = 200; | |
string LayerMap[]; | |
int LayerMapLength = 0; | |
int Lcnt = 1; | |
int GUI_TargetLayer = 0; | |
int SavedTargetLayer = 0; | |
/* | |
******************************************************************************* | |
* NON-GUI FUNCTIONS | |
******************************************************************************* | |
*/ | |
/* | |
******************************************************************************* | |
* strcomp2() | |
* | |
* Description: The purpose of this function is to take the input scompare and | |
* compare it to strings s1 and s2 for an exact match. If there is | |
* no match to either string it will return -1, if there is a match | |
* to one of the strings it will return the index of the | |
* corresponding strstr function that succeeded. | |
* | |
* The strstr function checks to see if a substring shows up within | |
* a given string, if it does it gives the index where the | |
* substring shows up within the string. This is not enough to | |
* ensure an exact match. To ensure an exact match we would need | |
* the length of the strings to be the the same. | |
* | |
* Arguments: scompare String to be compared | |
* s1 First item to match | |
* s2 Second item to match | |
* | |
* Return: -1 If there is no match | |
* int If there is a match corresponding to index of strstr | |
* function that succeeded | |
* | |
* Caller: dxf | |
* | |
******************************************************************************* | |
*/ | |
int strcomp2(string scompare, string s1, string s2) { | |
int result = strstr(scompare, s1); | |
if(result != -1 && strlen(scompare) == strlen(s1)) { | |
return result; | |
} | |
else { | |
result = strstr(scompare, s2); | |
if (result != -1 && strlen(scompare) == strlen(s2)) { | |
return result; | |
} | |
else { | |
return -1; | |
} | |
} | |
} | |
/* | |
******************************************************************************* | |
* mx() and my() | |
* | |
* Description: These functions below are used to find the extreme XY points of | |
* the DXF file we're importing. This info will later be used to | |
* make sure the file fits inside the drawing area of EAGLE. They | |
* modify the drawing Max and Min variables in order to find the | |
* size of the imported drawing | |
* | |
* Arguments: real Real x or y value | |
* | |
* Return: real The original x or y value that was passed | |
* | |
* Caller: dxf | |
* | |
******************************************************************************* | |
*/ | |
real mx(real x) { | |
if (XMax < x) XMax = x; | |
if (XMin > x) XMin = x; | |
return x; | |
} | |
real my(real y) { | |
if (YMax < y) YMax = y; | |
if (YMin > y) YMin = y; | |
return y; | |
} | |
/*2019-03-07 | |
******************************************************************************* | |
* searchlayermap() | |
* | |
* Description: This function searches the layer map created by createlayermap() | |
* | |
* Arguments: layer The layer name to search | |
* | |
* Return: -1 If the layer name is not found | |
* int Index of the layer name if it is found | |
* | |
* Caller: dxf | |
* | |
******************************************************************************* | |
*/ | |
int searchlayermap(string layer) { | |
int idx; | |
if (LayerMapLength > 0) { | |
for (idx = 0; idx < LayerMapLength; idx++) { | |
if (strstr(LayerMap[idx], layer) != -1 && strlen(LayerMap[idx]) == strlen(layer)) { | |
return idx; | |
} | |
} | |
} | |
return -1; | |
} | |
/*2019-03-07 | |
******************************************************************************* | |
* createlayermap() | |
* | |
* Description: This function takes a DXF file path and processes it to produce | |
* an array of DXF layer names whose indices correspond to EAGLE layers | |
* Unfortunately its necessary to load into a global variable since ULP's | |
* can't pass arrays or return them | |
* | |
* Arguments: dxffile Path to the DXF file to be processed | |
* ent Skips the search for sections and entities, | |
* useful for files that don't strictly follow | |
* the DXF format. | |
* | |
* Return: string Returns a script command that adds user layers if necessary | |
* | |
* Caller: dxf | |
* | |
******************************************************************************* | |
*/ | |
string createlayermap(string dxffile, int ent) { | |
string s[]; // This string array will store the DXF file | |
string out; // Out is the script generated by this function | |
string temp; // Place holder | |
string stemp[]; // Place holder for string manipulation | |
string LayerName; // Output layer name | |
enum { state_SECTION, | |
state_ENTITIES, | |
state_SEARCH, | |
state_LINE, | |
state_ARC, | |
state_CIRCLE, | |
state_POLYLINE, | |
state_VERTEX, | |
state_LWPOLYLINE}; // Defines states for the main state machine | |
int state; | |
int nlines; | |
LayerMapLength = 0; | |
out = "# Creating layer map\n"; | |
if (ent >= 1) { // Allows the section search to be disabled | |
state = state_SEARCH; | |
out += "# Skipped Section Search\n"; | |
} | |
else { | |
state = state_SECTION; | |
} | |
nlines = fileread(s, dxffile); | |
for (int m = 0; m < nlines;m++) { | |
switch (state) { | |
case state_SECTION: // scan for SECTIONS in the DXF file | |
if (strstr(s[m],"SECTION") != -1) { | |
if (ent >= 1) { | |
state = state_SEARCH; | |
} | |
else { | |
state = state_ENTITIES; | |
} | |
} | |
break; | |
case state_ENTITIES: // scan for ENTITIES in the DXF file | |
if (strstr(s[m],"ENDSEC") != -1) { | |
state = state_SECTION; | |
} | |
if (strstr(s[m],"ENTITIES") != -1) { | |
state = state_SEARCH; | |
} | |
break; | |
case state_SEARCH: // scanning for LINE, ARC, CIRCLE, POLYLINE, SPLINE | |
if (strstr(s[m],"ENDSEC") != -1) { | |
if (ent >= 1) { | |
state = state_SEARCH; | |
} | |
else { | |
state = state_SECTION; | |
} | |
} | |
if (strstr(s[m],"LINE") != -1 && strlen(s[m]) == 4) { | |
state = state_LINE; | |
} | |
if (strstr(s[m],"ARC") != -1 && strlen(s[m]) == 3) { | |
state = state_ARC; | |
} | |
if (strstr(s[m],"CIRCLE") != -1 && strlen(s[m]) == 6) { | |
state = state_CIRCLE; | |
} | |
if (strstr(s[m],"POLYLINE") != -1 && strlen(s[m]) == 8) { | |
state = state_POLYLINE; | |
} | |
if (strstr(s[m],"LWPOLYLINE") != -1 && strlen(s[m]) == 10) { // JG Support for LWPOLYLINE added 07/09/2012 | |
state = state_LWPOLYLINE; | |
} | |
break; | |
case state_LINE: | |
case state_ARC: | |
case state_CIRCLE: | |
case state_POLYLINE: | |
case state_LWPOLYLINE: | |
if (strcomp2(s[m], " 8", "8") != -1 || (strstr(s[m], " 8") != -1 && strlen(s[m]) == 3)) { | |
if (searchlayermap(s[m+1]) == -1) { | |
LayerMap[LayerMapLength++] = s[m+1]; | |
if (GUI_layerstart + LayerMapLength > 99) { | |
int LayerNum = GUI_layerstart + LayerMapLength - 1; | |
// Remove spaces from layer name; not sure if necessary | |
strsplit(stemp, s[m+1], ' '); | |
LayerName = strjoin(stemp, '_'); | |
sprintf(temp, "#%s\nLAYER %d %ddxf-%s;\n", s[m+1], LayerNum, LayerNum, LayerName); | |
sprintf(temp, "%sSET FILL_LAYER %d 10;\n", temp, LayerNum); | |
sprintf(temp, "%sSET COLOR_LAYER %d %d;\n", temp, LayerNum, LayerMapLength); | |
out += temp; | |
} | |
} | |
state = state_SEARCH; | |
} | |
break; | |
} //case state | |
} //for lines | |
return out; | |
} //createlayermap() | |
/* | |
******************************************************************************* | |
* dxf() | |
* | |
* Description: This function takes a DXF file path and processes it to produce | |
* a script full of commands to draw the contents of the DXF file | |
* in EAGLE. | |
* | |
* Arguments: dxffile Path to the DXF file to be processed | |
* units Units of the DXF file | |
* xorigin User defined offset in the X direction | |
* yorigin User defined offset in the Y direction | |
* liwidth User defined line width | |
* ent Skips the search for sections and entities, | |
* useful for files that don't strictly follow | |
* the DXF format. | |
* scale Optional scaling factor to increase or decrease | |
* the size of the DXF file | |
* | |
* Return: string A long string full of EAGLE commands | |
* | |
* Caller: checkscript | |
* | |
******************************************************************************* | |
*/ | |
string dxf(string dxffile, int units, real xorigin, real yorigin, real liwidth, int ent, real scale) { | |
string s[]; // This string array will store the DXF file | |
string out; // Out is the script generated by this function | |
string temp; // Place holder | |
enum { state_SECTION, | |
state_ENTITIES, | |
state_SEARCH, | |
state_LINE, | |
state_ARC, | |
state_CIRCLE, | |
state_POLYLINE, | |
state_VERTEX, | |
state_LWPOLYLINE}; // Defines states for the main state machine | |
enum { order_LAYER, | |
order_FIRST, | |
order_SECOND, | |
order_THIRD, | |
order_FOURTH, | |
order_FIFTH}; // Defines states for the secondary state machines | |
int i; // index variable for xa and ya | |
int p; // dummy variable for for loop | |
int m; // dummy variable for main while loop | |
int nlines; // number of lines in the text file | |
int state; | |
int order; // Used for internal state machines | |
int lines; | |
int arcs; | |
int circles; | |
int polylines; | |
int linewidth=1; | |
int LWPOLY_FLAG=1; // See comment in LWPOLYLINE state | |
int layernum; | |
real x; | |
real y; | |
real x1; | |
real y1; | |
real x2; | |
real y2; | |
real x3; | |
real y3; | |
real r; | |
real theta1; | |
real theta3; | |
real xorg; | |
real yorg; | |
real xa[]; // xa and ya arrays hold the possible vertexes of a polyline | |
real ya[]; | |
real plclosed; | |
real bulgevalue[]; // plclosed and bulgevalue array helps in dealing with... | |
// ... closed polylines | |
if (units == 1) { // Setup unit scale factor | |
S_factor = 1000; // Convert mm to um | |
XMax = u2mm(INT_MIN)*S_factor; | |
YMax = u2mm(INT_MIN)*S_factor; | |
XMin = u2mm(INT_MAX)*S_factor; | |
YMin = u2mm(INT_MAX)*S_factor; | |
} | |
else { | |
S_factor = 25400; // Convert in to um | |
XMax = u2inch(INT_MIN)*S_factor; | |
YMax = u2inch(INT_MIN)*S_factor; | |
XMin = u2inch(INT_MAX)*S_factor; | |
YMin = u2inch(INT_MAX)*S_factor; | |
} | |
linewidth = liwidth * S_factor; | |
xorg = xorigin * S_factor; | |
yorg = yorigin * S_factor; | |
S_factor *= scale; // Added scale factor affects everything except xorg, ... | |
// ... yorg and linewidth those are handled by the GUI | |
out += "# dxfimport generated script file.\n"; | |
out += "Grid mic 1 off;\n"; | |
out += "Set Wire_Bend 2;\n"; | |
if (GUI_TargetLayer == 0) { | |
out += createlayermap(dxffile, ent); | |
} | |
else { | |
sprintf(temp, "CHANGE LAYER %d;\n", GUI_TargetLayer); // 2015-02-10 | |
out += temp; | |
} | |
out += "Change Font Vector;\n"; | |
if (ent >= 1) { // Allows the section search to be disabled | |
state = state_SEARCH; | |
out += "# Skipped Section Search\n"; | |
} | |
else { | |
state = state_SECTION; | |
} | |
order = order_LAYER; | |
lines = arcs = circles = polylines = 0; | |
nlines = fileread(s, dxffile); | |
for (m = 0;m < nlines;m++) { | |
switch (state) { | |
case state_SECTION: // scan for SECTIONS in the DXF file | |
if (strstr(s[m],"SECTION") != -1) { | |
if (ent >= 1) { | |
state = state_SEARCH; | |
} | |
else { | |
state = state_ENTITIES; | |
} | |
} | |
break; | |
case state_ENTITIES: // scan for ENTITIES in the DXF file | |
if (strstr(s[m],"ENDSEC") != -1) { | |
state = state_SECTION; | |
} | |
if (strstr(s[m],"ENTITIES") != -1) { | |
state = state_SEARCH; | |
} | |
break; | |
case state_SEARCH: // scanning for LINE, ARC, CIRCLE, POLYLINE, SPLINE | |
if (strstr(s[m],"ENDSEC") != -1) { | |
if (ent >= 1) { | |
state = state_SEARCH; | |
} | |
else { | |
state = state_SECTION; | |
} | |
} | |
if (strstr(s[m],"LINE") != -1 && strlen(s[m]) == 4) { | |
state = state_LINE; | |
lines++; | |
} | |
if (strstr(s[m],"ARC") != -1 && strlen(s[m]) == 3) { | |
state = state_ARC; | |
arcs++; | |
} | |
if (strstr(s[m],"CIRCLE") != -1 && strlen(s[m]) == 6) { | |
state = state_CIRCLE; | |
circles++; | |
} | |
if (strstr(s[m],"POLYLINE") != -1 && strlen(s[m]) == 8) { | |
i=0; | |
state = state_POLYLINE; | |
polylines++; | |
} | |
if (strstr(s[m],"LWPOLYLINE") != -1 && strlen(s[m]) == 10) { | |
i=0; // JG Support for LWPOLYLINE added 07/09/2012 | |
state = state_LWPOLYLINE; | |
polylines++; | |
} | |
break; | |
case state_LINE: // absorbing LINE | |
switch(order) { // LINE 8, 10, 20, 30 (start point), 11, 21, 31 (end point). | |
case order_LAYER: | |
if (GUI_TargetLayer == 0) { | |
if (strcomp2(s[m], " 8", "8") != -1 || (strstr(s[m], " 8") != -1 && strlen(s[m]) == 3)) { | |
layernum = searchlayermap(s[m+1]); | |
if (layernum != -1) { | |
sprintf(temp, "LAYER %d\n", GUI_layerstart + layernum); | |
out += temp; | |
} | |
else { | |
out += "# Could not determine layer from map\n"; | |
} | |
order = order_FIRST; | |
} | |
break; | |
} | |
case order_FIRST: | |
if (strcomp2(s[m], " 10", "10") != -1) { | |
x = S_factor*strtod(s[m+1]); | |
order = order_SECOND; | |
} | |
break; | |
case order_SECOND: | |
if (strcomp2(s[m], " 20", "20") != -1) { | |
y = S_factor*strtod(s[m+1]); | |
order = order_THIRD; | |
} | |
break; | |
case order_THIRD: | |
if (strcomp2(s[m], " 11", "11") != -1) { | |
x1 = S_factor*strtod(s[m+1]); | |
order = order_FOURTH; | |
} | |
break; | |
case order_FOURTH: | |
if (strcomp2(s[m], " 21", "21") != -1) { | |
y1 = S_factor*strtod(s[m+1]); | |
sprintf(temp, "Wire %d (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(x+xorg), | |
my(y+yorg), | |
mx(x1+xorg), | |
my(y1+yorg) | |
); | |
out += temp; // Write to script | |
state = state_SEARCH; | |
order = order_LAYER; | |
} | |
break; | |
} | |
break; | |
case state_ARC: // absorbing ARC | |
switch(order) { // ARC 8, 10, 20, 30 (center), 40 (radius), 50 (start angle), 51 (end) | |
case order_LAYER: | |
if (GUI_TargetLayer == 0) { | |
if (strcomp2(s[m], " 8", "8") != -1 || (strstr(s[m], " 8") != -1 && strlen(s[m]) == 3)) { | |
layernum = searchlayermap(s[m+1]); | |
if (layernum != -1) { | |
sprintf(temp, "LAYER %d\n", GUI_layerstart + layernum); | |
out += temp; | |
} | |
else { | |
out += "# Could not determine layer from map\n"; | |
} | |
order = order_LAYER; | |
} | |
break; | |
} | |
case order_FIRST: | |
if (strcomp2(s[m], " 10", "10") != -1) { | |
x = S_factor*strtod(s[m+1]); | |
order = order_SECOND; | |
} | |
break; | |
case order_SECOND: | |
if (strcomp2(s[m], " 20", "20") != -1) { | |
y = S_factor*strtod(s[m+1]); | |
order = order_THIRD; | |
} | |
break; | |
case order_THIRD: | |
if (strcomp2(s[m], " 40", "40") != -1) { | |
r = S_factor*strtod(s[m+1]); | |
order = order_FOURTH; | |
} | |
break; | |
case order_FOURTH: | |
if (strcomp2(s[m], " 50", "50") != -1) { | |
theta1 = strtod(s[m+1]); | |
theta1 *= (PI/180); | |
order = order_FIFTH; | |
} | |
break; | |
case order_FIFTH: | |
if (strcomp2(s[m], " 51", "51") != -1) { | |
theta3 = strtod(s[m+1]); | |
theta3 *= (PI/180); | |
x1 = r*cos(theta1)+x; // compute Eagle arc parameters from DXF arc params | |
y1 = r*sin(theta1)+y; | |
x2 = x1-2*r*cos(theta1); | |
y2 = y1-2*r*sin(theta1); | |
x3 = r*cos(theta3)+x; | |
y3 = r*sin(theta3)+y; | |
sprintf(temp, "Arc CCW %d (%0.2f %0.2f) (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(x1+xorg), | |
my(y1+yorg), | |
mx(x2+xorg), | |
my(y2+yorg), | |
mx(x3+xorg), | |
my(y3+yorg) | |
); | |
out += temp; | |
state = state_SEARCH; | |
order = order_LAYER; | |
} | |
break; | |
} | |
break; | |
case state_CIRCLE: // absorbing CIRCLE | |
switch(order) { // CIRCLE 8, 10, 20, 30 (center), 40 (radius). | |
case order_LAYER: | |
if (GUI_TargetLayer == 0) { | |
if (strcomp2(s[m], " 8", "8") != -1 || (strstr(s[m], " 8") != -1 && strlen(s[m]) == 3)) { | |
layernum = searchlayermap(s[m+1]); | |
if (layernum != -1) { | |
sprintf(temp, "LAYER %d\n", GUI_layerstart + layernum); | |
out += temp; | |
} | |
else { | |
out += "# Could not determine layer from map\n"; | |
} | |
order = order_FIRST; | |
} | |
break; | |
} | |
case order_FIRST: | |
if (strcomp2(s[m], " 10", "10") != -1) { | |
x = S_factor*strtod(s[m+1]); | |
order = order_SECOND; | |
} | |
break; | |
case order_SECOND: | |
if (strcomp2(s[m], " 20", "20") != -1) { | |
y = S_factor*strtod(s[m+1]); | |
order = order_THIRD; | |
} | |
break; | |
case order_THIRD: | |
if (strcomp2(s[m], " 40", "40") != -1) { | |
y1 = S_factor*strtod(s[m+1]); | |
sprintf(temp, "Circle %d (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(x+xorg), | |
my(y+yorg), | |
mx(x+xorg), | |
my(y+y1+yorg) | |
); | |
out += temp; | |
state = state_SEARCH; | |
order = order_LAYER; | |
} | |
break; | |
} | |
break; | |
case state_POLYLINE: // absorbing POLYLINE | |
if (GUI_TargetLayer == 0) { | |
if (strcomp2(s[m], " 8", "8") != -1 || (strstr(s[m], " 8") != -1 && strlen(s[m]) == 3)) { | |
layernum = searchlayermap(s[m+1]); | |
if (layernum != -1) { | |
sprintf(temp, "LAYER %d\n", GUI_layerstart + layernum); | |
out += temp; | |
} | |
else { | |
out += "# Could not determine layer from map\n"; | |
} | |
} | |
} | |
if (strstr(s[m], "VERTEX") != -1) { // VERTEX | |
state = state_VERTEX; | |
} | |
if (strcomp2(s[m], " 70", "70") != -1) { // EDIT HM 20120425: Determine if Polyline is closed and... | |
plclosed = strtod(s[m+1]); // ...take care of bulge values for line segments. | |
} | |
if (strstr(s[m], "SEQEND") != -1) { | |
for (p=0; p < i-1;p++) { // n points give n-1 lines that's why there's an i-1 in... | |
if (bulgevalue[p] != 0) { // ...the conditional | |
sprintf(temp, "Wire %d (%0.2f %0.2f) %+0.2f (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
(atan(bulgevalue[p])*180/PI*4), | |
mx(xa[p+1]+xorg), | |
my(ya[p+1]+yorg) | |
); | |
out += temp; | |
} | |
else { | |
sprintf(temp, "Wire %d (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
mx(xa[p+1]+xorg), | |
my(ya[p+1]+yorg) | |
); | |
out += temp; | |
} | |
} | |
if(plclosed) { | |
if(bulgevalue[p] != 0) { | |
sprintf(temp, "Wire %d (%0.2f %0.2f) %+0.2f (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
(atan(bulgevalue[p])*180/PI*4), | |
mx(xa[0]+xorg), | |
my(ya[0]+yorg) | |
); | |
out += temp; | |
} | |
else { | |
sprintf(temp, "Wire %d (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
mx(xa[0]+xorg), | |
my(ya[0]+yorg) | |
); | |
out += temp; | |
} | |
} | |
state = state_SEARCH; | |
} | |
break; | |
case state_VERTEX: // absorbing VERTEX | |
switch(order) { | |
case order_LAYER: // layer should show up in polyline state | |
case order_FIRST: | |
if (strcomp2(s[m], " 10", "10") != -1) { // 10 (x-value) 20 (y-value) | |
xa[i] = S_factor*strtod(s[m+1]); | |
order = order_SECOND; | |
} | |
break; | |
case order_SECOND: | |
if (strcomp2(s[m], " 20", "20") != -1) { | |
ya[i] = S_factor*strtod(s[m+1]); // This avoids a misalignment of the bulge array should... | |
bulgevalue[i] = 0; // ...one or more polylines not have bulges | |
order = order_THIRD; | |
} | |
break; | |
case order_THIRD: | |
if (strcomp2(s[m], " 42", "42") != -1) { | |
bulgevalue[i] = strtod(s[m+1]); //* Store bulge value for node | |
} | |
if (strcomp2(s[m], " 0", "0") != -1) { | |
i++; | |
state = state_POLYLINE; // Look for next vertex in polyline | |
order = order_LAYER; | |
} | |
break; | |
} | |
break; | |
case state_LWPOLYLINE: // absorbing LWPOLYLINE 07/09/2012 | |
if (GUI_TargetLayer == 0) { | |
if (strcomp2(s[m], " 8", "8") != -1 || (strstr(s[m], " 8") != -1 && strlen(s[m]) == 3)) { | |
layernum = searchlayermap(s[m+1]); | |
if (layernum != -1) { | |
sprintf(temp, "LAYER %d\n", GUI_layerstart + layernum); | |
out += temp; | |
} | |
else { | |
out += "# Could not determine layer from map\n"; | |
} | |
} | |
} | |
if (strcomp2(s[m], " 70", "70") != -1) { // Checks for closed polylines and imports them. | |
plclosed = strtod(s[m+1]); | |
} | |
if (strcomp2(s[m], " 10", "10") != -1) { | |
xa[i] = S_factor*strtod(s[m+1]); | |
m = m+1; //By doing this I'm having the for loop move to the next untouched | |
//line. This avoids a bug where a value of 0 for any of the | |
//LWPOLY attributes will cause it to exit prematurely JG 06/05/2017 | |
//the next few states have similar lines. I set the value to the | |
//line of the currently processed data that way when the for loop | |
//comes around it will increment to the next line automatically. | |
} | |
if (strcomp2(s[m], " 20", "20") != -1) { | |
LWPOLY_FLAG = 0; // On poorly formated files, this state may run into an | |
// improperly formatted zero and exit without | |
// processing any points. This flag guarantees that | |
// the state will not be exited before points are | |
// processed. See the if statement below. | |
ya[i] = S_factor*strtod(s[m+1]); | |
if (strcomp2(s[m+2], " 42", "42") == -1) { // No bulge value | |
bulgevalue[i] = 0; | |
m = m+1; // See comments on line 624 | |
i++; // This avoids a misalignment of the bulge array should | |
} // one or more polylines not have bulges. | |
if (strcomp2(s[m+2], " 42", "42") != -1) { | |
bulgevalue[i] = strtod(s[m+3]); // Store bulge value for node | |
i++; | |
m = m+3; // See comments on line 624 | |
} | |
} | |
if (strcomp2(s[m], " 0", "0") != -1 & LWPOLY_FLAG == 0) { | |
for (p=0; p < i-1;p++) { // n points give n-1 lines that's why there's an i-1 in | |
if (bulgevalue[p] != 0) { // the conditional. | |
sprintf(temp, "Wire %d (%0.2f %0.2f) %+0.2f (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
(atan(bulgevalue[p])*(180/PI)*4), | |
mx(xa[p+1]+xorg), | |
my(ya[p+1]+yorg) | |
); | |
out += temp; | |
} | |
else { | |
sprintf(temp, "Wire %d (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
mx(xa[p+1]+xorg), | |
my(ya[p+1]+yorg) | |
); | |
out += temp; | |
} | |
} | |
if(plclosed) { | |
if(bulgevalue[p] != 0) { | |
sprintf(temp, "Wire %d (%0.2f %0.2f) %+0.2f (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
(atan(bulgevalue[p])*180/PI*4), | |
mx(xa[0]+xorg), | |
my(ya[0]+yorg) | |
); | |
out += temp; | |
} | |
else { | |
sprintf(temp, "Wire %d (%0.2f %0.2f) (%0.2f %0.2f);\n", | |
linewidth, | |
mx(xa[p]+xorg), | |
my(ya[p]+yorg), | |
mx(xa[0]+xorg), | |
my(ya[0]+yorg) | |
); | |
out += temp; | |
} | |
} | |
state = state_SEARCH; | |
LWPOLY_FLAG = 1; | |
} | |
break; | |
} | |
} | |
sprintf(temp, "Window Fit;\n"); | |
out += temp; | |
sprintf(temp, "# lines=%d, arcs=%d, circles=%d, polylines=%d\n", | |
lines, | |
arcs, | |
circles, | |
polylines | |
); | |
out += temp; | |
out += "Grid last;"; | |
return out; | |
} | |
/* | |
******************************************************************************** | |
* GUI FUNCTIONS | |
******************************************************************************** | |
*/ | |
/* | |
******************************************************************************* | |
* get_project_path() | |
* | |
* Description: Returns project path, if in board or schematic, otherwise | |
* it will return the library path | |
* | |
* Arguments: none | |
* | |
* Return: p String containing full path of project | |
* | |
* Caller: runscript | |
* | |
******************************************************************************* | |
*/ | |
string get_project_path() { | |
string s = "", p = "";; | |
if (library) { library(L) s = L.name;} | |
if (board) { board(B) s = B.name;} | |
if (schematic){ schematic(S) s = S.name;} | |
char c = '/'; | |
int pos = strrchr(s, c); | |
if (pos >= 0) { | |
p = strsub(s, 0, pos + 1); | |
} | |
return p; | |
} | |
/* | |
******************************************************************************* | |
* LoadConfigSettings() | |
* | |
* Description: Loads the most recent configuration settings. | |
* | |
* Arguments: none | |
* | |
* Return: none | |
* | |
* Caller: Main GUI code | |
* | |
******************************************************************************* | |
*/ | |
void LoadConfigSettings() { | |
string lines[]; | |
string rf[]; | |
int nrf = fileglob(rf, ConfigFileName); | |
if (nrf) { | |
nrf = fileread(lines, rf[0]); | |
} | |
if (nrf == 7) { | |
int i = 0; | |
GUI_fileName = lines[i++]; | |
GUI_Xorg = strtod(lines[i++]); | |
GUI_Yorg = strtod(lines[i++]); | |
GUI_scale = strtod(lines[i++]); | |
GUI_lwidth = strtod(lines[i++]); | |
GUI_in_unit = strtol(lines[i++]); | |
SavedTargetLayer = strtol(lines[i++]); | |
} | |
} | |
/* | |
******************************************************************************* | |
* SaveConfigSettings() | |
* | |
* Description: Saves the most recent configuration settings. | |
* | |
* Arguments: none | |
* | |
* Return: none | |
* | |
* Caller: runscript | |
* | |
******************************************************************************* | |
*/ | |
void SaveConfigSettings() { | |
output(ConfigFileName, "wt") { | |
printf("%s\n", GUI_fileName); | |
printf("%f\n", GUI_Xorg); | |
printf("%f\n", GUI_Yorg); | |
printf("%f\n", GUI_scale); | |
printf("%f\n", GUI_lwidth); | |
printf("%d\n", GUI_in_unit); | |
printf("%d\n", GUI_TargetLayer); | |
} | |
} | |
/* | |
******************************************************************************* | |
* runscript() | |
* | |
* Description: This function writes the commands to a script file, and then | |
* exits the ULP. Upon exit the command to run the script is | |
* issued to EAGLE. | |
* | |
* Arguments: scr List of script commands | |
* | |
* Return: none | |
* | |
* Caller: checkscript | |
* | |
******************************************************************************* | |
*/ | |
void runscript(string scr) { | |
string filepath = get_project_path() + "dxfimp.scr"; | |
if (argc <= 1) { | |
SaveConfigSettings(); //When run from command line don't store settings | |
} | |
output(filepath,"wt") { | |
printf(scr); | |
} | |
exit("SCRIPT '" + filepath + "'"); | |
} | |
/* | |
******************************************************************************* | |
* checkscript() | |
* | |
* Description: This function checks if the DXF file will fit inside EAGLE's | |
* drawing area and if not return helpful messages. Addtionally it | |
* will display the generated script to the user for modifications | |
* before the script is run. | |
* | |
* Arguments: none | |
* | |
* Return: none | |
* | |
* Caller: Main GUI code | |
* | |
******************************************************************************* | |
*/ | |
void checkscript(void) { // This allows the user to inspect the script and make changes | |
real sc_xo = GUI_Xorg; // These allow the scale factor to be applied independently | |
real sc_yo = GUI_Yorg; | |
real sc_lw = GUI_lwidth; | |
string error; | |
if (GUI_scaled_Xorg == 1) { | |
sc_xo *= GUI_scale; | |
} | |
if (GUI_scaled_Yorg == 1) { | |
sc_yo *= GUI_scale; | |
} | |
if (GUI_scaled_lwidth ==1) { | |
sc_lw *= GUI_scale; | |
} | |
GUI_script = dxf(GUI_fileName, GUI_in_unit, sc_xo, sc_yo, sc_lw, 0, GUI_scale); | |
string dummy[]; // Dummy array to check of dxf function returned valid data | |
if (strsplit(dummy, GUI_script, '\n') == 8) { | |
GUI_script = dxf(GUI_fileName, | |
GUI_in_unit, | |
sc_xo, | |
sc_yo, | |
sc_lw, | |
1, | |
GUI_scale); // Run again without searching for sections | |
} | |
real Xdim = XMax - XMin; // Max dimensions of DXF file,must be defined after dxf runs | |
real Ydim = YMax - YMin; | |
real EXdim = Exmax - Exmin; // Max dimensions of EAGLE | |
real EYdim = Eymax - Eymin; | |
if ((Xdim > EXdim) || (Ydim > EYdim)) { // Checks if DXF file is larger than EAGLE's drawing area | |
dlgMessageBox(":DXF file is larger than EAGLE's drawing area please scale the file in your MCAD software and try again"); | |
exit(-1); | |
} | |
if ((Xdim < Exmax) && (Ydim < Eymax)) { // Checks if DXF file is small enough to fit in the | |
// first quadrant (+X +Y) | |
if ((XMax > Exmax) || (YMax > Eymax) || | |
(XMin < Exmin) || (YMin < Eymin)) { // Check if any of the points are outside of EAGLE's drawing area | |
GUI_Xorg = -1.0*(XMin/S_factor); // Lower left corner of DXF file will now be at 0 0 | |
GUI_Yorg = -1.0*(YMin/S_factor); // Make sure we return the offset in original units | |
sprintf(error,":DXF file is outside of EAGLE's drawing area would you like to apply an offset in X of %.1f and %.1f in y?", | |
GUI_Xorg, GUI_Yorg); | |
if (dlgMessageBox(error, "Set offset", "CANCEL") != 0) exit(-1); | |
return; | |
} | |
} | |
else { // DXF file is too large to fit in first quadrant | |
if ((XMax > Exmax) || (YMax > Eymax) || | |
(XMin < Exmin) || (YMin < Eymin)) { // Check if any of the points are outside of EAGLE's drawing area | |
GUI_Xorg = -1.0*(((XMin+XMax)/2)/S_factor); // Center of DXF file will now be at 0 0 | |
GUI_Yorg = -1.0*(((YMin+YMax)/2)/S_factor); | |
sprintf(error,":DXF file is outside of EAGLE's drawing area would you like to apply an offset in X of %.1f and %.1f in y?", | |
GUI_Xorg, GUI_Yorg); | |
if (dlgMessageBox(error, "Set offset", "CANCEL") != 0) exit(-1); | |
return; | |
} | |
} | |
if (argc > 1) { | |
runscript(GUI_script); //Just run the import script no further confirmation needed. Helps Automation JG | |
} | |
else { | |
int Result = dlgDialog("Run Script") { | |
dlgTextEdit(GUI_script); | |
dlgHBoxLayout { | |
dlgPushButton("Run") runscript(GUI_script); | |
dlgPushButton("Cancel") dlgReject(); | |
} | |
}; | |
} | |
} | |
int gettargetlayer(int select) { | |
return strtol(GUI_layers[select]); | |
} | |
/* | |
******************************************************************************** | |
* MAIN() * | |
******************************************************************************** | |
*/ | |
if (argc <= 1) { //When running from command line use defaults only | |
LoadConfigSettings(); // load the last filename and config settings | |
} | |
GUI_TargetLayer = 0; | |
if (board) { | |
board(B) { | |
B.layers(L) { | |
if (L.name) { | |
sprintf(GUI_layers[Lcnt], "%d %s",L.number, L.name); | |
if (L.number == SavedTargetLayer) { | |
GUI_TargetLayer = L.number; | |
GUI_layerselect = Lcnt; | |
} | |
Lcnt++; | |
} | |
} | |
} | |
} | |
else if (schematic) { | |
schematic(SCH) { | |
SCH.layers(L) { | |
if (L.name) { | |
sprintf(GUI_layers[Lcnt], "%d %s",L.number, L.name); | |
if (L.number == SavedTargetLayer) { | |
GUI_TargetLayer = L.number; | |
GUI_layerselect = Lcnt; | |
} | |
Lcnt++; | |
} | |
} | |
} | |
} | |
else if (package || symbol) { | |
library(LIB) { | |
LIB.layers(L) { | |
if (L.name) { | |
sprintf(GUI_layers[Lcnt], "%d %s",L.number, L.name); | |
if (L.number == SavedTargetLayer) { | |
GUI_TargetLayer = L.number; | |
GUI_layerselect = Lcnt; | |
} | |
Lcnt++; | |
} | |
} | |
} | |
} | |
else { | |
dlgMessageBox("Start this ULP in a Schematic- or Board- or Package- or Symbol- Editor!", "OK"); | |
exit(-1); | |
} | |
int main() { | |
if (argc > 1) { | |
//Run from the command line | |
if (argc < 4) { | |
dlgMessageBox("Not enough arguments. Please enter the filename, target layer, and units", "OK"); | |
} | |
GUI_fileName = argv[1]; | |
GUI_TargetLayer = strtol(argv[2]); | |
GUI_in_unit = strtol(argv[3]); // 0 means imperial, 1 means metric | |
if (argv[4]) { | |
GUI_Xorg = strtod(argv[4]); | |
} | |
if (argv[5]) { | |
GUI_Yorg = strtod(argv[5]); | |
} | |
if (argv[6]) { | |
GUI_lwidth = strtod(argv[6]); | |
} | |
if (argv[7]) { | |
GUI_scale = strtod(argv[7]); | |
} | |
if (argv[8]) { | |
string setup_value = argv[8]; | |
char param1 = setup_value[0]; | |
char param2 = setup_value[1]; | |
char param3 = setup_value[2]; | |
if (param1 == '1') { | |
GUI_scaled_Xorg = 1; | |
} | |
if (param2 == '1') { | |
GUI_scaled_Yorg = 1; | |
} | |
if (param3 == '1') { | |
GUI_scaled_lwidth = 1; | |
} | |
} | |
if (argv[9]) { | |
GUI_layerstart = strtol(argv[9]); | |
} | |
checkscript(); | |
} | |
else { | |
string stateline = " "; | |
int Result = dlgDialog("DXFIMPORT - "+Version) { | |
dlgHBoxLayout { | |
dlgLabel(Help); | |
} | |
dlgHBoxLayout { | |
dlgLabel("File &name:"); | |
dlgStringEdit(GUI_fileName); | |
dlgPushButton("Bro&wse") { | |
GUI_fileName = dlgFileOpen("Select a file", GUI_fileName, "*.dxf"); | |
} | |
} | |
dlgHBoxLayout { | |
dlgLabel("Target layer "); | |
dlgComboBox(GUI_layers, GUI_layerselect) GUI_TargetLayer = gettargetlayer(GUI_layerselect); | |
dlgStretch(1); | |
} | |
dlgHBoxLayout { | |
dlgLabel("MultiLayer StartLayer"); | |
dlgSpinBox(GUI_layerstart, 1, 255); | |
dlgSpacing(200); | |
dlgStretch(1); | |
} | |
dlgHBoxLayout { | |
dlgGroup("Input Units") { | |
dlgRadioButton("Imperial(in)", GUI_in_unit); // GUI_in_unit = 0 | |
dlgRadioButton("Metric(mm)", GUI_in_unit); // GUI_in_unit = 1 | |
} | |
dlgGridLayout { | |
dlgCell(0, 0) dlgLabel("Xorg"); | |
dlgCell(1, 0) dlgLabel("Yorg"); | |
dlgCell(0, 1) dlgRealEdit(GUI_Xorg); | |
dlgCell(1, 1) dlgRealEdit(GUI_Yorg); | |
dlgCell(2, 0) dlgLabel("Width"); | |
dlgCell(2, 1) dlgRealEdit(GUI_lwidth); | |
dlgCell(3, 0) dlgLabel("Scale"); | |
dlgCell(3, 1) dlgRealEdit(GUI_scale); | |
dlgCell(0, 2, 3, 2) { | |
dlgGroup("Scaled") { | |
dlgCheckBox("Xorg", GUI_scaled_Xorg); // If checked int contains 1, if unchecked 0 | |
dlgCheckBox("Yorg", GUI_scaled_Yorg); | |
dlgCheckBox("Width", GUI_scaled_lwidth); | |
} | |
} | |
dlgCell(1, 3) dlgPushButton("OK") { | |
stateline = "converting file... please wait."; | |
dlgRedisplay(); | |
checkscript(); | |
stateline = " "; | |
dlgRedisplay(); | |
} | |
dlgCell(2, 3) dlgPushButton("-Cancel") dlgReject(); | |
} | |
} | |
dlgLabel(stateline, 1); | |
}; | |
return Result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment