/* TESTDATA (LAY) -- Test Data Output */ /* TESTDATA (LAY) -- Testdatenausgabe */ /* // 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 (091027) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (060517) ENHANCEMENT: // Improved circle shape recognition. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (040721) ENHANCEMENT: // Added full batch call support. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (010625) RELEASED FOR BAE V5.0. // rl (010402) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000509) RELEASED FOR BAE V4.6. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980711) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // mb (960919) RELEASED FOR BAE V3.4. // mb (951012) IMPROVEMENT: // Performing BAE_Demo_check(2) before starting output. // mb (95) RELEASED FOR BAE V3.2. // mb (941129) IMPROVEMENT: // Warning messages post-poned. // mb (94) RELEASED FOR BAE V3.0. // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The testdata User Language program produces a generic // format test data output for the currently loaded layout. // The output is directed to a file. // // OUTPUT FILE FORMAT // // The test data output constists of a pad description and a // padstack placement section. The format of a pad description // in the pad section is given by: // // PAD padid (padname) { // graphiclist // } // // A graphiclist consists of one or more of the following items: // // BOX { (xcenter,ycenter) W width H height } // CIRCLE { (xcenter,ycenter) D diameter } // POLY { (x1,y1), (x2,y2), ... , (xn,yn) } // // Arcs in polygons are approximated by the line connecting the // arc end points. // // The padstack placement section is a table of placement entries. // The first column specifies the padstack type. // Valid padstack types are: // // drill - Padstack containing only drills // pin - Part pin padstack // via - Via padstack // // A drill table entry consists of the drill coordinates and the // drill diameter. // // Pin and via table entries consist of pad id, net name, Layer // (0 for all layers), pad x coordinate, pad y coordinate, pad // angle and optionally drill x coordinate, drill y coordinate, // and drill diameter if drills are placed on the padstack. The // table contains one entry for every combination of drills and // pads on a padstack. // // WARNING // // Pins connected to short circuits are assigned to net NIL. */ // Includes #include "pop.ulh" // User Language popup utilities #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string REPTDWRITE = M("Testdaten-Ausgabe...","Test data output..."); string REPTDDONE = M("Testdaten ausgegeben auf Datei '%s'.", "Test data written to file '%s'."); string REPTDFILE = M("Testdaten Datei .....................: '%s'", "Test Data File ..........................: '%s'"); string WRNPADARC = M("WARNUNG : Pad '%s' Kreisbogen durch Gerade genaehert!", "WARNING : Pad '%s' arc substituted by line!"); // Format strings #define FMTPADHD "/* Pad info */\n\nPADS\n\n" #define FMTPAD "PAD %03d (%s) {\n" #define FMTPADM "PAD %03d (%s m) {\n" #define FMTTESTHD "/* Test data */\n\n" #define FMTDATAHD "DATA {\n\n" #define FMTDATA "/*\nTyp Pad Net Layer X Y Angle DX DY DDIA\n*/\n\n" #define FMTCIRCLE "\tCIRCLE { (%.2f,%.2f) D %.2f }\n" #define FMTBOX "\tBOX { (%.2f,%.2f) W %.2f H %.2f }\n" #define FMTPOLY "\tPOLY {\n\t\t" #define FMTPOINT " (%.2f,%.2f)%s" #define FMTSMDPAD "%s %03d %-15s %2d %6.2f %6.2f %6.2f" #define FMTDRLPAD "%s %03d %-15s %2d %6.2f %6.2f %6.2f %6.2f %6.2f %.2f" #define FMTDRL "drill %.2f %.2f %.2f" #define FMTNL "\n" #define FMTTABEND "}\n" #define FMTTERM "\t}\n" #define FMTWRAP "\n\t\t" #define FMTCMDEND ";\n" // INI file parameter name definitions #define PAR_TESTFEXT "TESTFEXT_LAY" // Test file name extension // Globals string TESTEXT = bae_inistrval(PAR_TESTFEXT,".tst") /* Test file name extension */; #define SMALLVAL 0.000001 // Small compare value #define GV_BATCALL "BAT_CALL" // Remote control operation flag #define GV_BATREPCNT "BAT_REPCNT" // Remote control op. report count #define GV_BATREPLINE "BAT_REPL_" // Remote control op. report line int tdfh /* Test data output file handle */; string jobfname /* Job file name */; string jobename /* Job element name */; int curpinmac /* Current padstack type : 1 = pin 0 = via */; string curtreename /* Current tree name */; struct padlib { // Pad info int pl_alwy /* Pad standard polygon count */; int pl_mirr /* Pad mirror polygon count */; int pl_nomi /* Pad no mirror polygon count */; string pl_name /* Pad name */; } padll[] /* Pad info list */; int padln = 0 /* Pad info count */; struct paddata { // Pad data double pad_x,pad_y /* Pad coordinates */; double pad_ang /* Pad rotation angle */; int pad_lay /* Pad layer code */; int pad_mirr /* Pad mirroring flag */; int pad_idx /* Pad index */; } padl[] /* Pad list */; int padn = 0 /* Pad count */; struct ptdes { // Point descriptor double x,y /* Point coordinate */; int typ /* Point type */; }; struct drldes { // Drill descriptor double drl_x,drl_y /* Drill coordinates */; double drl_rad /* Drill radius */; int drl_class /* Drill class */; } drll[] /* Drill list */; int drln = 0 /* Drill count */; int toplay = lay_plantoplay() /* Plan top player */; int ilaycnt = lay_planmidlaycnt() /* Inner layer count */; int ilayub /* Inner layer upper boundary */; STRINGS msgl /* Message list */; int msgn = 0 /* Message count */; // Main program void main() { string tdname /* Test data output file name */; int i /* Loop control variable */; // Abort if invalid plan class if (bae_planddbclass()!=DDBCLLAY) error_class(); // Perform BAE Demo check with abort option BAE_Demo_check(2); // Save current element with verification on request verifysave(); // Get the plan file and element name jobfname=bae_planfname(); jobename=bae_planename(); tdname=convstring(jobfname,0)+TESTEXT; // Get the inner layer range upper boundary ilayub= toplay==1 ? (ilaycnt+2) : toplay ; // Open the test data output file tdfh=bae_fopen(tdname,1); // Write the output message bae_prtdialog(REPTDWRITE); // Write pad info padout(); // Write padstack placement data pstkout(); // Close test data file fclose(tdfh); // Check if remote control operation if (varget(GV_BATCALL,0)==0) { vardelete(GV_BATCALL); // Print messages sprintf(msgl[msgn],REPTDFILE,tdname); msgn++; for (i=0;ipidx;i--) padll[i]=padll[i-1]; // Insert new data padll[pidx].pl_name=mac.NAME; padll[pidx].pl_mirr=0; padll[pidx].pl_nomi=0; // Adjust pad info count padln++; } // Get pad info for (pidx=0;pidx0 || padn>0) flushpin(); // Write test data table end fprintf(tdfh,FMTTABEND); } double outlength(double val) /* // Convert a length value to output units // Return value : // converted length value // Parameters : // double val : Value */ { double newval /* New value */; // Convert to mm newval=cvtlength(val,0,2); // Prevent output of signed zero return(newval==0.0?0.0:newval); } double outangle(double ang) /* // Convert an angle value to output units // Return value : // converted angle value // Parameters : // double ang : Angle */ { // Convert to degree return(cvtangle(ang,0,1)); } int polyout(struct ptdes pl[],int pn) /* // Write polygon. Check for basic shapes // Return value : // zero if ok, or 1 if noncircle polygon arcs found // Parameters : // struct ptdes pl[] : Polygon point list // int pn : Polygon point count */ { int arcflag /* Poly. contains arcs flag */; double xmin,ymin /* Shape minimum coords. */; double xmax,ymax /* Shape maximum ccords. */; double xcent,ycent /* Shape center point */; double r /* Circle radius */; double r1,r2 /* Arc radius buffer vars. */; int centcnt /* Center point count */; int pidx /* Previous point index */; int nidx /* Next point index */; double x,y /* Current point coords. */; int i /* Loop control variable */; // Test if there are arcs arcflag=0; for (i=0;i0.0 || fabs(pl[nidx].y-y)>0.0 ) { // Not a standard shape polyline(pl,pn); return(arcflag); } // Store the center coordinates xcent+=x; ycent+=y; centcnt++; } } else { // Check if rectangle // Get the previous and next point indexes pidx=i-1; if ((pidx=i-1)<0) pidx=pn-1; if ((nidx=i+1)>=pn) nidx=0; // Test if rectangle corner if ( ! ( fabs(pl[nidx].x-x)==0.0 && fabs(pl[pidx].y-y)==0.0 || fabs(pl[nidx].y-y)==0.0 && fabs(pl[pidx].x-x)==0.0)) { // Not a standard shape polyline(pl,pn); return(arcflag); } } } // Get the polygon range bae_getpolyrange(xmin,ymin,xmax,ymax); // Get the shape specific data if (arcflag) { // Test if the center count is valid if (centcnt!=2) { // Not a standard type polyline(pl,pn); return(arcflag); } // Calc. the arc center point xcent/=2.0; ycent/=2.0; // Calc. both possible radius values r1=fabs(xmin-xcent); r2=fabs(xmax-xcent); // Test if both are equal if (fabs(r1-r2)>SMALLVAL) { // Not a standard shape polyline(pl,pn); return(arcflag); } // Get the min. radius r= r10) { // Check pad count if (padn>0) { // Loop for all drills for (i=0;i0 || padn>0) flushpin(); // Set padstack type curpinmac=refname==""?0:1; break; // Pad case DDBCLLPAD : // Check if signal layer pad if (layoff==LAYERALL || layoff==LAYERBTW || layoff==LAYERTOP || (layoff>=0 && layoff<100)) { // Translate part side layer if (layoff==LAYERTOP) layoff=toplay; // Search library pad for (pidx=0;pidx=0) { // Check if mirroring possible if (layoff<=toplay) // Mirror at part side layoff=toplay-layoff; else if (layoff