/* CEDGROUP (CED) -- Chip Editor Group Functions */ /* CEDGROUP (CED) -- Chipeditor-Gruppenfunktionen */ /* -- INTENDED FOR KEY-CALL USE -- */ /* // Copyright (c) 2001-2012 Oliver Bartels F+E, Muenchen // Author: Roman Ludwig // 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 (060814) ENHANCEMENT: // Added graphical matrix size definition option. // Added group matrix autoselection option. // rl (051212) ENHANCEMENT: // Changed zoom all to zoom out to result for matrix copies. // rl (051206) BUGFIX: // Fixed #-name selection problem. // rl (050906) RELEASED FOR BAE V6.6. // rl (040811) RELEASED FOR BAE V6.4. // rl (031204) ENHANCEMENT: // Added macro name list sorting. // rl (030904) RELEASED FOR BAE V6.2. // rl (021211) RELEASED FOR BAE V6.0. // rl (020618) RELEASED FOR BAE V5.4. // rl (020308) ENHANCEMENT: // Added group selection by part name(s). // rl (010802) ORIGINAL CODING. DERIVED FROM GEDGROUP.ULC. // // DESCRIPTION // // The cedgroup User Language program provides a menu with advanced // Chip Editor group functions such as automatic // selection and/or de-selection of specially defined groups // of elements of the currently loaded IC Design element (e.g. // all objects of a selectable type, all fixed/unfixed, all // mirrored/unmirrored, all on selectable layer, etc.). // There are also functions available for automatic group copy, // for layer-selective group delete or for changing text size // and/or trace width of all group-selected texts and/or traces. */ // Includes #include "pop.ulh" // User Language popup utilities #include "icd.ulh" // User Language IC Design utilities // Disable undo state request #pragma ULCALLERNOUNDO // INI file parameter name definitions #define PAR_GPARTSUF "GPARTSUF_CED" // Group part name suffix #define PAR_GPRECTSEL "GPRECTSEL_CED" // Group rectangle selection flag // Messages string UPRABORT = M_UPRABORT(); string UPRFEXIT = M_UPRFEXIT(); string REPDONE = M("Es wurden keine Fehler festgestellt.", "Operation completed without errors."); string REPSELDONE = M("Gruppe selektiert.", "Group elements selected."); string REPDSELDONE = M("Gruppe deselektiert.", "Group elements deselected."); string REPLCTEXT = M("Text-Lagen aendern...", "Changing text layers..."); string REPLCPOLY = M("Polygonlagen aendern...", "Changing polygon layers..."); string REPLCPATH = M("Leiterbahn-Lagen aendern...", "Changing path layers..."); string REPSCTEXT = M("Text-Groessen aendern...", "Changing text sizes..."); string REPSCPATH = M("Leiterbahnbreiten aendern...", "Changing path widths..."); string REPLCDONE = M(" Lagenaenderungen durchgefuehrt.", " layer changes performed."); string REPSCDONE = M(" Groessenaenderungen durchgefuehrt.", " size changes performed."); string REPMACLIST = M("Auswahl Makrotyp %s :", "Selection Menu Macro Type %s :"); string REPNAMELIST = M("Auswahl Name :","Name Selection :"); string REPGNAMELIST = M("Auswahl Gruppenname :","Group Name Selection :"); string REPSCANATT = M("Scannen Bauteile/Attribute...", "Scanning parts/attributes..."); string REPATTL = M("Definierte Attribute :","Defined Attributes : "); string REPATTVALL = M("Attributwerte zu '%s' :", "Attribute values for '%s' : "); string REPATTSEL = M(" Bauteil(e) selektiert."," part(s) selected."); string UPRGRPFCT = M("Gruppenfunktion selektieren!", "Select Group Function!"); string UPRFCT1 = M("&Selektieren","&Select"); string UPRFCT2 = M("&Deselektieren","&Deselect"); string UPRFCT3 = M("R&echteck selektieren","Select R&ectangle"); string UPRFCT4 = M("Re&chteck deselektieren","Deselect Rectan&gle"); string UPRFCT5 = M("%Lage l&oeschen","%Delete La&yer"); string UPRFCT6 = M("%&Text-Lagen aendern","%Change &Text Layers"); string UPRFCT7 = M("&Polygon-Lagen aendern","Change &Polygon Layers"); string UPRFCT8 = M("Polygon-T&yp aendern","Change Pol&ygon Types"); string UPRFCT9 = M("&Bahn-Lagen aendern","Change Pat&h Layers"); string UPRFCT10 = M("%Text&groessen aendern","%Change Text Si&zes"); string UPRFCT11 = M("Ba&hnbreiten aendern","Change Path &Widths"); string UPRFCT12 = M("%Bauteiltexte &Reset","%&Reset Part Texts"); string UPRFCT13 = M("%Bahnen-&Kopie","%&Copy Traces"); string UPRFCT14 = M("Matri&x-Kopie","Copy Matri&x"); string UPRFCT15 = M("%Gruppennamen setzen","Set Group Name"); string UPRFCT16 = M("%&Laden ohne Hierarchie","&Load without Hierarchy"); string UPRSELALL = M("A&lles","A&ll"); string UPRSELPRT = M("&Makros","&Macros"); string UPRSELAPRT = M("Alle &Makros","All &Macros"); string UPRSELATRC = M("Alle Leite&rbahnen","All T&races"); string UPRSELTRC = M("&Leiterbahnen","T&races"); string UPRSELAPLY = M("Alle Flae&chen","All Area&s"); string UPRSELPLY = M("&Flaechen","Area&s"); string UPRSELATXT = M("Alle &Texte","All &Texts"); string UPRSELTXT = M("&Texte","&Texts"); string UPRSELVIS = M("%Alles s&ichtbar","%All &visible"); string UPRSELIVIS = M("Alles u&nsichtbar","All &invisible"); string UPRSELFIX = M("%Fi&xiert alles","%All fi&xed"); string UPRSELUFIX = M("Un&fixiert alles","All un&fixed"); string UPRSELMIR = M("%Ge&spiegelt alles","%All &mirrored"); string UPRSELUMIR = M("&Ungespiegelt alles","All &unmirrored"); string UPRSELLAY = M("%La&ge","%La&yer"); string UPRSELCON = M("%&Con-Elemente","%&Con. Elements"); string UPRSELNCON = M("&Nicht-Con-Elemente","N&on-Con. Elements"); string UPRSELATTR = M("%Attribute","%Attributes"); string UPRSELMAC = M("%&Makros","%&Macros"); string UPRSELNAM = M("%Na&men","%N&ames"); string UPRSELGNAM = M("Gru&ppenname","&Group Name"); string UPRSELWINS = M("Gruppenrechteck Startpunkt waehlen!", "Select Group Rectangle Start Point!"); string UPRSELWINE = M("Gruppenrechteck Endpunkt waehlen!", "Select Group Rectangle End Point!"); string UPRLAYER = M("Lage waehlen!","Select Layer!"); string UPRTSIZEM = M("Neue Textgroesse [mm] ? ", "New Text Size [mm] ? "); string UPRTSIZEI = M("Neue Textgroesse [Inch] ? ", "New Text Size [Inch] ? "); string UPRPWIDTHM = M("Neue Leiterbreite [mm] ? ", "New Trace Width [mm] ? "); string UPRPWIDTHI = M("Neue Leiterbreite [Inch] ? ", "New Trace Width [Inch] ? "); string UPRGRPCNT = M("Anzahl Gruppenkopien ? ","Group Copy Count ? "); string UPRGRPMATC = M("Gruppe Matrixkopie","Group Matrix Copy"); string UPRGRPMATGS = M("Groesse mit Fadenkreuz","Crosshair Size Input"); string UPRGRPMATRS = M("Autoselektion 1. Rechteck", "Autoselect 1st Rectangle"); string UPRGRPXCNTD = M("Matrixelemente X-Richtung :", "Matrix X Count :"); string UPRGRPYCNTD = M("Matrixelemente Y-Richtung :", "Matrix Y Count :"); string UPRGRPXCNT = M("Anzahl Matrixelemente X-Richtung ? ", "Matrix X Count ? "); string UPRGRPYCNT = M("Anzahl Matrixelemente Y-Richtung ? ", "Matrix Y Count ? "); string UPRSELORG = M("Gruppennullpunkt waehlen!", "Select Group Origin!"); string UPRSELVEC = M("Erste Kopieposition waehlen!", "Select First Copy Position!"); string UPRSELMVEC = M("Diagonalecke erstes Matrixrechteck waehlen!", "Select First Matrix Rectangle Diagonal Vertice!"); string UPRSELMEND = M("Matrix Endposition waehlen!", "Select Matrix End Position!"); string UPRSELANAM = M("Attributname ? ","Attribute Name ?"); string UPRSELAVAL = M("Attributwert(smuster) ? ", "Attribute Value (Pattern) ?"); string UPRSELMACTP = M("Makrotyp fuer (De-)Selektion waehlen!", "Select Macro Type to (de)select)!"); string UPRMACCELL = M("&Zelle","&Cell"); string UPRMACPIN = M("&Pin/Via","&Pin/Via"); string UPRSELMACRO = M("Makroname(nsmuster) fuer Selektion ? ", "Macro name (or pattern) to select ? "); string UPRUSELMACRO = M("Makroname(nsmuster) fuer Deselektion ? ", "Macro name (or pattern) to deselect ? "); string UPRSELNAME = M("Name(nsmuster) fuer Selektion ? ", "Name (or pattern) to select ? "); string UPRDSELNAME = M("Name(nsmuster) fuer Deselektion ? ", "Name (or pattern) to deselect ? "); string UPRSELGNAME = M("Gruppenname fuer Selektion ? ", "Group name to select ? "); string UPRDSELGNAME = M("Gruppenname fuer Deselektion ? ", "Group name to deselect ? "); #define DE_UPRFILE "Dateiname ? " #define EN_UPRFILE "File Name ? " string UPRFILE = M(DE_UPRFILE,EN_UPRFILE); #define UPRCLILAY "Chip &Layout" string UPRCLICELL = M("Chip Std.-&Zelle" ,"Chip Std. &Cell"); #define UPRCLIPIN "Chip &Pin" string ERRNOGRP = M("Gruppe enthaelt kein Element von Interesse!", "Group contains no element of interest!"); string ERRCOORD = M("Ungueltige Koordinaten!", "Invalid coordinates!"); string ERRCREATE = M("Fehler beim Erzeugen eines neuen Elementes!", "Error creating new element!"); string ERRPATH = M("Fehler beim Erzeugen der neuen Leiterbahn!", "Error creating new trace!"); string ERRDELETE = M("Fehler beim Loeschen von Elementen!", "Error deleting element!"); string ERRLCPOLY = M("Fehler beim Aendern der Polygonlage!", "Error changing poly layer!"); string ERRLCPATH = M("Fehler beim Aendern der Leiterbahnlage!", "Error changing path layer!"); string ERRLCTEXT = M("Fehler beim Aendern der Textlage!", "Error changing text layer!"); string ERRSCTEXT = M("Fehler beim Aendern der Textgroesse!", "Error changing text size!"); string ERRSCPATH = M("Fehler beim Aendern der Leiterbreite!", "Error changing trace width!"); string ERRNOFGRP = M("%s '%s' in Datei '%s' nicht gefunden!", "%s '%s' not found in file '%s'!"); string ERRINPVAL = M_ERRINPVAL(); string WRNNOATTRDEF = M("Keine Attributdefinitionen gefunden!", "No attribute definitions found!"); string WRNNOATTRVAL = M("Keine Werte fuer Attribut '%s' definiert!", "No attribute value definitions for '%s' found!"); // Globals string PARTSUFFIX = bae_inistrval(PAR_GPARTSUF,"gpcp") /* Group part name suffix */; int GPRECTSEL = bae_iniintval(PAR_GPRECTSEL,0) /* Group rectangle selection mode */; #define FIGTYPALL 0 // Figure list type all #define SD 0.000001 // Small distance value #define SMALLVAL 0.00000001 // Small compare value #define GV_GRPXCNT "grpmat_x" // Matrix X count variable #define GV_GRPYCNT "grpmat_y" // Matrix Y count variable #define GV_GRPCNT "grpcopyn" // Group copy count variable int ddbclass = bae_planddbclass() /* Plan DDB class */; int plcelems = 0 /* Placed element bit field */; int grpelems = 0 /* Group element bit field */; string ps_dis = "" /* Part/padstack items disable */; string s_dis = "" /* Padstack items disable */; string g_dis = "" /* Group empty disable */; string gt_dis = "" /* Group text empty disable */; string dgt_dis = "" /* Text empty disable */; string gl_dis = "" /* Group line empty disable */; string dgl_dis = "" /* Line empty disable */; string glv_dis = "" /* Group line/via empty disable */; string dglv_dis = "" /* Line/via empty disable */; string gp_dis = "" /* Group polygon empty disable */; string dgp_dis = "" /* Polygon empty disable */; string gn_dis = "" /* Group named ref. empty disable */; string dgn_dis = "" /* Named ref. empty disable */; string ga_dis = "" /* Group all empty disable */; int selectmode /* Select mode : 0 = deselect 1 = select */; struct ppoint { // Polygon point structure double x,y /* Point coordinates */; int typ /* Point type */; } pplist[] /* Polygon point list */; int ppcnt /* Polygon point count */; string macroname /* Macro name */; int polytyp /* Polygon type */; int polytfound /* Polygon tree found flag */; string textstr /* Text string */; string vianame /* Via macro name */; string selmacroname /* Selected macro name */; int cursearchclass /* Current macro search class */; STRINGS namel /* Name list */; int namen = 0 /* Name count */; // Main program void main() { // Test the plan class switch (ddbclass) { case DDBCLILAY : break; case DDBCLICELL : ps_dis=","; break; case DDBCLIPIN : s_dis=","; break; default : error_class(); } // Check if element type scan if (bae_iniintval(PAR_METYPSCAN,1)==1 && !bae_peekiact()) { groupscan(); if (grpelems==0) g_dis=","; if ((plcelems&(1<6) // Abort on default error_abort(); // Disable range check bae_getintpar(0,rangedis); bae_setintpar(0,1); // Free grid lock gridlock=bae_getgridlock(); bae_setgridlock(0); // Get the rectangle Points bae_promptdialog(UPRSELWINS); if (bae_inpoint(bae_planwsnx(),bae_planwsny(),x1,y1,0)) { // Restore old range check state bae_setintpar(0,rangedis); // Restore grid lock bae_setgridlock(gridlock); error_abort(); } bae_promptdialog(UPRSELWINE); if (bae_inpoint(x1,y1,x2,y2,1)) { // Restore old range check state bae_setintpar(0,rangedis); // Restore grid lock bae_setgridlock(gridlock); error_abort(); } // Restore old range check state bae_setintpar(0,rangedis); // Restore grid lock bae_setgridlock(gridlock); // Setup the interaction queue bae_clriactqueue(); bae_storemenuiact(1,elemtyp,LMB); bae_storemenuiact(1,selectmode ? 0 : 1,LMB); bae_storemouseiact(1,x1,y1,0,LMB); bae_storemouseiact(1,x2,y1,0,LMB); bae_storemouseiact(1,x2,y2,0,LMB); bae_storemouseiact(1,x1,y2,0,LMB); bae_storemouseiact(1,0.0,0.0,0,RMB); bae_storemenuiact(1,0,LMB); bae_callmenu(MNU_GEDGRPPOLY); // Select done bae_prtdialog(selectmode ? REPSELDONE : REPDSELDONE); } // Group element functions static void selectall(int etyp) /* // Group polygon select/deselect all // Parameters : // int etyp : Element type */ { // Select/deselect all of ced_groupselect(0,etyp,selectmode); } static void selectvis(int visflag) /* // Select all elements with given visibility // Parameters : // int visflag : Visibility */ { // Select/deselect all visible/invisible elements ced_groupselect(3,visflag,selectmode); } static void selectfix(int fixflag) /* // Select all elements with given fixed flag // Parameters : // int fixflag : Fixed flag */ { // Select/deselect all fixed/unfixed elements ced_groupselect(2,fixflag,selectmode); } static void selectmir(int mirflag) /* // Select all elements with given mirror flag // Parameters : // int mirflag : Mirror flag */ { index I_FIGURE fig /* Figure list index */; int etyp /* Element type */; // Loop for all elements forall (fig where fig.MIRROR==mirflag) // Test the element type if ((etyp=fig.TYP)==I_FIGNREF || etyp==I_FIGUREF && ddbclass!=DDBCLILAY && ddbclass!=DDBCLICELL || etyp==I_FIGTEXT) // Select/deselect element to group ced_elemgrpchg(fig,selectmode); } static void selectattr() /* // Group select parts by attribute values */ { index I_CPART cpart /* Connection part index */; index I_FIGURE fig /* Figure list index */; index I_ATTRIBUTE attr /* Attribute index */; string attnam /* Attribute name */; string attval /* Attribute value */; STRINGS hl /* Popup menu header list */; int hn = 0 /* Popup menu header count */; int changes = 0 /* Changes count */; string prompt = "" /* Prompt string */; // Build attribute name list bae_prtdialog(REPSCANATT); forall (cpart where cpart.USED&CPART_PLC) forall (attr of cpart) gcname(attr.NAME); // Abort with warning if attributes found if (namen==0) { popupmessage(1,-1,-1,WRNNOATTRDEF,"",""); return; } // Build the attribute selection popup menu hl[0]=REPATTL; hl[1]=""; hn=2; // Select group attribute to be set/changed bae_setintpar(16,3004); if ((attnam=popupmenu(4,UPRSELANAM,hl,hn,namel,namen, UINPOPABORT,0,-1,-1,0,0,0,UINPOPABORT))=="" || attnam==UINPOPABORT || attnam[0]!='$') error_abort(); // Build attribute value list bae_prtdialog(REPSCANATT); namen=0; forall (cpart) forall (attr of cpart where attr.NAME==attnam) gcname(attr.VALUE); // Abort with warning if no attribute values found if (namen==0) { sprintf(prompt,WRNNOATTRVAL,attnam); popupmessage(1,-1,-1,prompt,"",""); return; } // Build the attribute selection popup menu sprintf(hl[0],REPATTVALL,attnam); // Select group attribute to be set/changed bae_setintpar(16,3005); if ((attval=popupmenu(4,UPRSELAVAL,hl,hn,namel,namen, UINPOPABORT,0,-1,-1,0,0,0,""))==UINPOPABORT) error_abort(); // Loop for all parts forall (cpart where cpart.USED&CPART_PLC) { // Search attribute forall (attr of cpart where attr.NAME==attnam && (strmatch(attr.VALUE,attval) || attr.VALUE==attval)) { if (icd_nrefsearch(cpart.NAME,fig)==0) { ced_elemgrpchg(fig,selectmode); changes++; } break; } } // Done bae_prtdialog(itoa(changes)+REPATTSEL); } int gcname(string name) /* // Get or create a name list entry // Return value : // entry index // Parameters : // string name : Name */ { int slb = 0 /* Search lower boundary */; int sub = namen-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; // Get the comparison result if ((compres=strcmp(name,namel[sidx]))==0) // Name found return(sidx); // Update the search area if (compres<0) sub=sidx-1; else slb=sidx+1; } // Update the name list for (sidx=namen;sidx>slb;sidx--) namel[sidx]=namel[sidx-1]; // Insert name namel[slb]=name; namen++; // Return sheet index return(slb); } static void selectcon(int conflag) /* // Select connection list elements // Parameters : // int conflag : Select con. flag (nonzero=connected) */ { index I_FIGURE fig /* Figure list index */; // Evaluate the con. flag if (conflag) { // Loop thru all con. elements forall (fig where fig.GROUP!=selectmode && isconelem(fig)) { // Abort on request if (kbhit()) { getchr(); if (verify(UPRFEXIT,1)) break; } // Select/deselect element to group ced_elemgrpchg(fig,selectmode); } } else { // Loop thru all non-con. elements forall (fig where fig.GROUP!=selectmode && !isconelem(fig)) { // Abort on request if (kbhit()) { getchr(); if (verify(UPRFEXIT,1)) break; } // Select/deselect element to group ced_elemgrpchg(fig,selectmode); } } } static int isconelem(index I_FIGURE fig) /* // Check if given figure list element is defined in the connection list // Return value : // nonzero if connection element, or zero else // Parameters : // index I_FIGURE fig : Figure list index */ { index I_CPART cpart /* Connection part index */; index I_CNET cnet /* Connection net index */; // Perform special check on named reference if (fig.TYP==I_FIGNREF) { return(icd_findconpart(fig.NAME,cpart)==0); } else if (fig.TYP==I_FIGPOLY && fig.TREE==(-1)) { // Scan the polygon data polytfound=0; if (icd_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,tpolyfunc,NULL,NULL,NULL,NULL)) error_scan(); return(polytfound); } // Perform tree number check return(fig.TREE!=(-1) && icd_gettreeidx(fig.TREE,cnet)==0 && cnet.PINN>1); } static int tpolyfunc(index I_POLY poly,int layer, int polyinws,int tree,index I_LEVEL level) /* // Store polygon tree check function // Return value : // zero if done or (-1) on file error // Parameters : // index I_POLY poly : Polygon // int layer : Polygon layer // int polyinws : Poly in workspace flag // int tree : Polygon tree number // index I_LEVEL level : Polygon level */ { index I_CNET cnet /* Connection list index */; if (level>=0 && icd_gettreeidx(level.LEVVAL,cnet)==0 && cnet.PINN>1) polytfound=1; // Return without errors return(0); } // Group macro functions static void selectmacros() /* // Select macros on current element */ { index I_MACRO macro /* Macro index */; index I_FIGURE fig /* Figure element index */; int figtyp1,figtyp2 /* Figure type */; STRINGS hl /* Popup header list */; STRINGS ml /* Macro name list */; int mn = 0 /* Macro count */; string macname /* Macro name */; string nref_dis = "," /* Named reference disable */; string uref_dis = "," /* Unnamed reference disable */; int i /* Loop control variable */; nref_dis= selectmode ? ((plcelems&(1<0;i--) if (ml[i-1]>macname) ml[i]=ml[i-1]; else break; ml[i]=macname; mn++; } // Select macro name with popup menu hl[1]=""; sprintf(hl[0],REPMACLIST,ddbclassname(cursearchclass)); bae_setintpar(16,3006); if ((selmacroname=popupmenu(1,selectmode ? UPRSELMACRO : UPRUSELMACRO, hl,2,ml,mn,UINPOPABORT,0,-1,-1,0,0,0,""))=="" || selmacroname==UINPOPABORT) error_abort(); // Select all figure list elements with selected macro name forall (fig where ((fig.TYP==figtyp1 && strmatch(fig.NREF.MACRO.NAME,selmacroname)) || (fig.TYP==figtyp2 && strmatch(fig.UREF.MACRO.NAME,selmacroname))) && fig.GROUP!=selectmode) ced_elemgrpchg(fig,selectmode); } // Group name functions static void selectnames() /* // Select name specified elements */ { index I_NREF nref /* Named reference index */; index I_FIGURE fig /* Figure element index */; STRINGS hl /* Popup header list */; STRINGS nl /* Name list */; int nn = 0 /* Name count */; STRINGS selentryl /* Selected entry string list */; int selentryn = 0 /* Selected entry count */; int i /* Loop control variable */; // Build the name list forall (nref) nl[nn++]=nref.NAME; // Select name with popup menu hl[0]=REPNAMELIST; hl[1]=""; // Show the multiple selection menu bae_setintpar(16,3001); popupmulmenu(1,0,selectmode ? UPRSELNAME : UPRDSELNAME,hl,2,nl,nn, 0,-1,nn+4,100,selentryl,selentryn,0); // Abort if no elements selected if (selentryn<=0) error_abort(); // Mark all selected figure list elements for (i=0;i=0 && oldlay!=layer) { // Change layer if (ced_elemlaychg(fig,layer)) error(ERRLCPOLY); // Increment the changes count changes++; } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Done bae_prtdialog(itoa(changes)+REPLCDONE); } static void grouppolytype() /* // Set type of group-selected polygons */ { perror("NOT YET IMPLEMENTED!"); } static void grouppathlayer() /* // Set layer of group-selected paths */ { index I_FIGURE fig /* Figure list element */; int layer = ced_getpickpreflay() /* Layer */; int changes = 0 /* Changes count */; // Select signal layer if (bae_promptdialog(UPRLAYER),ced_asklayer(layer)) error_abort(); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Loop thru all group selected paths not on layer bae_prtdialog(REPLCPATH); forall (fig where fig.GROUP && fig.TYP==I_FIGPATH && fig.LAYER!=layer) { // Change layer if (ced_elemlaychg(fig,layer)) error(ERRLCPATH); // Increment the changes count changes++; } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Done bae_prtdialog(itoa(changes)+REPLCDONE); } /*________________________________________________________________*/ // Group size change routines static void grouptextsize() /* // Set size of group-selected texts */ { index I_FIGURE fig /* Figure list element */; int changes = 0 /* Changes count */; double newsize /* New text size */; // Scan any old text size forall (fig where fig.GROUP && fig.TYP==I_FIGTEXT) { newsize=fig.SIZE; break; } // Select new text size if (askdist(newsize,bae_getcoorddisp()?UPRTSIZEI:UPRTSIZEM,0) || newsize==0.0) // Invalid input value error(ERRINPVAL); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Loop thru all group selected texts bae_prtdialog(REPSCTEXT); forall (fig where fig.GROUP && fig.TYP==I_FIGTEXT) { // Change size if (ced_elemsizechg(fig,newsize)) error(ERRSCTEXT); // Increment the changes count changes++; } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Done bae_prtdialog(itoa(changes)+REPSCDONE); } static void grouppathwidth() /* // Set width of group-selected paths */ { index I_FIGURE fig /* Figure list element */; int changes = 0 /* Changes count */; double newwidth /* New path width */; // Select new path width ced_getpathwidth(newwidth,0.0); if (askdist(newwidth,bae_getcoorddisp()?UPRPWIDTHI:UPRPWIDTHM,0) || newwidth==0.0) // Invalid input value error(ERRINPVAL); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Loop thru all group selected paths bae_prtdialog(REPSCPATH); forall (fig where fig.GROUP && fig.TYP==I_FIGPATH) { // Change width if (ced_elemsizechg(fig,newwidth)) error(ERRSCPATH); // Increment the changes count changes++; } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Done bae_prtdialog(itoa(changes)+REPSCDONE); } /*________________________________________________________________*/ // Part text routines void resetparttexts() /* // Reset text positions of mouse-selectable parts */ { index I_FIGURE fig /* Figure list index */; index I_FIGURE dfig /* Delete figure list element */; index I_FIGURE nfig /* New figure list index */; string name /* Part name buffer */; string macname /* Part macro name buffer */; double x,y /* Part position buffer */; double ang /* Part angle buffer */; double scale /* Part scale buffer */; STRINGS rl /* Rule list */; int mirr /* Part mirror buffer */; // Abort if invalid plan class if (ddbclass!=DDBCLILAY && ddbclass!=DDBCLICELL) error_class(); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Loop for all group parts forall (fig where fig.TYP==I_FIGNREF && fig.GROUP) { // Buffer the part data name=fig.NREF.NAME; macname=fig.NREF.MACRO.NAME; x=fig.NREF.X; y=fig.NREF.Y; ang=fig.NREF.ANGLE; scale=fig.NREF.SCALE; mirr=fig.NREF.MIRROR; // Delete the old part dfig=fig; if (ced_delelem(dfig)) error(ERRDELETE); // Place part at same position if (ced_storepart(name,macname,x,y,ang,scale,mirr)) error(ERRCREATE); // Check if part should be fixed if (fig.FIXED && icd_lastfigelem(nfig)==0) ced_elemfixchg(nfig,fig.FIXED); // Transfer rules if (/* fig.RULEOBJID>=0 && */ icd_lastfigelem(nfig)==0) { // Get rules if (rsi_getfigrules(fig,rl)>0) // Attach rules if (icd_rulefigatt(nfig,rl)) rsi_error(0); } } } /*________________________________________________________________*/ // Group copy routines static void groupcopytrace() /* // Group copy traces */ { index I_FIGURE fig /* Figure list index */; index I_FIGURE nfig /* New figure list index */; int grpcnt /* Number of group copies */; double x1,y1 /* Group origin coordinates */; double x2,y2 /* Group first copy coordinates */; double xstep,ystep /* Group offset vector */; double vx,vy /* Via coordinates */; double vscale /* Via scale */; int i,j /* Loop control variables */; // Abort if invalid plan class if (ddbclass!=DDBCLILAY && ddbclass!=DDBCLICELL) error_class(); // Ask for copy count and test it if (varget(GV_GRPCNT,grpcnt)) grpcnt=1; if (askint(grpcnt,UPRGRPCNT,5) || grpcnt<=0) error(ERRINPVAL); // Store settings for next call varset(GV_GRPCNT,grpcnt); // Select group origin coordinates bae_promptdialog(UPRSELORG); if (bae_inpoint(bae_planwsnx(),bae_planwsny(),x1,y1,0)) error_abort(); // Select first copy coordinates if (bae_promptdialog(UPRSELVEC),bae_inpoint(x1,y1,x2,y2,2)) error_abort(); // Calculate grid steps xstep=x2-x1; ystep=y2-y1; if (xstep==0.0 && ystep==0.0) error(ERRCOORD); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Loop for all figure list elements forall (fig where fig.GROUP) { switch (fig.TYP) { // Path case I_FIGPATH : // Scan the path data if (icd_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,NULL,pathfunc,NULL,NULL,NULL)) error_scan(); // Check if path points found if (ppcnt) { for (i=1;i<=grpcnt;i++) { // Build new path point list bae_clearpoints(); for (j=0;jgux) gux=fig.RUX; if (fig.RLYguy) guy=fig.RUY; } switch (fig.TYP) { // Polygon case I_FIGPOLY : // Scan the polygon data if (icd_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,polyfunc,NULL,NULL,NULL,NULL)) error_scan(); // Check if polygon points found if (ppcnt==0) continue; // Get polygon data layer=fig.LAYER; mirr=fig.MIRROR; // Loop for all matrix elements for (i=0;i0.0) guy=gly+(grpycnt-1)*ystep+gh; else gly=guy+(grpycnt-1)*ystep-gh; if (xstep>0.0) gux=glx+(grpxcnt-1)*xstep+gw; else glx=gux+(grpxcnt-1)*xstep-gw; // Ensure group destination range display winadjust(glx,gly,gux,guy); } // Zoom all zoomall(); // Return without errors bae_prtdialog(REPDONE); } /*________________________________________________________________*/ // Group load routines static void grouploadhierless() /* // Group Load without Hierarchy */ { index I_POOL pool /* Pool element index */; string msg /* Error message string */; string grpfname /* Group file name */; string grpename /* Group element name */; int grpeclass = DDBCLUNDEF /* Group element class */; double x,y /* Group placement position */; // Select the layout plan DDB class switch (bae_askmenu(4,UPRCLILAY,UPRCLICELL,UPRCLIPIN,UPRABORT)) { /* Layout */ case 0 : grpeclass=DDBCLILAY; break; /* Cell */ case 1 : grpeclass=DDBCLICELL; break; /* Pin */ case 2 : grpeclass=DDBCLIPIN; break; } // Select DDB file and element name if (grpeclass==DDBCLUNDEF || bae_askddbfname(grpfname,1,UPRFILE) || bae_askddbename(grpename,grpfname,grpeclass,"")) // Abort error_abort(); // Select group origin coordinates bae_promptdialog(UPRSELORG); if (bae_inpoint(bae_planwsnx(),bae_planwsny(),x,y,0)) error_abort(); // Load the symbol macro if (icd_macload(pool,grpfname,grpename,grpeclass)<0) { // Load error sprintf(msg,ERRNOFGRP, ddbclassname(grpeclass),grpename,grpfname); error(msg); } // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Scan object data if (icd_scanpool(pool,-x,-y,0.0,1,1, NULL,lpolyfunc,lpathfunc,ltextfunc,NULL,NULL)!=0) { // Release the macro element icd_macrelease(pool); error_scan(); } // Release the macro element icd_macrelease(pool); } static int lpolyfunc(index I_POLY poly,int layer, int polyinws,int tree,index I_LEVEL level) /* // Store an already transformed polygon data block // Return value : // zero if done or (-1) on file error // Parameters : // index I_POLY poly : Polygon // int layer : Polygon layer // int polyinws : Poly in workspace flag // int tree : Polygon tree number // index I_LEVEL level : Polygon level */ { index I_POINT point /* Polygon point */; index I_FIGURE fig /* Figure list index */; // Store the polygon points bae_clearpoints(); forall (point of poly) bae_storepoint(point.X,point.Y,point.TYP); // Store the polygon ced_storepoly(layer,poly.TYP,poly.MVIS); // Select new polygon to group if (icd_lastfigelem(fig)==0) ced_elemgrpchg(fig,1); // Return without errors return(0); } static int lpathfunc(index I_LINE path, int layer,int pathinws,index I_LEVEL level) /* // Store an already transformed path data block // Return value : // zero if done or (-1) on file error // Parameters : // index I_LINE path : Path // int layer : Path layer // int pathinws : Path in workspace flag // index I_LEVEL level : Path level */ { index I_POINT point /* Path point */; index I_FIGURE fig /* Figure list index */; // Store the trace bae_clearpoints(); forall (point of path) bae_storepoint(point.X,point.Y,point.TYP); ced_storepath(layer,path.WIDTH); // Select new trace to group if (icd_lastfigelem(fig)==0) ced_elemgrpchg(fig,1); // Return without errors return(0); } static int ltextfunc(index I_TEXT textp,double tx,double ty,double tangle, int mirrflag,int layer,double tsize,string tstr,int textinws) /* // Store a text // Return value : // zero if done or (-1) on error // Parameters : // index I_TEXT textp : Text index // double tx : Text X coordinate // double ty : Text Y coordinate // double tangle : Text rotation angle // int mirrflag : Text mirror flag // int layer : Text layer code // double tsize : Text size // string tstr : Text string // int textinws : Text in workspace flag */ { index I_FIGURE fig /* Figure list index */; // Store the text ced_storetext(tstr,tx,ty,tangle,tsize,layer,mirrflag,0); // Select new text to group if (icd_lastfigelem(fig)==0) ced_elemgrpchg(fig,1); // Return without errors return(0); } // Scan functions static int viamac(index I_MACRO macro,index I_POOL pool, int macinws,string refname,index I_LEVEL level) /* // Via macro scan function // Return value : // zero if scan abort or 1 if scan continue // Parameters : // index I_MACRO macro : Macro index // index I_POOL pool : Macro pool element index // int macinws : Macro in workspace flag // string refname : Macro reference name // index I_LEVEL level : Macro level */ { // Abort scan if not padstack if (macro.CLASS!=DDBCLIPIN) return(0); // Abort scan if named reference (pin) if (refname!="") return(0); // Store via macro name vianame=macro.NAME; // Abort scan return(0); } static int polyfunc(index I_POLY poly,int layer, int polyinws,int tree,index I_LEVEL level) /* // Polygon scan function; generates polygon point list // Return value : // zero if done or (-1) on error // Parameters : // index I_POLY poly : Polygon data // int layer : Polygon layer // int polyinws : Polygon in workspace flag // int tree : Polygon level // index I_LEVEL level : Polygon level */ { index I_POINT point /* Polygon point index */; // Reset point count ppcnt=0; // Check if board outline if (poly.TYP==I_POLYBORDER) return(0); // Scan points forall (point of poly) { // Add point to the path point list pplist[ppcnt].x=point.X; pplist[ppcnt].y=point.Y; pplist[ppcnt].typ=point.TYP; // Increment point count ppcnt++; } // Store polygon data polytyp=poly.TYP; // Return without errors return(0); } static int pathfunc( index I_LINE path,int layer,int pathinws,index I_LEVEL level) /* // Path scan function. Generates path point list // Return value : // zero if done or (-1) on error // Parameters : // index I_LINE path : Path data // int layer : Path layer // int pathinws : Path in workspace flag // index I_LEVEL level : Path level */ { index I_POINT point /* Polygon point index */; // Reset point count ppcnt=0; // Scan points forall (point of path) { // Add point to the path point list pplist[ppcnt].x=point.X; pplist[ppcnt].y=point.Y; pplist[ppcnt].typ=point.TYP; // Increment point count ppcnt++; } // Return without errors return(0); } static void groupscan() /* // Scan group element types */ { index I_FIGURE fig /* Figure list index */; // Loop thru the figure list forall (fig where fig.GROUP && fig.TYP==I_FIGNREF) { grpelems|=(1<wux || uy>wuy) { // Get bounding box of current window and given range lx= lxwux ? ux : wux; uy= uy>wuy ? uy : wuy; // Call the Zoom Window command bae_clriactqueue(); bae_storemouseiact(1,lx,ly,0,LMB); bae_storemouseiact(1,ux,uy,0,LMB); call(MNU_BAEZOOMWND); } } // User Language program end