/* DRILLOUT (LAY) -- Drilling Data Output */ /* DRILLOUT (LAY) -- Bohrdatenausgabe */ /* // Copyright (c) 1993-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (100316) ENHANCEMENT: // Added drill legend creation with PDF layer support. // rl (091020) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (070423) ENHANCEMENT: // Added drill tolerance dependant tool table creation. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (060712) BUGFIX: // Fixed problems with unused via references and global tools. // rl (060329) ENHANCEMENT: // Added double drill position check option to drill report. // rl (060314) ENHANCEMENT: // Added support for padstack drill output disable rules. // Suppressed output of unused tools in global tool table. // rl (060118) ENHANCEMENT: // Made excellon tool table and drill data units configurable. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (040707) ENHANCEMENT: // Added option to create class indepandent tool table. // rl (040513) ENHANCEMENT: // Added fix tool table configuration through bae.ini. // rl (040325) ENHANCEMENT: // Added drill count display in class selection. // rl (040115) BUGFIX: // Fixed wrong tool number display in pure report function. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (020614) ENHANCEMENT: // Added Sieb & Meyer 1000/3000 support. // rl (010619) BUGFIX: // Eliminated disfunctionality in non GED environments. // rl (010626) RELEASED FOR BAE V5.0. // rl (010619) ENHANCEMENT: // Added total drill count display to reports. // rl (010409) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000720) RELEASED FOR BAE V4.6. // rl (000720) ENHANCEMENT: // Added mirror drill class support. // rl (000509) ENHANCEMENT: // Added dialog box support. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980713) ENHANCEMENT: // Pulldown menu delimiters introduced. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (971120) IMPROVEMENT: // Delete / from Excellon output header. When using fixed // tool table only the used tools are written to the Excellon // file. // rl (970929) RELEASED FOR BAE V4.0. // mb (960919) RELEASED FOR BAE V3.4. // mb (960509) CHANGE: // Excellon drill data output format changed in order to // meet CAM View Excellon input conventions. // mb (951012) IMPROVEMENT: // Performing BAE_Demo_check(2) before starting output. // mb (95) RELEASED FOR BAE V3.2. // mb (941208) ENHANCEMENT: // Automatic output file name generation with // drill class designator. // mb (941206) ENHANCEMENT: // Implemented drill class menu. // mb (941124) ENHANCEMENT: // Introduced new drill sort algorithm // (x,y coords sort was useless!). // Introduced compilation-controlled drill rout display option. // Improved user interface (drill statistics output, etc.). // Integrated DRILLCNT. // mb (941124) BUGFIX: // Corrected integer round function for Excellon output. // mb (940614) BUGFIX: // Drill class setting corrected for matching non-default // classes. // mb (94) RELEASED FOR BAE V3.0. // mb (94) ENHANCEMENT: // Introduced Excellon drill data output option. // mb (94) IMPROVEMENT: // Introduced scan routine for unsorted drill data // (cir. 20 times speed-up). // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The drillout User Language program generates drill data output // for the currently loaded layout. drillout supports both // Sieb&Meyer and Excellon drill data format and also provides // an option for displaying drill data statistics. Output drill // class selection is accomplished via popup menu. A predefined // drill tool table will be used if the user refrains from // automatic drill tool table generation. Optionally a heuristic // sort algorithm for optimizing (i.e. minimizing) the drill route // may be activated. The drillout source code provides a Compiler // directive for optionally compiling drillout for generating // graphical drill route display (drill route simulation). */ // Includes #include "pop.ulh" // User Language popup utilities #include "lay.ulh" // User Language layout utilities // Enforce layout caller type #pragma ULCALLERLAY // Messages string UPRABORT = M_UPRABORT(); string UPRPEXIT = M_UPRPEXIT(); string UPRPOPCONTINUE = M("(Weiter)","(Continue)"); string REPTSCAN = M("Scannen Bohrwerkzeuge","Scanning drill tools"); string REPDSCAN = M("Scannen Bohrungen","Scanning drills"); string REPDDSCAN = M("Scannen doppelte Bohrungen", "Scanning double drills"); string REPDSORT = M("Sortieren Bohrungen","Sorting drills"); string REPSTARTT = M("Schreiben Werkzeugtabelle...", "Writing drill tool table..."); string REPSTARTD = M("Schreiben Bohrdaten...", "Writing drill data..."); string REPDRLCUT1 = M("Ueberlappende Bohrungen bei %.1fmm,%.1fmm", "Overlapping Drills at %.1fmm,%.1fmm"); string REPDRLCUT2 = M(" (%.2fmm/%.2fmm) '%s'/'%s', '%c'/'%c'!", " (%.2fmm/%.2fmm) '%s'/'%s', '%c'/'%c'!"); string REPDBLDRL1 = M("Doppelte Bohrkoordinate %.1fmm,%.1fmm", "Ignored Double Drill Coordinate %.1fmm,%.1fmm"); string REPDBLDRL2 = M(" (%.2fmm) '%s', '%c' ignoriert!", " (%.2fmm) '%s', '%c'!"); string REPCLASS = M("Legende Bohrklasse %c","Legend Drill Class %c"); string UPRDRLPAR = M("Bohrdaten-Ausgabeparameter", "Drill Data Output Settings"); string UPRSELFMT = M("Bohrdaten-Ausgabeformat selektieren!", "Select Drill Data Output Format!"); string UPRFMTSM = M("&Sieb && Meyer","&Sieb && Meyer"); string UPRFMTSM1000 = M("Sieb && Meyer &1000","Sieb && Meyer &1000"); string UPRFMTSM3000 = M("Sieb && Meyer &3000","Sieb && Meyer &3000"); string UPRFMTEXC = M("&Excellon","&Excellon"); string UPRFMTCNT = M("%&Bohrdatenstatistik","%&Drill Statistics"); string UPRFMTLEG = M("%Bohrplan/-&legende","%Drill Plan/&Legend"); string UPRDCLASS = M("Bohrungsklasse (-,A..Z) ? ", "Drilling Class (-,A..Z) ? "); string UPRALLCLASS = M("Alle","All"); string UPRDDCLASS = M("Bohrungsklasse :","Drilling Class :"); string UPRDRLFIX = M("Vordefinierte Bohrertabelle verwenden ? ", "Use pre-defined Drill Tool Table ? "); string UPRDDRLFIX = M("Vordefinierte Bohrertabelle :", "Pre-defined Drill Tool Table :"); string UPRSELSRT = M("Bohrungs-Sortierverfahren waehlen!", "Select Drill Sort Mode!"); string UPRDSRT = M("Sortierverfahren :","Drill Sort Mode :"); string UPRNOSORT = M("&Keine Sortierung","Drills &Unsorted"); string UPRSORT = M("&Sortiere Bohrungen","Drills &Sorted"); string UPRRBOFF = M("&Aus","O&ff"); string UPRRBON = M("&Ein","&On"); string UPRDOCLAY = M("Dokumentarlage fuer Bohrplan/-legende waehlen!", "Select Documentary Layer for Drill Plan/Legend!"); string ERRFIXDRL = M( "Bohrdurchmesser %.1f mm nicht in vorgegebener Bohrertabelle!", "Drill Diameter %.1f mm not in pre-defined Drill Tool Table!"); string ERRDCLASS = M("Ungueltige Bohrungsklasse!", "Invalid drilling class!"); string ERRNODRL = M("Keine Bohrung fuer Ausgabe selektiert!", "No drill hole selected for output!"); string ERRNODRLS = M("Keine Bohrung gefunden!","No drill holes found!"); string ERRDRLCHAR = M("Zu viele verschiedene Bohrungen fuer A-Z/a-z-Bezeichnung!", "Too many different drills for A-Z/a-z naming!"); string FMTCLASSH = M("Datei '%s' / Layout '%s' - Bohrklassen :", "File '%s' / Layout '%s' - Drill Classes :"); string FMTREPHD = M("Bohrdatenstatistik","Drill Data Statistics"); string FMTREPDDB = M(" Datei ................: '%s'", " File .................: '%s'"); string FMTREPLAY = M(" Layout ...............: '%s'", " Layout ...............: '%s'"); string FMTREPCNT = M(" Gesamtzahl Bohrungen .: %d", " Total Drill Count ....: %d"); string FMTREPFMT = M(" Ausgabeformat ........: %s", " Drill Data Format ....: %s"); string FMTREPCLS = M(" Bohrklasse ...........: %s", " Drill Class ..........: %s"); string FMTREPTOL = M(" Werkzeugtabelle ......: '%s'", " Drill Tool File ......: '%s'"); string FMTREPDRL = M(" Bohrband .............: '%s'", " Drill Data File ......: '%s'"); string FMTREPLEN = M(" Verfahrweg ...........: %.2f %s", " Drill Route Length... : %.2f %s"); string FMTREPLHD = M("Bohrklasse Bohrdurchmesser Anzahl Tool Kommentar", "Drill Class Drill Diameter Drill Count Tool Comment"); string FMTREPLUL = M("========== =============== ====== ==== =========", "=========== =============== =========== ==== ======="); string FMTREPENT = M(" %c %6.2f mm %6d T %-2s %s", " %c %6.2f mm %11d T %-2s %s"); string FMTTOOLHD = M("/* Bohrer (Nummer) Bohrdurchmesser (mm) */\n\n", "/* Drill tool (no.) Drill diameter (mm) */\n\n"); string FMTCLASSHD = M("Bohrklasse %c, %d Bohrungen :", "Drill Class %c, %d Drills :"); string FMTDRLENT = M("%c - %smm%s %d Bohrungen","%s - %smm%s %d Drills"); string FMTDRLHD = M("Gesamtzahl Bohrungen : %d", "Total Drill Count : %d"); // INI file parameter name definitions #define PAR_PROGALL "DOPROGALL_LAY" // Popup progress all enable #define PAR_PROGQUIT "DOPROGQUIT_LAY"// Popup progress quit enable #define PAR_PROGBARSIZ "DOPBSIZE_LAY" // Popup progress bar size #define PAR_PROGCOLDON "DOPBCOLD_LAY" // Popup progress done color #define PAR_SHOWDRROUT "DOSDRROUT_LAY" // Display drill routing flag #define PAR_SHOWDRRLAY "DOSDRRLAY_LAY" // Drill rout display doc layer #define PAR_SHOWDRRCOL "DOSDRRCOL_LAY" // Drill rout display color #define PAR_SHOWDRRRAD "DOSDRRRAD_LAY" // Drill radius #define PAR_DFLTCLASS "DODEFCLASS_LAY"// Default drill class name #define PAR_TOLEXT "DOTOLEXT_LAY" // Tool file name extension #define PAR_TOLGLOB "DOTOLGLOB_LAY" // Global tool table flag #define PAR_DRLEXT "DODRLEXT_LAY" // Drill data file name extension #define PAR_TOLEXTC "DOTOLEXTC_LAY" // Tool file name extension #define PAR_DRLEXTC "DODRLEXTC_LAY" // Drill data file name extension #define PAR_DEFSORT "DODEFSORT_LAY" // Drill data default sort mode #define PAR_DRILLFIX "DODRILLFIX_LAY"// Def. fixed drill tool table usage #define PAR_DRLFIXTL "DODRILLFTL_LAY"// Fixed tool table #define PAR_DRLEXCTU "DODRLEXCTU_LAY"// Excellon tool table units #define PAR_DRLEXCDU "DODRLEXCDU_LAY"// Excellon drill data units #define PAR_DRLDBLCHK "DRLDBLCHECK_LAY"// Drill double position check flag #define PAR_DRLCLMAT "DRLDBLCHKM_LAY"// Drill class compare matrix #define PAR_DRLLOWCL "DRLDBLIGNC_LAY"// Drill class low priority comp. field #define PAR_DRLPTYP "DRLLTYPE_LAY" // Drill legend type #define PAR_DRLTSIZE "DRLLTSIZE_LAY" // Drill legend text size #define PAR_DRLHTSIZE "DRLHTSIZE_LAY" // Drill hole text size #define PAR_DRLTSPC "DRLLTSPC_LAY" // Drill legend text spacing #define PAR_DRLLSTK "DRLLSTK_LAY" // Drill legend padstack placement // Fixed drill tool list variables int DRILLFIX = bae_iniintval(PAR_DRILLFIX,0) /* Fixed drill tool usage flag */; double DEFTOOLRAD[] = { // Def. fixed drlrad. list (int. units) cvtlength(0.30,2,0)/2.0, cvtlength(0.50,2,0)/2.0, cvtlength(0.60,2,0)/2.0, cvtlength(0.70,2,0)/2.0, cvtlength(0.80,2,0)/2.0, cvtlength(0.90,2,0)/2.0, cvtlength(1.00,2,0)/2.0, cvtlength(1.15,2,0)/2.0, cvtlength(1.30,2,0)/2.0, cvtlength(1.60,2,0)/2.0 }; double TOOLRAD[] /* Fixed drl rad. list (int. units) */; int TOOLUSE[] /* Fixed drill usage list */; int TOOLRADN /* Fixed drill tool count */; STRINGS defclassmatrix = { // Default class compare matrix "200000000000000000000000000", // Drill class - "020000000000000000000000000", // Drill class A "002000000000000000000000000", // Drill class B "000200000000000000000000000", // Drill class C "000020000000000000000000000", // Drill class D "000002000000000000000000000", // Drill class E "000000200000000000000000000", // Drill class F "000000020000000000000000000", // Drill class G "000000002000000000000000000", // Drill class H "000000000200000000000000000", // Drill class I "000000000020000000000000000", // Drill class J "000000000002000000000000000", // Drill class K "000000000000200000000000000", // Drill class L "000000000000020000000000000", // Drill class M "000000000000002000000000000", // Drill class N "000000000000000200000000000", // Drill class O "000000000000000020000000000", // Drill class P "000000000000000002000000000", // Drill class Q "000000000000000000200000000", // Drill class R "000000000000000000020000000", // Drill class S "000000000000000000002000000", // Drill class T "000000000000000000000200000", // Drill class U "000000000000000000000020000", // Drill class V "000000000000000000000002000", // Drill class W "000000000000000000000000200", // Drill class X "000000000000000000000000020", // Drill class Y "000000000000000000000000002" // Drill class Z }; STRINGS classmatrix /* Class compare matrix */; string lowcmpcl = bae_inistrval(PAR_DRLLOWCL,"000000000000000000000000000") /* Drill low prio. comp. field class '-' followed by classes 'A'-'Z' */; // General Sieb & Meyer format strings #define FMTSMTOOL "%3d %5.2f\n" #define FMTSMDRLHD "%%\n" #define FMTSMDRLHD1000 "%%%%1000\n" #define FMTSMDRLHD3000 "%%%%3000\n" #define FMTSMDRL "X%ldY%ld" #define FMTSMDRLCHG "T%d" #define FMTSMTOOL1000E "$%ld$$$$$" #define FMTSMTOOL1000N "$$$$$$" #define FMTSMTOOL3000E "T%dD%ld\n" #define FMTSMTOOL3000EC "(T%d %s)\n" #define FMTSMTOOLT "$\n" #define FMTSMNL "\n" #define FMTSMDRLEND "M30\n" // General Excellon format strings #define FMTEXCHEADER "M48\nFMAT,2\nVER,1\n%s\n" #define FMTEXCTOOL "T%dC%5.3f\n" #define FMTEXCDRLHD "ICI,OFF\n%s\n%%\nG90\nM72\n" #define FMTEXCDRLCHG "T%d\n" #define FMTEXCDRL "X%05ldY%05ld\n" #define FMTEXCDRLEND "M30\n" // Program test features int SHOWDRILLROUT = uliptype()!=ULIPGED ? 0 : bae_iniintval(PAR_SHOWDRROUT,0) /* Display drill routing flag */; int DRLAY = bae_iniintval(PAR_SHOWDRRLAY,0x442) /* Drill rout display doc layer */; int DRCOL = bae_iniintval(PAR_SHOWDRRCOL,15) /* Drill rout display color */; int DRRAD = bae_inidblval(PAR_SHOWDRRRAD,0.0005) /* Drill radius */; // Global variable definitons string DFLTCLASS = bae_inistrval(PAR_DFLTCLASS,"-") /* Default drill class name */; string TOLEXT = bae_inistrval(PAR_TOLEXT,".tol") /* Tool file name extension */; string DRLEXT = bae_inistrval(PAR_DRLEXT,".drl") /* Drill data file name extension */; string TOLEXTC = bae_inistrval(PAR_TOLEXTC,".t_") /* Tool file name extension */; string DRLEXTC = bae_inistrval(PAR_DRLEXTC,".d_") /* Drill data file name extension */; int DRLDBLCHK = bae_iniintval(PAR_DRLDBLCHK,0) /* Drill double position check flag */; int DRLEXCTU = bae_iniintval(PAR_DRLEXCTU,0) /* Excellon tool table units */; int DRLEXCDU = bae_iniintval(PAR_DRLEXCDU,1) /* Excellon drill data units */; int DRLPLANTYP = bae_iniintval(PAR_DRLPTYP,2) /* Drill legend marker type */; int DRLLSTK = bae_iniintval(PAR_DRLLSTK,0) /* Drill legend padstack list flag */; double DRLTSIZE = bae_inidblval(PAR_DRLTSIZE,0.002) /* Drill legend text size */; double DRLHTSIZE = bae_inidblval(PAR_DRLHTSIZE,0.0) /* Drill hole text size */; double DRLTSPC = bae_inidblval(PAR_DRLTSPC,0.00054) /* Drill legend text row spacing */; #define FORMATSM 0 // Sieb & Meyer format #define FORMATSM1000 1 // Sieb & Meyer 1000 format #define FORMATSM3000 2 // Sieb & Meyer 3000 format #define FORMATEXC 3 // Excellon format #define FORMATREP 4 // Drill report/statistics format #define FORMATLEG 5 // Drill legend format int FORMAT /* Output format */; #define GRPDRLPLAN "drill_plan" // Drill plan group name #define GRPDRLLEG "drill_legend" // Drill legend group name #define VIANAME "via" // Report via name #define MATSIZE 0.010 // Matrix element size #define SMALLVAL 0.00001 // Small compare value int SORTMODE = bae_iniintval(PAR_DEFSORT,0) /* Drill sort mode : (0=unsorted,1=sorted) */; int GLOBTOOLS = bae_iniintval(PAR_TOLGLOB,0) /* Drill tool table mode : (0=class,1=global) */; double XOFF = bae_planwsnx()/* Plan origin X offset */; double YOFF = bae_planwsny()/* Plan origin Y offset */; string jobfname /* Job file name */; string toolfname /* Tool file name */; string drillfname /* Drill data file name */; string classname /* Drill data class name */; index L_MACRO curstk /* Drill current padstack macro */; double maxstkh = 0.0 /* Drill max. padstack height */; int classl[] /* Drill class reference list */; int classn = 0 /* Drill class reference count */; int class /* Selected drill data class */; index L_FIGURE curfig /* Current figure list index */; int curpidx /* Current scan padstack index */; int curruleid /* Current scan rule object ID */; struct coord { // Coordinate descriptor double x /* X coordinate */; double y /* Y coordinate */; }; struct tooldes { // Tool descriptor int class /* Tool drill class */; char legend /* Tool drill legend character */; double rad /* Tool drill radius */; string comm /* Tool drill comment */; string tolpos /* Tool drill pos. tolerance */; string tolneg /* Tool drill neg. tolerance */; int drilln /* Tool drill count */; struct coord drilll[] /* Tool drill coordinates list */; int stkn /* Tool drill padstack count */; index L_MACRO stkl[] /* Tool drill padstack list */; double routlen /* Tool drill route length */; } tooll[] /* Tool list */; int tooln = 0 /* Tool elements count */; int drilln = 0 /* Drill elements count */; int drillcount = 0 /* Global drill count */; int curtool = 0 /* Current tool index */; int curpool = 0 /* Pool element scan flag */; int curlayer /* Drill legend layer */; struct coord curdrilll[] /* Current drill coordinate list */; int curdrilln /* Current drill coordinate count */; int sdrilln /* Current sorted drill count */; int sdrillcount /* Global sorted drill count */; int totaldrlcnt = 0 /* Total drill count */; int classcnt = 0 /* Drill class count */; double totalroutlen = 0.0 /* Total drill rout length */; struct { // X coordinates descriptor double x /* X coordinate */; int yn /* Y coordinates count */; double yl[] /* Y coordiantes list */; } xl[] /* X coordinates list */; int xn = 0 /* X coordinates count */; double mxoff=bae_planwslx() /* Matrix origin X offset */; double myoff=bae_planwsly() /* Matrix origin Y offset */; double mxscale /* Matrix X scaling factor */; double myscale /* Matrix Y scaling factor */; int matrdim /* Matrix row dimension */; int matcdim /* Matrix row dimension */; int drlmat[][] /* Drill matrix */; struct cmpcoord { // Compare coordinate descriptor double x /* X coordinate */; double y /* Y coordinate */; double r /* Drill radius */; int pidx /* Drill padstack index */; int dis /* Drill disabled flag */; int class /* Drill class */; int mnext /* Next matrix drill index */; index L_FIGURE fig /* Drill figure list element index */; string name /* Drill part name */; } ddl[] /* Double drill compare list */; int ddn = 0 /* Double drill compare count */; string curpartname /* Current part name */; STRINGS entryl /* Entry list */; int entryn = 0 /* Entry count */; // Progress popup definitions int PROGALL = bae_iniintval(PAR_PROGALL,1) /* Popup progress all enable */; int PROGQUIT = bae_iniintval(PAR_PROGQUIT,0) /* Popup progress quit disable */; #define PROGREPPCT "%d %% (%d / %d)" #define PROGBARREPPCT " %d %% (%d / %d)..." int PROGBARSIZ = bae_iniintval(PAR_PROGBARSIZ,50) /* Popup progress bar size */; int PROGCOLDON = bae_iniintval(PAR_PROGCOLDON,14) /* Popup progress done color */; #define PROGHDN 2 // Popup progress header count STRINGS PROGHDL = {REPDSCAN} /* Popup progress header list */; int curprogrep = 0 /* Current progress report value */; int PROGCOLS = PROGBARSIZ+4 /* Progress popup columns */; int PROGROWS = PROGHDN+(PROGQUIT ? 7 : 3) /* Progress popup rows */; #define PROGREPCPU "Elapsed CPU Time = %6.1f [Sec]" double progstime = clock() /* Progress start time */; string progmsg = REPDSCAN /* Progress base message */; int dialsupport = 0 /* Dialog box support flags */; // Main program void main() { int toolfh /* Tool file handle */; int drillfh /* Drill file handle */; string msgbuf /* Message buffer */; string classstr /* Class name string */; double pcol = 24.0 /* Parameter column */; double cy /* Dialog box current y coordinate */; int repflag /* Dialog box repeat flag */; int res /* Dialog box selection result */; int varidx /* INI variable index */; int drlcidx /* Drill class parameter index */; int drltidx /* Drill tool table parameter index */; int drlsidx /* Drill sort mode parameter index */; int i /* Loop control variables */; // Abort if invalid plan class if (bae_planddbclass()!=DDBCLLAY) error_class(); // Get the dialog support flags bae_getintpar(41,dialsupport); // Select the drill data output format bae_promptdialog(UPRSELFMT); switch (bae_askmenu(7,UPRFMTSM,UPRFMTSM1000,UPRFMTSM3000,UPRFMTEXC, UPRFMTCNT,(uliptype()!=ULIPGED ? "," : "")+UPRFMTLEG,UPRABORT)) { // Sieb & Meyer case 0 : FORMAT=FORMATSM; break; // Sieb & Meyer 1000 case 1 : FORMAT=FORMATSM1000; break; // Sieb & Meyer 3000 case 2 : FORMAT=FORMATSM3000; break; // Excellon case 3 : FORMAT=FORMATEXC; break; // Statistics case 4 : FORMAT=FORMATREP; // Display the drill report drillreport(); // Done return; // Statistics case 5 : if (uliptype()!=ULIPGED) error_class(); // Display the drill legend drilllegend(); // Done return; // Abort on default default : error_abort(); } // Perform BAE Demo check with abort option BAE_Demo_check(2); // Scan the drill tools for getting the drill tool table scantools(); bae_msgprogressterm(); // Check for dialog support if (bae_dialclr()) { // Select the drill class askdrillclass(0); if (!GLOBTOOLS) // Select the fixed drill tool table to be used DRILLFIX=verify(UPRDRLFIX,1); // Select the drill sort mode bae_promptdialog(UPRSELSRT); if ((SORTMODE=bae_askmenu(3,UPRNOSORT,UPRSORT,UPRABORT))<0 || SORTMODE>1) error_abort(); } else { bae_prtdialog(""); // Init. the y coordinate cy=DIAL_TOPMARG; // Store drill class controls dial_label(0.0,cy,UPRDDCLASS); for (i=0;i=classn ? 0 : i,pcol,cy); for (i=0;i26 || class<0) error(ERRDCLASS); } /*________________________________________________________________*/ // Drill output functions void drillreport() /* // Display the drill statistics report */ { struct cmpcoord curcoord /* Current drill coordinate */; int MAXCOLS = 100 /* Maximum popup columns */; STRINGS headl /* Header list */; int headn = 4 /* Header count */; string rulename /* Rule name (pattern) */; STRINGS rl /* Rule list */; int rn /* Rule count */; int rcnt /* Rule count */; int row, col /* Matrix position */; int toolnum = 0 /* Tool number */; int lastclass = (-1) /* Last class */; int i, j /* Loop control variables */; // Check if double drill scan if (FORMAT==FORMATREP && DRLDBLCHK) { for (i=0;i<=26;i++) { if ((classmatrix[i]=bae_inistrval( bae_iniarrayvarname(PAR_DRLCLMAT,i),""))=="") { // Use default drill class matrix classmatrix=defclassmatrix; break; } } // Count drills curruleid=(-2); forall (curfig where curfig.TYP==L_FIGNREF || curfig.TYP==L_FIGUREF) if (lay_scanfelem(curfig,XOFF,YOFF,0.0,1,1, NULL,NULL,NULL,NULL,toolfunc,NULL,NULL)!=0) error_scan(); // Get the matrix dimensions matcdim=(bae_planwsux()-mxoff)/MATSIZE+1; matrdim=(bae_planwsuy()-myoff)/MATSIZE+1; mxscale=matcdim/(bae_planwsux()-mxoff); myscale=matrdim/(bae_planwsuy()-myoff); mxoff-=XOFF; myoff-=YOFF; // "Allocate" the drill data array ddl[drillcount].y=0.0; ddl[drillcount].x=0.0; ddl[drillcount].r=0.0; ddl[drillcount].pidx=(-1); ddl[drillcount].dis=0; ddl[drillcount].class=(-1); ddl[drillcount].name=""; ddl[drillcount].mnext=(-1); // Print drill scan message bae_msgprogressrep(REPDDSCAN+"...",PB_TYPPROC|PB_ABORT,0,40); progmsg=REPDDSCAN; // Init. the drill matrix for (row=matrdim-1;row>=0;row--) for (col=matcdim-1;col>=0;col--) drlmat[row][col]=(-1); // Display the initial progress popup pop_progress(ddn,drillcount); // Build the drill disable rule name pattern sprintf(rulename,":%s:%s*=1;",RS_PCBSUBJ, strextract(RS_PSTKDDFLAG,0,strlen(RS_PSTKDDFLAG)-3)); // Scan the drills forall (curfig) { if (curfig.TYP==L_FIGNREF) curpartname=curfig.NAME; else if (curfig.TYP==L_FIGUREF) curpartname=VIANAME; else continue; curpidx=(-1); if (lay_scanfelem(curfig,XOFF,YOFF,0.0,1,1, macfunc,NULL,NULL,NULL,dcmpfunc,NULL,NULL)!=0) error_scan(); if (curfig.RULEOBJID>=0) { // Get the element rules rn=rcnt=rs_getfigrules(curfig,rl); // Delete any old padstack drill disable rules for (i=0;i=0) { // Query the group name if (lay_rulequery(RS_OCFIG,curfig,RS_PCBSUBJ,RS_GROUPNAME, "?s",grpname)<1) continue; if (grpname==GRPDRLPLAN || grpname==GRPDRLLEG) ged_delelem(curfig); } // Check if global drill text size if (DRLHTSIZE==0.0) DRLHTSIZE=DRLTSIZE; // Scan the drill tools for getting the drill tool table scantools(); if (tooln==0) error(ERRNODRLS); for (i=0;i1) askdrillclass(1); else class=(-2); // Assign drill tool characters for (i=0;i1) totrown+=2*classcnt; // Draw the drill symbols forall (curfig where curfig.TYP==L_FIGNREF || curfig.TYP==L_FIGUREF) { // Set padstack scan data curpidx=(-1); curruleid=curfig.RULEOBJID; if (lay_scanfelem(curfig,0.0,0.0,0.0,1,1, macfunc,NULL,NULL,NULL,drldrawfunc,NULL,NULL)!=0) error_scan(); } if (DRLTSIZE=0;i--) { if (tooll[i].drilln==0) continue; if (lastclass==(-1)) { lastclass=tooll[i].class; classdrlcnt=0; if (classcnt>1) { sprintf(classname,REPCLASS, lastclass==0 ? '-' : 'A'+lastclass-1); sprintf(rulel[5],":%s:%s='%s';", RS_PCBSUBJ,RS_PDFLAY,classname); } } else if (lastclass!=tooll[i].class) { sprintf(outstr,FMTCLASSHD, lastclass==0 ? '-' : 'A'+lastclass-1,classdrlcnt); lastclass=tooll[i].class; if (ged_storetext( outstr,cx,cy,0.0,DRLTSIZE,curlayer,0)==0 && lay_lastfigelem(curfig)==0) { ged_elemgrpchg(curfig,1); sprintf(rulel[2],":%s:%s=%d;", RS_PCBSUBJ,RS_MTEXTROW,totrown); if (lay_rulefigatt(curfig,rulel)) rs_error(-1); } cy+=2*linestep; totrown-=2; classdrlcnt=0; if (classcnt>1) { sprintf(classname,REPCLASS, lastclass==0 ? '-' : 'A'+lastclass-1); sprintf(rulel[5],":%s:%s='%s';", RS_PCBSUBJ,RS_PDFLAY,classname); } } if (DRLLSTK) { px=cx-DRLTSPC; for (j=0;j1) rulel[5]=""; sprintf(outstr,FMTDRLHD,totaldrlcnt); if (ged_storetext(outstr,cx,cy,0.0,DRLTSIZE,curlayer,0)==0 && lay_lastfigelem(curfig)==0) { ged_elemgrpchg(curfig,1); sprintf(rulel[2],":%s:%s=%d;",RS_PCBSUBJ,RS_MTEXTROW,totrown); if (lay_rulefigatt(curfig,rulel)) rs_error(-1); } cy+=linestep; // Move the group anglock=bae_getanglelock(); bae_setanglelock(0); ged_getintpar(32,grpdisp); ged_setintpar(32,2); bae_clriactqueue(); bae_storemouseiact(1,cx,cy,0,LMB); bae_callmenu(MNU_GEDMOVEGRP); if (bae_getanglelock()==0) bae_setanglelock(anglock); ged_setintpar(32,grpdisp); // Draw the drill symbols if (DRLPLANTYP==4 || DRLPLANTYP==5) forall (curfig where curfig.GROUP && (curfig.TYP==L_FIGNREF || curfig.TYP==L_FIGUREF)) { // Set padstack scan data curpidx=(-1); curruleid=curfig.RULEOBJID; if (lay_scanfelem(curfig,0.0,0.0,0.0,1,1, macfunc,NULL,NULL,NULL,drldrawfunc,NULL,NULL)!=0) error_scan(); } } int drldrawfunc(index L_DRILL drill,double x,double y, int drillinws,int tree,index L_LEVEL level) /* // Draw drill legend // Return value : // zero if done or (-1) on file error // Parameters : // index L_DRILL drill : Drill data block // double x : Drill X coordinate // double y : Drill Y coordinate // int drillinws : Drill in workspace flag // int tree : Drill tree number // index L_LEVEL level : Drill level */ { index L_FIGURE fig /* Figure list index */; index L_NREF nref /* Named reference index */; string rulel[] /* Rule list */; string outstr /* Output string */; string rulename /* Rule name */; string classname /* Drill class name */; string comm /* Drill comment */; string tolpos /* Pos. tolerance value */; string tolneg /* Neg. tolerance value */; double rad /* Drill radius */; int pstkdis /* Padstack disable flag */; int drlclass /* Drill class */; // Check if disabled padstack (double drill mark) */ if (curruleid>=0) { sprintf(rulename,RS_PSTKDDFLAG,curpidx); if (lay_rulequery(RS_OCFIG,curfig,RS_PCBSUBJ, rulename,"?d",pstkdis)>0 && pstkdis) // Padstack disabled return(0); } // Get the effective drill class drlclass= ((drill.CLASS&DRLCMIRR) && (nref=lay_getscpartrpidx())>=0 && nref.MIRROR) ? (drill.CLASS&DRLCMASK2)>>DRLCSHFT2 : drill.CLASS&DRLCMASK1 ; // Test if class of interest if (class!=(-2) && drlclass!=class) return(0); sprintf(classname,REPCLASS,drlclass==0 ? '-' : 'A'+drlclass-1); // Build the drill marker rule list sprintf(rulel[0],":%s:%s='%s';",RS_PCBSUBJ,RS_GROUPNAME,GRPDRLPLAN); if (classcnt>1) sprintf(rulel[1],":%s:%s='%s';",RS_PCBSUBJ,RS_PDFLAY,classname); // Query the drill comment if (lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLCOMM,"?s",comm)<1) comm=""; // Query the pos. tolerance if ( lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLTOLPOS,"?s",tolpos)<1) tolpos=""; // Query the neg. tolerance if ( lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLTOLNEG,"?s",tolneg)<1) tolneg=""; rad=drill.RAD; if ((curtool=gctool(drlclass,rad,comm,tolpos,tolneg))<0) // Internal error err_intern("drldrawfunc"); sprintf(outstr,"%c",tooll[curtool].legend); switch (DRLPLANTYP) { // Shifted fixed size text with propeller marker case 2 : bae_clearpoints(); bae_storepoint(x-rad,y,0); bae_storepoint(x+rad,y,0); bae_storepoint(x,y,1); bae_storepoint(x,y+rad,0); bae_storepoint(x,y-rad,0); bae_storepoint(x,y,2); bae_storepoint(x-rad,y,0); if (ged_storepoly(curlayer,L_POLYDOCLINE,"",0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); // Assign the group name predicate rule rs_assfigstrpred(fig,RS_GROUPNAME,GRPDRLPLAN,"",""); if (ged_storetext(outstr, x-DRLHTSIZE*2.0/3.0,y,0.0,DRLHTSIZE,curlayer,0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); break; // Shifted fixed size text with cross marker case 3 : bae_clearpoints(); bae_storepoint(x-rad,y,0); bae_storepoint(x+rad,y,0); if (ged_storepoly(curlayer,L_POLYDOCLINE,"",0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); bae_clearpoints(); bae_storepoint(x,y+rad,0); bae_storepoint(x,y-rad,0); if (ged_storepoly(curlayer,L_POLYDOCLINE,"",0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); if (ged_storetext(outstr, x-DRLHTSIZE*2.0/3.0,y,0.0,DRLHTSIZE,curlayer,0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); break; // Filled circle case 4 : bae_clearpoints(); bae_storepoint(x-rad,y,0); bae_storepoint(x,y,1); bae_storepoint(x+rad,y,0); bae_storepoint(x,y,1); if (ged_storepoly(curlayer,L_POLYDOCAREA,"",0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); break; // Filled circle or square case 5 : bae_clearpoints(); if (comm!="") { bae_storepoint(x-rad,y-rad,0); bae_storepoint(x+rad,y-rad,0); bae_storepoint(x+rad,y+rad,0); bae_storepoint(x-rad,y+rad,0); } else { bae_storepoint(x-rad,y,0); bae_storepoint(x,y,1); bae_storepoint(x+rad,y,0); bae_storepoint(x,y,1); } if (ged_storepoly(curlayer,L_POLYDOCAREA,"",0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); break; // Centered text circle case 1 : bae_clearpoints(); bae_storepoint(x-rad,y,0); bae_storepoint(x,y,1); bae_storepoint(x+rad,y,0); bae_storepoint(x,y,1); bae_storepoint(x-rad,y,0); if (ged_storepoly(curlayer,L_POLYDOCLINE,"",0)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); // Pure centered text case 0 : default : if (ged_storetext( outstr,x,y,0.0,rad*2.0,curlayer,TEXTHCENT|TEXTVCENT)==0 && lay_lastfigelem(fig)==0) if (lay_rulefigatt(fig,rulel)) rs_error(-1); } // Test on program abort request checkabort(); // Return without errors return(0); } void writesmtools(int fh,int class) /* // Write the Sieb & Meyer tool table // Parameters : // int fh : File handle // int class : Drill class */ { int toolnum = 1 /* Tool number */; int i /* Loop control variable */; // Write the file header fprintf(fh,FMTTOOLHD); // Test if fixed drill tool table to be used if (DRILLFIX) { // Loop thru the fixed drill tool table for (i=0;i0.0) ged_storepoly(DRLAY,L_POLYDOCLINE,"",0); } // Reset tool number toolnum=1; // Write format specific drill data terminator switch (FORMAT) { case FORMATSM : // Write the file terminator fprintf(fh,FMTSMDRLEND); break; case FORMATSM1000 : // Test if fixed drill tool tabel to be used if (DRILLFIX) { if (GLOBTOOLS) { // Loop thru the fixed drill tool table for (i=0;i=0) // Write tool diameter info fprintf(fh,FMTSMTOOL1000E, roundint(100*cvtlength( 2.0*TOOLRAD[toolnum],0,2))); else fprintf(fh,FMTSMTOOL1000N); } // Fill remaining tool table entries for (;i<15;i++) fprintf(fh,FMTSMTOOL1000N); } else { // Search tools for given class for (i=0;i=0) // Write tool diameter info fprintf(fh,FMTSMTOOL3000E,toolnum+1, roundint(100*cvtlength( 2.0*TOOLRAD[toolnum],0,2))); } else { // Search tools for given class for (i=0;i0;j--) if (TOOLRAD[j-1]>rad) TOOLRAD[j]=TOOLRAD[j-1]; else break; TOOLRAD[j]=rad; TOOLRADN++; } } DRILLFIX=1; } } /*________________________________________________________________*/ // Drill scan functions int macfunc(index L_MACRO macro,index L_POOL pool, int macinws,string refname,index L_LEVEL level) /* // Drill data output macro function // Return value : // 0 if out of workspace, 1 if inside, 2 if unknown, or (-1) on error // Parameters : // index L_MACRO macro : Macro index // index L_POOL pool : Macro pool index // int macinws : Macro in workspace flag // string refname : Macro reference name // index L_LEVEL level : Macro level */ { // Check class switch (macro.CLASS) { case DDBCLLPRT : // Continue scan return(1); case DDBCLLSTK : // Update padstack index curstk=macro; curpidx++; // Continue scan return(1); default : ; } // Abort scan return(0); } int toolfunc(index L_DRILL drill,double x,double y, int drillinws,int tree,index L_LEVEL level) /* // Scan and store a new drill tool to sorted drill tool list // Return value : // zero if done or (-1) on file error // Parameters : // index L_DRILL drill : Drill data block // double x : Drill X coordinate // double y : Drill Y coordinate // int drillinws : Drill in workspace flag // int tree : Drill tree number // index L_LEVEL level : Drill level */ { index L_NREF nref /* Named reference index */; string rulename /* Rule name */; string comm /* Drill comment */; string tolpos /* Pos. tolerance value */; string tolneg /* Neg. tolerance value */; int pstkdis /* Padstack disable flag */; int drlclass /* Drill class */; // Check if disabled padstack (double drill mark) */ if (curruleid>=0) { sprintf(rulename,RS_PSTKDDFLAG,curpidx); if (lay_rulequery(RS_OCFIG,curfig,RS_PCBSUBJ, rulename,"?d",pstkdis)>0 && pstkdis) // Padstack disabled return(0); } // Check if pure drill count call else if (curruleid==(-2)) { /* Increment the global drill count */ if (!curpool) drillcount++; return(0); } // Get the effective drill class drlclass= ((drill.CLASS&DRLCMIRR) && (nref=lay_getscpartrpidx())>=0 && nref.MIRROR) ? (drill.CLASS&DRLCMASK2)>>DRLCSHFT2 : drill.CLASS&DRLCMASK1 ; // Query the drill comment if (lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLCOMM,"?s",comm)<1) comm=""; // Query the pos. tolerance if ( lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLTOLPOS,"?s",tolpos)<1) tolpos=""; // Query the neg. tolerance if ( lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLTOLNEG,"?s",tolneg)<1) tolneg=""; // Get or create tool if ((curtool=gctool(drlclass,drill.RAD,comm,tolpos,tolneg))<0) err_intern("toolfunc"); if (!curpool) { // Increment the current tools drill count tooll[curtool].drilln++; /* Increment the global drill count */; drillcount++; } checkabort(); } int gtoolfunc(index L_DRILL drill,double x,double y, int drillinws,int tree,index L_LEVEL level) /* // Scan current class drill radius usage // Return value : // zero if done or (-1) on file error // Parameters : // index L_DRILL drill : Drill data block // double x : Drill X coordinate // double y : Drill Y coordinate // int drillinws : Drill in workspace flag // int tree : Drill tree number // index L_LEVEL level : Drill level */ { index L_NREF nref /* Named reference index */; string rulename /* Rule name */; int pstkdis /* Padstack disable flag */; int drlclass /* Drill class */; int tidx /* Tool index */; // Check if disabled padstack (double drill mark) */ if (curruleid>=0) { sprintf(rulename,RS_PSTKDDFLAG,curpidx); if (lay_rulequery(RS_OCFIG,curfig,RS_PCBSUBJ, rulename,"?d",pstkdis)>0 && pstkdis) // Padstack disabled return(0); } // Get the effective drill class drlclass= ((drill.CLASS&DRLCMIRR) && (nref=lay_getscpartrpidx())>=0 && nref.MIRROR) ? (drill.CLASS&DRLCMASK2)>>DRLCSHFT2 : drill.CLASS&DRLCMASK1 ; if (drlclass!=class) return(0); if ((tidx=findfixdrill(drill.RAD))>=0) TOOLUSE[tidx]=1; // Test on program abort request checkabort(); // Return without errors return(0); } int drillfunc(index L_DRILL drill,double x,double y, int drillinws,int tree,index L_LEVEL level) /* // Scan and store a new drill to unsorted drill list // Return value : // zero if done or (-1) on file error // Parameters : // index L_DRILL drill : Drill data block // double x : Drill X coordinate // double y : Drill Y coordinate // int drillinws : Drill in workspace flag // int tree : Drill tree number // index L_LEVEL level : Drill level */ { index L_NREF nref /* Named reference index */; string rulename /* Rule name */; string comm /* Drill comment */; string tolpos /* Pos. tolerance value */; string tolneg /* Neg. tolerance value */; int pstkdis /* Padstack disable flag */; int drlclass /* Drill class */; // Check if disabled padstack (double drill mark) */ if (curruleid>=0) { sprintf(rulename,RS_PSTKDDFLAG,curpidx); if (lay_rulequery(RS_OCFIG,curfig,RS_PCBSUBJ, rulename,"?d",pstkdis)>0 && pstkdis) // Padstack disabled return(0); } // Get the effective drill class drlclass= ((drill.CLASS&DRLCMIRR) && (nref=lay_getscpartrpidx())>=0 && nref.MIRROR) ? (drill.CLASS&DRLCMASK2)>>DRLCSHFT2 : drill.CLASS&DRLCMASK1 ; // Ignore drill if not of selected class if (drlclass!=class) return(0); // Query the drill comment if (lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLCOMM,"?s",comm)<1) comm=""; // Query the pos. tolerance if ( lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLTOLPOS,"?s",tolpos)<1) tolpos=""; // Query the neg. tolerance if ( lay_rulequery(RS_OCPOOL,drill,RS_PCBSUBJ,RS_DRLTOLNEG,"?s",tolneg)<1) tolneg=""; // Find tool if (tooln>1) { if ((curtool=gctool(drlclass,drill.RAD,comm,tolpos,tolneg))<0) // Internal error err_intern("drillfunc"); } else curtool=0; // Insert drill coordinates to tool table tooll[curtool].drilll[tooll[curtool].drilln].y=y; tooll[curtool].drilll[tooll[curtool].drilln].x=x; tooll[curtool].drilln++; // Increment the global drill count drilln++; // Test on program abort request checkabortbar(drillcount); // Update the progress popup pop_progress(drilln,drillcount); // Return without errors return(0); } int dcmpfunc(index L_DRILL drill,double x,double y, int drillinws,int tree,index L_LEVEL level) /* // Scan and store a new drill to sorted drill compare list and matrix // Return value : // zero if done or (-1) on file error // Parameters : // index L_DRILL drill : Drill data block // double x : Drill X coordinate // double y : Drill Y coordinate // int drillinws : Drill in workspace flag // int tree : Drill tree number // index L_LEVEL level : Drill level */ { index L_NREF nref /* Named reference index */; double rad /* Drill radius */; double cmprad /* Drill compare radius */; double d /* Drill distance */; int drlclass /* Drill class */; int row, col /* Matrix position */; int mnext /* Matrix scan variable */; int i, j /* Loop control variables */; // Get the effective drill class drlclass= ((drill.CLASS&DRLCMIRR) && (nref=lay_getscpartrpidx())>=0 && nref.MIRROR) ? (drill.CLASS&DRLCMASK2)>>DRLCSHFT2 : drill.CLASS&DRLCMASK1 ; rad=drill.RAD; col=x2col(x); row=y2row(y); ddl[ddn].dis=0; for (i=col-1;i<=(col+1);i++) { if (i<0 || i>=matcdim) continue; for (j=row-1;j<=(row+1);j++) { if (j<0 || j>=matrdim) continue; for (mnext=drlmat[j][i];mnext!=(-1);mnext=ddl[mnext].mnext) { // Check if classes match if (classmatrix[ddl[mnext].class][drlclass]=='0') continue; // Get the drill distance d=dist(x,y,ddl[mnext].x,ddl[mnext].y); // Get the compare drill radius cmprad=ddl[mnext].r; // Check if same size drill if (fabs(rad-cmprad)<=SMALLVAL) { // Check if same position if (d<=SMALLVAL) { switch (classmatrix[ddl[mnext].class] [drlclass]) { case '2' : ddl[ddn].dis=1; break; case '1' : ddl[mnext].dis=1; break; // Classes don't match case '0' : default : ; } } else if (d<2.0*rad) { // Drills overlap partially sprintf(entryl[entryn], REPDRLCUT1+REPDRLCUT2, cvtlength(x,0,2),cvtlength(y,0,2), cvtlength(rad,0,2), cvtlength(cmprad,0,2),curpartname, ddl[mnext].name, drillclass(drlclass), drillclass(ddl[mnext].class)); entryn++; } } else if (d<(rad+cmprad)) { // Check if smaller inside larger drill if (d=0 && minyidx>=0 && fabs(curx-lastcoord.x)>mindist) break; // Find the Y coordinate if ((yidx=findy(xidx,lastcoord.y,insidx))<0) yidx=insidx; // Test if (upper) Y coordinate in range if (yidx=0) { // Get distance to lower Y coordinate curdist= calcdist(curx,xl[xidx].yl[yidx],lastcoord); // Test if new nearest distance if (minxidx<0 || minyidx<0 || curdist=0) { // Get the current X coordinate curx=xl[xidx].x; // Test if X coordinate runs out of range if (minxidx>=0 && minyidx>=0 && fabs(curx-lastcoord.x)>mindist) break; // Find the Y coordinate if ((yidx=findy(xidx,lastcoord.y,insidx))<0) yidx=insidx; // Test if (upper) Y coordinate in range if (yidx=0) { // Get distance to lower Y coordinate curdist= calcdist(curx,xl[xidx].yl[yidx],lastcoord); // Test if new nearest distance if (minxidx<0 || minyidx<0 || curdist=xn || minyidx>=xl[minxidx].yn) // This may not happen err_intern("visitnext"); // Update the last coordinates lastcoord.y=xl[minxidx].yl[minyidx]; lastcoord.x=xl[minxidx].x; // Store the minimum coordinate to the sorted list curdrilll[curdrilln].y=lastcoord.y; curdrilll[curdrilln].x=lastcoord.x; curdrilln++; // Remove current coordinate yn=xl[minxidx].yn-1; for (i=minyidx;i=0) { // Tool found; return the tool index if (!curpool) classl[class]++; stkn=tooll[toolidx].stkn; for (i=0;i=stkn) { tooll[toolidx].stkl[stkn]=curstk; if ((curstk.MUY-curstk.MLY)>maxstkh) maxstkh=curstk.MUY-curstk.MLY; tooll[toolidx].stkn++; } return(toolidx); } // Insert new tool at insert position for (toolidx=tooln;toolidx>insidx;toolidx--) tooll[toolidx]=tooll[toolidx-1]; tooll[insidx].routlen=0.0; tooll[insidx].drilln=0; tooll[insidx].rad=rad; tooll[insidx].class=class; tooll[insidx].comm=comm; tooll[insidx].tolpos=tolpos; tooll[insidx].tolneg=tolneg; tooll[insidx].stkn=1; tooll[insidx].stkl[0]=curstk; if ((curstk.MUY-curstk.MLY)>maxstkh) maxstkh=curstk.MUY-curstk.MLY; tooln++; // Store drill class while (classn<=class) classl[classn++]=0; if (!curpool) classl[class]++; // Return the new tool insert index return(insidx); } int findtool( int class,double rad,string comm,string tolpos,string tolneg,int insidx=(-1)) /* // Find tool with given class and radius in sorted drill tool list // Return value : // tool list insertion point // Parameters : // int class : Drill tool class // double rad : Drill tool radius // string comm : Drill tool comment // string tolpos : Drill tool pos. tolerance // string tolneg : Drill tool neg. tolerance // int insidx=(-1) : Tool list insertion index */ { int slb = 0 /* Search lower boundary */; int sub = tooln-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Compare drill tool classes if (class==tooll[sidx].class) { // Compare drill radius values if (rad==tooll[sidx].rad) { // Compare drill comments if (comm==tooll[sidx].comm) { // Compare drill pos. tolerance values if (tolpos==tooll[sidx].tolpos) { // Compare drill neg. tolerance values if (tolneg==tooll[sidx].tolneg) { // Tool found return(sidx); } else { // Smaller neg. tolerance first compres=numstrcmp( tolneg,tooll[sidx].tolneg); } } else { // Smaller pos. tolerance first compres= numstrcmp(tolpos,tooll[sidx].tolpos); } } else { // Lower comment first compres=numstrcmp(comm,tooll[sidx].comm); } } else { // Smaller radius first compres=rad=0) // Coordinate found; return the coordinate index return(coordidx); // Insert new coordinate at insert position yl=xl[xidx].yl; for (coordidx=xl[xidx].yn;coordidx>insidx;coordidx--) yl[coordidx]=yl[coordidx-1]; yl[insidx]=y; xl[xidx].yl=yl; xl[xidx].yn++; // Return the new coordinate insert index return(insidx); } int findy(int xidx,double y,int insidx=(-1)) /* // Find Y coordinate entry // Return value : // Y coordinate list insertion point // Parameters : // int xidx : X coordinate list index // double y : Y coordinate // int insidx=(-1) : Y coordinate list insertion index */ { int slb = 0 /* Search lower boundary */; int sub = xl[xidx].yn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Compare coordinates if ((compres=cmpdbl(y,xl[xidx].yl[sidx]))==0) // Coordinate found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Set the insert index insidx=slb; // Not found return(-1); } int gcx(double x) /* // Get or create X coordinates entry // Return value : // coordinate list index // Parameters : // double x : X coordinate */ { int coordidx /* Coordinate list index */; int insidx /* Coordinate list insert index */; // Search X coordinate if ((coordidx=findx(x,insidx))>=0) // Coordinate found; return the coordinate index return(coordidx); // Insert new coordinate at insert position for (coordidx=xn;coordidx>insidx;coordidx--) xl[coordidx]=xl[coordidx-1]; xl[insidx].x=x; xl[insidx].yn=0; xn++; // Return the new coordinate insert index return(insidx); } int findx(double x,int insidx=(-1)) /* // Find X coordinate entry // Return value : // X coordinate list insertion point // Parameters : // double x : X coordinate // int insidx=(-1) : X coordinate list insertion index */ { int slb = 0 /* Search lower boundary */; int sub = xn-1 /* Search upper boundary */; int sidx /* Search index */; int compres /* Compare result */; // Loop until search area empty while (slb<=sub) { // Get the search index sidx=(slb+sub)>>1; // Compare coordinates if ((compres=cmpdbl(x,xl[sidx].x))==0) // Coordinate found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Set the insert index insidx=slb; // Not found return(-1); } int findfixdrill(double rad) /* // Find radius-sepcified tool in fixed drill tool table // Return value : // fixed drill tool list index or (-1) if not found // Parameters : // double rad : Requested drill radius */ { int i /* Loop control variable */; // Loop thru the fixed drill tool table for (i=0;iv2) // Parameters : // double v1 : Input double value 1 // double v2 : Input double value 2 */ { // Test if equal if (v1==v2) // Return equal result return(0); // Return non-equal result return(v1=1 && code <=26) // Special class return(code+'A'-1); // Undefined return('*'); } string toolspec(int toolidx) /* // Build tool description string // Return value : // description string // Parameters : // int toolidx : Drill tool table index */ { string spec /* Drill specification string */; if (tooll[toolidx].comm!="") spec=" "+tooll[toolidx].comm; else spec=""; if (tooll[toolidx].tolpos!="") { if (spec=="") spec=tooll[toolidx].tolpos; else spec+=" "+tooll[toolidx].tolpos; } if (tooll[toolidx].tolneg!="") { if (spec=="") spec=tooll[toolidx].tolneg; else spec+=" "+tooll[toolidx].tolneg; } return(spec); } /*________________________________________________________________*/ // Popup progress report void pop_progress(int curcount,int totcount) /* // Display work in progress bar // Parameters : // int curcount : Current count // int totcount : Total count */ { int popuprows = PROGROWS /* Popup rows count */; int popupcols = PROGCOLS /* Popup columns count */; double mlx /* Popup window left boundary */; double muy /* Popup window upper boundary */; int currow /* Current text row */; string progress /* Progress string */; if (dialsupport&DIAL_PROGRESS) { if (curcount==0) curprogrep=(-1); // Check if last call if (curcount==totcount) { bae_msgprogressterm(); } else { // Check if bar size changed if (floor(PROGBARSIZ*curcount/totcount)>curprogrep) { // Update the progress status curprogrep=floor(PROGBARSIZ*curcount/totcount); // Display percentage report sprintf(progress,progmsg+PROGBARREPPCT, 100*curcount/totcount,curcount,totcount); bae_msgprogressrep(progress,PB_TYPPERC|PB_ABORT, 10000*curcount/totcount,40); } } return; } // Check if first call if (curcount==0) { // Calculate the popup bottom aligned upper boundary if ((muy=POPMIN+calcpopheight(popuprows))>POPMAX) muy=POPMAX; // Calculate the popup center aligned lower boundary mlx=(1.0-calcpopwidth(popupcols))/2.0; // Show the progress popup bae_popshow(popuprows,popupcols,mlx,POPMIN,1.0-mlx,muy); // Print the menu header for (currow=0;currowcurprogrep) { // Update the progress status curprogrep=floor(PROGBARSIZ*curcount/totcount); // Update the progress bar bae_popcolbar( PROGHDN+1,2,PROGHDN+1,2+curprogrep,PROGCOLDON); if (PROGALL) { // Display percentage report sprintf(progress,PROGREPPCT, 100*curcount/totcount,curcount,totcount); bae_poptext(PROGHDN,2,progress); } } if (PROGALL) { if (PROGQUIT) // Display percentage report sprintf(progress,PROGREPPCT, 100*curcount/totcount, curcount,totcount,clock()-progstime); else // Display percentage report sprintf(progress,PROGREPPCT, 100*curcount/totcount,curcount,totcount); bae_poptext(PROGHDN,2,progress); } } } void checkabort() /* // Check for program abort request */ { int progressabort /* Progress bar abort flag */; // Test on program abort request if (kbhit()) { getchr(); if (verify(UPRPEXIT,0)) { bae_msgprogressterm(); error_abort(); } } bae_getintpar(43,progressabort); if (progressabort) { // Verify abort if (verify(UPRPEXIT,0)) { bae_msgprogressterm(); error_abort(); } bae_setintpar(43,0); } } void checkabortbar(int maxval) /* // Check for program abort request // Parameter: // int maxval : Progress bar max. value */ { int progressabort /* Progress bar abort flag */; // Test on program abort request if (kbhit()) { getchr(); if (verify(UPRPEXIT,0)) { bae_msgprogressterm(); error_abort(); } // Re-init the progress popup pop_progress(0,maxval); } bae_getintpar(43,progressabort); if (progressabort) { // Verify abort if (verify(UPRPEXIT,0)) { bae_msgprogressterm(); error_abort(); } bae_setintpar(43,0); // Re-init the progress popup pop_progress(0,maxval); } } // User Language program end