/* AIRLDENS (LAY) -- Airlines Density Diagram */ /* AIRLDENS (LAY) -- Airline-Dichteverteilungsdiagramm */ /* // Copyright (c) 1994-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 (091020) 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 (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (030904) RELEASED FOR BAE V6.2. // rl (030327) ENHANCEMENT: // Added bitmap label support. // rl (021209) RELEASED FOR BAE V6.0. // rl (021021) ENHANCEMENT: // Improved zoom to arc shaped boundaries. // rl (020618) RELEASED FOR BAE V5.4. // rl (010625) RELEASED FOR BAE V5.0. // rl (010409) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (000508) RELEASED FOR BAE V4.6. // rl (990625) RELEASED FOR BAE V4.4. // rl (990113) BUGFIX: // Fixed arc outline size bug. // rl (980910) RELEASED FOR BAE V4.2. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (970929) RELEASED FOR BAE V4.0. // mb (960919) RELEASED FOR BAE V3.4. // mb (960801) ENHANCEMENT: // Changed menu items to support key selection // in Windows/Motif user interfaces. // mb (95) RELEASED FOR BAE V3.2. // mb (94) ORIGINAL CODING. // // DESCRIPTION // // The airldens User Language program generates a coloured graphical // airline (unroutes) density diagram for the currently loaded layout. // Display area scaling depends on the resolution of the currently // used graphic device. */ // Includes #include "pop.ulh" // User Language popup utilities #include "popdraw.ulh" // User Language popup draw. util. #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // Messages string UPRABORT = M_UPRABORT(); string UPRPEXIT = M_UPRPEXIT(); string UPRPOPCONTINUE = M("(Weiter)","(Continue)"); string REPPROGUNRREP = M("Scannen Unroutes %d %% (%d / %d)...", "Scanning Unroutes %d %% (%d / %d)..."); string REPUNRREP = M("Scannen Unroutes...","Scanning Unroutes..."); string REPRESHD1 = M("Airlines-Dichteverteilung:", "Airlines Density Map:"); string REPRESHD2 = M("Layout '%s' / '%s'","Layout '%s' / '%s'"); string REPRESHD3 = M("Airlines %d / Laenge %.3f %s / Max. Dichte %d", "Airline %d / Length %.3f %s / Max. Density %d"); string UPRDISPL = M("Anzeige &Layout","Display &Layout"); string UPRDISPD = M("Anzeige &Dichte","Display &Density"); // INI file parameter name definitions #define PAR_PROGALL "ADPROGALL_LAY" // Popup progress all enable #define PAR_PROGQUIT "ADPROGQUIT_LAY"// Popup progress quit enable #define PAR_PROGBARSIZ "ADPBSIZE_LAY" // Popup progress bar size #define PAR_PROGCOLDON "ADPBCOLD_LAY" // Popup progress done color #define PAR_PICLABW "ADPICWIDTH_LAY"// Picture label width #define PAR_PICLABH "ADPICHEIGHT_LAY" // Picture label height #define PAR_DMATCOL "ADDMATCOL_LAY" // Density matrix columns #define PAR_DMATROW "ADDMATROW_LAY" // Density matrix rows // Globals int coltab[] = { // Density display color table 0, // Black 8, // Dark gray 7, // Light gray 1, // Blue 3, // Cyan 9, // Light blue 11, // Light cyan 2, // Green 10, // Light green 14, // Yellow 5, // Magenta 13, // Light magenta 6, // Brown 4, // Red 12 // Light red }; int colorn = arylength(coltab) /* Color count */; int maxdensity = 0 /* Maximum density */; int maxcoln,maxrown /* Maximum column/row count */; int coln,rown /* Column/row count */; double lx,ly,ux,uy /* Layout boundaries */; double lxdim, lydim /* Layout dimensions */; double hscal /* Horizontal scaling factor */; double vscal /* Vertical scaling factor */; double densscal /* Density scaling factor */; int densmat[][] /* Density matrix */; int unrcount = 0 /* Unroutes count */; double unrlength = 0.0 /* Unroutes length */; index L_POLY borderpoly /* Board outline polygon index */; int borderfound = 0 /* Board outline found flag */; int dialsupport = 0 /* Dialog box support flags */; // 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)" 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 = {REPUNRREP} /* Popup progress header list */; int curprogrep = (-1) /* 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 */; double PICLABWIDTH = bae_iniintval(PAR_PICLABW,50.0) /* Picture label width */; double PICLABHEIGHT = bae_iniintval(PAR_PICLABH,10.0) /* Picture label height */; int DENSMATCOL = bae_iniintval(PAR_DMATCOL,100) /* Density matrix columns */; int DENSMATROW = bae_iniintval(PAR_DMATROW,100) /* Density matrix rows */; // Main program void main() { index L_POINT point /* Point index */; double mlx,mly,mux,muy /* Popup window boundaries */; double width,height /* Density display width/height */; int colidx /* Display color table index */; string hd1 /* Popup header string 1 buffer */; string hd2 /* Popup header string 2 buffer */; string hd3 /* Popup header string 3 buffer */; string strbuf /* Display string buffer */; int mincol /* Minimum popup column count */; int c,r /* Column/row index */; int abort /* Abort flag */; int dialflag /* Dialog box flag */; double labwidth /* Picture label width */; double labheight /* Picture label height */; double legwidth /* Legend label width */; double legheight /* Legend label height */; double cx, cy /* Current dialog coord. values */; double wfxsize, wfysize /* Workspace font char. pixel size */; double dfxsize, dfysize /* Dialog font char. pixel size */; double waspectratio /* Window font aspect ratio */; // Abort if invalid plan class if (bae_planddbclass()!=DDBCLLAY) error_class(); // Get the dialog support flags bae_getintpar(41,dialsupport); // Get the layout boundaries getlaybound(); if (bae_dialclr()) { // Init the popup window boundaries mlx=mly=0.0; mux=muy=1.0; // Get the row and column count bae_twsize(maxcoln,maxrown); coln=maxcoln-4-8; rown=maxrown-4-2; // Get display width and height width=32.0*coln; height=48.0*rown; dialflag=0; } else { // Init the bitmap boundaries coln=DENSMATCOL; rown=DENSMATROW; width=DENSMATCOL; height=DENSMATROW; dialflag=1; } // Adjust the density matrix size to layout aspect ratio if (lxdim/width>lydim/height) rown=rown*lydim/lxdim*width/height+0.5; else coln=coln*lxdim/lydim*height/width+0.5; // "Allocate" and init the density matrix for (c=coln-1;c>=0;c--) for (r=rown-1;r>=0;r--) densmat[c][r]=0; // Get the horizontal/vertical scaling factor hscal=lxdim/coln; vscal=lydim/rown; // Perform the unroutes report unroutesrep(); // Get the density scaling factor densscal=maxdensity; densscal/=(colorn-1); // Get the popup header strings sprintf(hd1,REPRESHD1); sprintf(hd2,REPRESHD2,bae_planfname(),bae_planename()); sprintf(hd3,REPRESHD3,unrcount,baecvtl(unrlength), bae_getcoorddisp() ? "\"" : "mm",maxdensity); if (dialflag) { // Restore the popup area if (!(dialsupport&DIAL_PROGRESS)) bae_poprestore(); // Set the default picture label bitmap size labwidth=PICLABWIDTH; labheight=PICLABHEIGHT; // Get the character base sizes bae_charsize(wfxsize,wfysize); bae_popsetarea(2); bae_charsize(dfxsize,dfysize); // Get the requested legend size legwidth=9.0*wfxsize/dfxsize; legheight=18.0*wfysize/dfysize; // Get the drawn characters aspect ratio waspectratio=wfxsize/wfysize; // Create the legend label bitmap if (bmp_setsize(-0.5*waspectratio,-0.5,8.5*waspectratio, 17.5,legwidth,legheight,0.0,0.0) || bae_dialbmpalloc(legwidth,legheight,2,0,0)!=2) error_abort(); // Draw the legend label bitmap bae_popsetarea(2); btp_drawrect(COLOR_BBACK,DM_REPLACE,1, -0.5*waspectratio,-0.5,9.0*waspectratio,18.0); // Display the density colors legend btp_drawtext(0.0,0.0,COLOR_BTEXT,COLOR_BBACK,"Legende:"); btp_drawrect(coltab[0], DM_REPLACE,1,0.0,1.0,1.0*waspectratio,1.0); sprintf(strbuf,"=%5.1f",0); btp_drawtext(2.0*waspectratio,1.0, COLOR_BTEXT,COLOR_BBACK,strbuf); for (c=1;c%5.1f",(c-1)*densscal); btp_drawtext(2.0*waspectratio,c+1.0, COLOR_BTEXT,COLOR_BBACK,strbuf); } sprintf(strbuf,"<%5.1f",maxdensity); btp_drawtext(2.0*waspectratio,c+1.0, COLOR_BTEXT,COLOR_BBACK,strbuf); // Create the picture label bitmap if (bmp_setsize(-0.05*coln,1.05*rown, 1.05*coln,-0.05*rown,labwidth,labheight,0.0,0.0) || bae_dialbmpalloc(labwidth,labheight,3,0,0)!=3) error_abort(); // Draw the picture label bitmap bae_popsetarea(3); if (densscal!=0.0) for (c=0;c=colorn) colidx=colorn-1; // Display the density value btp_drawrect(coltab[colidx], DM_REPLACE,1,c,r,1.0,1.0); } // Check if board outline defined if (borderfound) { bae_clearpoints(); forall (point of borderpoly) btp_storepoint((point.X-lx)/hscal, (point.Y-ly)/vscal,point.TYP); bae_popdrawpoly(15,DM_COMPLEMENT,PPFM_CLINE); } bae_popsetarea(0); // Store the header labels cy=DIAL_TOPMARG; dial_label(0.0,cy,hd2); cy+=DIAL_TXTVSTEP; cx=strlen(hd2); dial_label(0.0,cy,hd3); if (strlen(hd3)>cx) cx=strlen(hd3); cx*=1.0; cy+=DIAL_CTRVSTEP; // Store the legend display label bae_dialadvcontrol(PA_BMLAB,0,0,2,0.0,0.0,0.0,"",0, DIAL_LEFTMARG,cy,legwidth,legheight,""); // Store the bitmap display label bae_dialadvcontrol(PA_BMLAB,0,0,3,0.0,0.0,0.0,"",0, DIAL_LEFTMARG+legwidth+2.0,cy,labwidth,labheight,""); labwidth=legwidth+2.0+labwidth; // Store the buttons cy+= (labheight>legheight ? labheight : legheight)+DIAL_SEPVSTEP; bae_dialaddcontrol( PA_OK,0,0,0,0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,0.0,""); bae_setintpar(16,4000); bae_dialaskparams(hd1,0,DIAL_LEFTMARG+ (cx>labwidth ? cx : labwidth)+DIAL_BMPBUTHO,cy+DIAL_BUTVSTEP); } else { // Get the minimum popup column count mincol=maxint( maxint(coln+2+8,strlen(hd1)), maxint(strlen(hd2),strlen(hd3))); // Repetively toggle between density and layout display do { // Show the density display popup if (rown%5.1f",(c-1)*densscal); bae_poptext(3+1+c,3,strbuf); } sprintf(strbuf,"<%5.1f",maxdensity); bae_poptext(3+1+c,3,strbuf); // Display the density matrix bae_popcolbar(3,2+8,3+rown-1,2+8+coln-1,0); if (densscal!=0.0) for (c=0;c=colorn) colidx=colorn-1; // Display the density value bae_popcolbar(3+rown-1-r, 2+8+c,3+rown-1-r, 2+8+c,coltab[colidx]); } // Verify layout re-display abort=bae_askmenu(2,UPRDISPL,UPRABORT); // Restore the popup area bae_poprestore(); // Abort on request if (abort) break; // Zoom all zoomall(); // Loop until no more density display is requested } while (bae_askmenu(2,UPRDISPD,UPRABORT)==0); } } void getlaybound() /* // Get the layout boundary values */ { index L_POLY poly /* Polygon index */; index L_POINT point /* Point index */; // Set default boundaries lx=bae_planwslx(); ly=bae_planwsly(); ux=bae_planwsux(); uy=bae_planwsuy(); // Loop for polygons (board outline is always first polygon) forall (poly) { // Abort if no board outline if (poly.TYP!=L_POLYBRDOUT) break; // Loop for polygon points bae_clearpoints(); forall (point of poly) // Store point to internal list bae_storepoint(point.X,point.Y,point.TYP); // Get the polygon range bae_getpolyrange(lx,ly,ux,uy); // Store the board outline polygon borderpoly=poly; borderfound=1; // Done break; } // Get the layout dimensions lxdim=ux-lx; lydim=uy-ly; } void unroutesrep() /* // Produce an unroutes report */ { index L_CNET n /* Net index */; int netcount = 0 /* Net count */; int netmax = 0 /* Net maximum count */; int progressabort /* Progress bar abort flag */; // Loop thru the list of nets with unroutes pool links forall (n) netmax++; // Display the initial progress popup pop_progress(netcount,netmax); // Loop thru the list of nets with unroutes pool links forall (n) { // Test if unroutes on net if (n.PINN>1 && n.UNRPOOL>=0) { // Scan the unroutes pool if (lay_scanpool(n.UNRPOOL,lx,ly,0.0,0,1, NULL,NULL,pathfunc,NULL,NULL,layunrchk,NULL)) error_scan(); } // Test on program abort request if (kbhit()) { getchr(); // Verify abort if (verify(UPRPEXIT,0)) { bae_msgprogressterm(); error_abort(); } // Re-init the progress popup pop_progress(0,netmax); } bae_getintpar(43,progressabort); if (progressabort) { // Verify abort if (verify(UPRPEXIT,0)) { bae_msgprogressterm(); error_abort(); } bae_setintpar(43,0); } // Update the progress popup pop_progress(++netcount,netmax); } // Done bae_prtdialog(""); } int pathfunc(index L_LINE path,int layer,int pathinws,index L_LEVEL level) /* // Path scan function // Return value : // zero if done or (-1) on error // Parameters : // index L_LINE path : Path index // int layer : Path transformed layer code // int pathinws : Path in workspace flag // index L_LEVEL level : Path level */ { index L_POINT p /* Point index */; double x1 = 0 /* Previous point X coordinate */; double y1 = 0 /* Previous point Y coordinate */; int sx,ex /* X range boundaries */; int sy,ey /* Y range boundaries */; int c,r /* Column/row index */; int intbuf /* Integer buffer */; // Loop thru the point list forall (p of path) { // Test the point index if (p>0) { // Update the unroutes count unrcount++; // Update the unroutes length unrlength+=dist(p.X,p.Y,x1,y1); // Get the segment range if (x1maxdensity) maxdensity=intbuf; } } // Move current to previous point x1=p.X; y1=p.Y; } // Return without errors return(0); } int layunrchk(int layer) /* // Layer check scan function // Return value : // 1 if inside workspace or zero otherwise // Parameters : // int layer : Layer number */ { // Check if layer of interest; return the inside workspace flag return(layer==(-4)?1:0); } // 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,REPPROGUNRREP, 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) { // Display percentage report sprintf(progress,PROGREPPCT, 100*curcount/totcount,curcount,totcount); bae_poptext(PROGHDN,2,progress); } } } // User Language program end