/* GED_MSG (GED) -- GED Message System Action */ /* GED_MSG (GED) -- GED Messagesystem-Aktion */ /* -- EXECUTED AFTER RECEIVING A MESSAGE -- */ /* // Copyright (c) 1998-2013 Bartels System GmbH, Muenchen // Author: Roman Ludwig // Changes History: // rl (131029) RELEASED FOR BAE V8.0. // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (100831) ENHANCEMENT: // Added schematic position part group placement option. // rl (091021) 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 (060515) ENHANCEMENT: // Added part macro load options. // rl (050906) RELEASED FOR BAE V6.6. // rl (040826) RELEASED FOR BAE V6.4. // rl (040216) ENHANCEMENT: // Added part macro load function. // rl (030904) RELEASED FOR BAE V6.2. // rl (021209) RELEASED FOR BAE V6.0. // rl (021011) ENHANCEMENT: // Changed highlight pin function to toggle highlight. // rl (020618) RELEASED FOR BAE V5.4. // rl (010625) RELEASED FOR BAE V5.0. // rl (010430) ENHANCEMENT: // Added group symbols to layout part set include function. // rl (000508) RELEASED FOR BAE V4.6. // rl (000418) ENHANCEMENT: // Introduced global variable and ULC script functions. // rl (990625) RELEASED FOR BAE V4.4. // rl (980910) RELEASED FOR BAE V4.2. // mb (980712) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (980528) ORIGINAL CODING. // // DESCRIPTION // // The ged_msg User Language program provides functions to be // performed when receiving messages from other modules. // The actions depend on the input string received. */ // Includes #include "pop.ulh" // User Language popup utilities #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // INI file parameter name definitions #define PAR_LOADMACRO "LOADMACRO_GED"// Layout part macro load mode // Messages string UPRSELPNAME = M("Bauteilname","Part Name"); string REPPARTPLC = M("Bauteil '%s' ist bereits platziert!", "Part '%s' is already placed!"); string REPPLC = M("platziert","placed"); string REPUPLC = M("unplatziert","unplaced"); string REPSPARTPLC = M("Bauteilplatzierung","Part placement"); string REPPARTSEL = M("%d Bauteile zur Gruppe hinzuselektiert!", "%d parts added to group!"); string ERRILLMSG = M("Unbekannter Messagetyp empfangen!", "Received unknown message type!"); // Global User Language program variables #define UL_CONUTIL "conutil" // ULP: Connection utilities #define GV_HLREQUEST "hlrequest" // Highlight request variable // Global variables #define SMALLVAL 0.000000001 // Small compare value string msgbuf /* Message string buffer */; double DPI = cvtangle(360.0,1,2) /* Double pi value */; double PI = cvtangle(180.0,1,2) /* Pi value */; double PI2 = cvtangle(90.0,1,2) /* Pi half value */; // Part placement variables struct pindes { // Part descriptor string name /* Pin name */; double sx, sy /* Pin schematic placement coord. */; double lx, ly /* Pin layout placement coordinates */; }; struct partdes { // Part descriptor string name /* Part name */; index L_CPART cpart /* Connection part index */; struct pindes pinl[] /* Part pin list */; int pinn /* Part pin count */; double x, y /* Part placement coordinates */; double slx, sly /* Part symbol lower boundary */; double sux, suy /* Part symbol upper boundary */; double llx, lly /* Part placment lower boundary */; double lux, luy /* Part placment upper boundary */; double ang /* Part angle */; int stat /* Part process status */; } partl[] /* Part list */; int partn = 0 /* Part count */; int curpidx /* Current part index */; double mlx, mly /* Part macro lower boundary */; double mux, muy /* Part macro upper boundary */; int polyfound /* Part polygon found flag */; int outllayer = (-2) /* Part outline layer */; // Main program void main() { // Get the message string if ((msgbuf=bae_getmsg())=="") { // No message found bae_prtdialog(""); exit(0); } // Evaluate the message ID switch (atoi(getmsgitem())) { // Place part case MSGID_PLCPART : plcpart(); break; // Place hierarchical part case MSGID_PLCHPART : plchpart(); break; // Place searched hierarchical part case MSGID_PLCHSPART : plchspart(); break; // Select part group case MSGID_SELPGRP : selpgroup(); break; // Place part group case MSGID_PLCPGRP : plcpgroup(); break; // Select hierarchical part group case MSGID_SELHPGRP : selhpgroup(); break; // Select part to part set case MSGID_SELPSET : selpset(); break; // Optionally deselect all parts from part set case MSGID_DSELPOPT : optdselpset(); break; // Select hierarchical part to part set case MSGID_SELHPSET: selhpset(); break; // Set integer variable case MSGID_SETIVAR : setivar(); break; // Set double variable case MSGID_SETDVAR : setdvar(); break; // Set string variable case MSGID_SETSVAR : setsvar(); break; // Run ULC script case MSGID_RUNULC : runulc(); break; // Load part macro case MSGID_LLPRTMAC : loadpartmacro(); break; // Highlight/zoom net case MSGID_NETZOOMHL : highlightzoomnet(); break; // Center mouse, activate window case MSGID_MOUSEGRAB : mousegrab(1); break; // Ignore schematic editor specific messages case MSGID_FINDSPRT : case MSGID_FINDSHPRT : break; default : error(ERRILLMSG); } } static void plcpart() /* // Place the requested part */ { index L_FIGURE fig /* Figure list index */; string pname /* Part name */; // Get the part name pname=getmsgitem(); // Search for the selected part if (lay_nrefsearch(pname,fig)) { // Set mouse cursor to window center mousegrab(1); // Part not found; place it bae_clriactqueue(); bae_storetextiact(1,pname); bae_callmenu(MNU_GEDADDPART); bae_clriactqueue(); } else { // Part found; perform zoom window to the part zoomtofig(fig); message(REPPARTPLC,pname); } } static void plchpart() /* // Place the requested hierarchical part */ { index L_CPART cpart /* Connection part index */; index L_ATTRIBUTE attr /* Attribute index */; index L_FIGURE fig /* Figure list index */; string rplanname /* Requested part plan name */; string rbrefname /* Requested part block ref. name */; string rorgname /* Requested part original name */; string planname /* Part plan name */; string brefname /* Part block reference name */; string orgname /* Part original name */; string pname = "" /* Part name */; // Get the requested part data rorgname="*"+getmsgitem()+"*"; rbrefname="*"+getmsgitem()+"*"; rplanname="*"+getmsgitem()+"*"; forall (cpart) { planname=brefname,orgname=""; forall (attr of cpart) switch (attr.NAME) { case "$orgname" : orgname=attr.VALUE; break; case "$blkrname" : brefname=attr.VALUE; break; case "$pagename" : planname=attr.VALUE; break; } if (strmatch(orgname,rorgname) && strmatch(brefname,rbrefname) && strmatch(planname,rplanname)) { pname=cpart.NAME; break; } } if (pname=="") return; // Search for the selected part if (lay_nrefsearch(pname,fig)) { // Set mouse cursor to window center mousegrab(1); // Part not found; place it bae_clriactqueue(); bae_storetextiact(1,pname); bae_callmenu(MNU_GEDADDPART); bae_clriactqueue(); } else { // Part found; perform zoom window to the part zoomtofig(fig); message(REPPARTPLC,pname+" / "+orgname); } } static void plchspart() /* // Search & place the requested hierachical block part */ { index L_FIGURE fig /* Figure list index */; index L_CPART cpart /* Connection part index */; index L_ATTRIBUTE attr /* Attribute index */; string sname /* Symbol name */; string pname /* Part name */; int pnamen = 0 /* Part name count */; string val /* Attribute value */; // Get the symbol name sname=pname=getmsgitem(); // Build part name list bae_nameclr(); forall (cpart) forall (attr of cpart where attr.NAME=="$orgname") { val=attr.VALUE; if (val==sname || strmatch(val,sname+",*") || strmatch(val,"*,"+sname+",*") || strmatch(val,"*,"+sname)) { pname=cpart.NAME; bae_nameadd(pname,"","", (cpart.USED&1) ? REPPLC : REPUPLC,2); pnamen++; break; } } if (pnamen>1) { bae_setintpar(16,3121); if (bae_askname(pname,UPRSELPNAME,MAXKEYLEN)) // Aborted error_abort(); } // Search for the selected part if (lay_nrefsearch(pname,fig)) { // Set mouse cursor to window center mousegrab(1); // Part not found; place it bae_clriactqueue(); bae_storetextiact(1,pname); bae_callmenu(MNU_GEDADDPART); bae_clriactqueue(); } else { // Part found; perform zoom window to the part zoomtofig(fig); message(REPPARTPLC,pname); } } static void selpgroup() /* // Group select the requested parts */ { index L_FIGURE fig /* Figure list index */; string pname /* Part name */; string msg /* Message buffer */; int cnt = 0 /* Selection count */; // Get the part name while ((pname=getmsgitem())!="") // Search for the selected part if (!lay_nrefsearch(pname,fig) && !fig.GROUP) { // Set the group select status ged_elemgrpchg(fig,1); cnt++; } sprintf(msg,REPPARTSEL,cnt); bae_prtdialog(msg); } static void plcpgroup() /* // Group select the requested parts */ { index L_FIGURE fig /* Figure list index */; index L_CPART cpart /* Connection part index */; index L_POOL pool /* Pool index */; index L_MACRO macro /* Macro index */; string pname = "" /* Current part name */; string name /* Scan name */; string cbuf /* Coordinate buffer */; double ang /* Part test angle */; int bestang /* Part best angle index */; double bestdiff /* Part best angle difference */; double angdiff /* Part current angle difference */; double diff /* Part angle difference */; double sx1, sy1 /* First schematic pin coordinates */; double lx1, ly1 /* First layout pin coordinates */; int pinfound /* Pin found flag */; double pindist /* Current pin distance */; double px, py /* Current pin coordinates */; double dx, dy /* Current pin distance dir. */; double minb /* Min. boundary coordinates */; double mindist /* Min. pin distance */; int minori /* Min. pin distance orientation */; double partx, party /* Current part coordinates */; double minpartx, minparty /* Min. distance part coordinates */; double blx, bly /* Part box lower boundary */; double bux, buy /* Part box upper boundary */; int part1idx, part2idx /* Placement combination parts */; int pin1idx, pin2idx /* Placement combination pins */; double m /* Modulo value */; double partexp /* Part expansion value */; double xgrid, ygrid /* Current part coordinates */; int gridlock /* Grid lock flag */; int anglock /* Angle lock flag */; int i, j, k, l /* Loop control variable */; // Get the next name while ((name=getmsgitem())!="") { if (name=="?") { if (pname!="" && lay_nrefsearch(pname,fig)!=0 && lay_findconpart(pname,cpart)==0) { partl[partn].name=pname; partl[partn].cpart=cpart; partn++; } pname=getmsgitem(); cbuf=getmsgitem(); partl[partn].slx=atof(cbuf); cbuf=getmsgitem(); partl[partn].sly=atof(cbuf); cbuf=getmsgitem(); partl[partn].sux=atof(cbuf); cbuf=getmsgitem(); partl[partn].suy=atof(cbuf); partl[partn].pinn=0; partl[partn].stat=0; partl[partn].llx=partl[partn].lly=0.0; partl[partn].lux=partl[partn].luy=0.0; } else { partl[partn].pinl[partl[partn].pinn].name=name; cbuf=getmsgitem(); partl[partn].pinl[partl[partn].pinn].sx=atof(cbuf); cbuf=getmsgitem(); partl[partn].pinl[partl[partn].pinn].sy=atof(cbuf); partl[partn].pinl[partl[partn].pinn].lx= partl[partn].pinl[partl[partn].pinn].ly=0.0; partl[partn].pinn++; } } if (pname!="" && lay_nrefsearch(pname,fig)!=0 && lay_findconpart(pname,cpart)==0) { partl[partn].name=pname; partl[partn].cpart=cpart; partn++; } if (partn==0) return; // Get the input grid bae_getinpgrid(xgrid,ygrid); gridlock=bae_getgridlock(); // Get the part expansion ged_getdblpar(13,partexp); // Get the part outline layer ged_getintpar(46,outllayer); // Reset group call(MNU_GEDGRPRESE); // Search best match part rotation angles for (i=0;iPI) diff-=DPI; while (diff<=-PI) diff+=DPI; angdiff+=fabs(diff); } // Check if new best match angle if (bestang<0 || angdiffSMALLVAL || m<(-SMALLVAL)) partl[curpidx].llx+= m>0.0 ? (xgrid-m) : -(xgrid+m) ; if ((m= fmod(partl[curpidx].lux,xgrid))>SMALLVAL || m<(-SMALLVAL)) partl[curpidx].lux+= m>0.0 ? (xgrid-m) : -(xgrid+m) ; } if (ygrid!=0.0) { if ((m= fmod(partl[curpidx].lly,ygrid))>SMALLVAL || m<(-SMALLVAL)) partl[curpidx].lly+= m>0.0 ? (ygrid-m) : -(ygrid+m) ; if ((m= fmod(partl[curpidx].luy,ygrid))>SMALLVAL || m<(-SMALLVAL)) partl[curpidx].luy+= m>0.0 ? (ygrid-m) : -(ygrid+m) ; } } } // Release the macro element lay_macrelease(pool); } bae_setstrpar(7,REPSPARTPLC); bae_callmenu(MNU_BAESAVESTATE); curpidx=0; minb=partl[0].pinn; for (i=1;iminb) { minb=partl[i].pinn; curpidx=i; } // Place first part partl[curpidx].x=0.0; partl[curpidx].y=0.0; partl[curpidx].stat=2; do { // Search closest unplaced pin pinfound=0; for (i=0;idx ? 0 : 1 ; } else if (px>partl[k].sux) { dx=px-partl[k].sux; minori= dy>dx ? 0 : 1 ; } else { minori=0; } } else if (py>partl[k].suy) { dy=py-partl[k].suy; if (pxdx ? 2 : 3 ; } else if (px>partl[k].sux) { dx=px-partl[k].sux; minori= dy>dx ? 2 : 3 ; } else { minori=2; } } else { minori= pxminb) continue; pindist=minb-partl[i].llx; if (pinfound && pindist>=mindist) continue; partx=partl[i].llx-partl[part1idx].lux; party=py-partl[part1idx].pinl[pin1idx].ly; lx1=px-(partx+partl[part1idx].pinl[pin1idx].lx); if (sx1!=0.0) party-=lx1*sy1/sx1; // Snap to grid if (gridlock && ygrid!=0.0) party=ygrid*floor(party/ygrid+0.5); break; case 2 : if (partl[i].luy=mindist) continue; party=partl[i].luy-partl[part1idx].lly; partx=px-partl[part1idx].pinl[pin1idx].lx; ly1=py-(party+partl[part1idx].pinl[pin1idx].ly); if (sy1!=0.0) partx-=ly1*sx1/sy1; // Snap to grid if (gridlock && xgrid!=0.0) partx=xgrid*floor(partx/xgrid+0.5); break; case 3 : if (partl[i].lux=mindist) continue; partx=partl[i].lux-partl[part1idx].llx; party=py-partl[part1idx].pinl[pin1idx].ly; lx1=px-(partx+partl[part1idx].pinl[pin1idx].lx); if (sx1!=0.0) party-=lx1*sy1/sx1; // Snap to grid if (gridlock && ygrid!=0.0) party=ygrid*floor(party/ygrid+0.5); break; case 0 : default : if (partl[i].lly>minb) continue; pindist=minb-partl[i].lly; if (pinfound && pindist>=mindist) continue; party=partl[i].lly-partl[part1idx].luy; partx=px-partl[part1idx].pinl[pin1idx].lx; ly1=py-(party+partl[part1idx].pinl[pin1idx].ly); if (sy1!=0.0) partx-=ly1*sx1/sy1; // Snap to grid if (gridlock && xgrid!=0.0) partx=xgrid*floor(partx/xgrid+0.5); } // Check if collision with other parts blx=partx+partl[part1idx].llx; bly=party+partl[part1idx].lly; bux=partx+partl[part1idx].lux; buy=party+partl[part1idx].luy; for (j=0;jpartl[j].llx && blypartl[j].lly) break; } // Check if new best position found if (j>=partn && (!pinfound || pindistpartl[i].llx) blx=partl[i].llx; if (buxpartl[i].lly) bly=partl[i].lly; if (buylx) mlx=lx; if (mly>ly) mly=ly; if (mux>DOCLAYSHIFT))) ? 1 : 0 ); } static void selhpgroup() /* // Group select the requested hierarchical part */ { index L_CPART cpart /* Connection part index */; index L_ATTRIBUTE attr /* Attribute index */; index L_FIGURE fig /* Figure list index */; string rplanname /* Requested part plan name */; string rbrefname /* Requested part block ref. name */; string rorgname /* Requested part original name */; string planname /* Part plan name */; string brefname /* Part block reference name */; string orgname /* Part original name */; string pname = "" /* Part name */; // Get the requested part data rorgname="*"+getmsgitem()+"*"; rbrefname="*"+getmsgitem()+"*"; rplanname="*"+getmsgitem()+"*"; forall (cpart) { planname=brefname,orgname=""; forall (attr of cpart) switch (attr.NAME) { case "$orgname" : orgname=attr.VALUE; break; case "$blkrname" : brefname=attr.VALUE; break; case "$pagename" : planname=attr.VALUE; break; } if (strmatch(orgname,rorgname) && strmatch(brefname,rbrefname) && strmatch(planname,rplanname)) { pname=cpart.NAME; break; } } if (pname=="") return; // Search for the selected part if (!lay_nrefsearch(pname,fig)) // Set the group select status ged_elemgrpchg(fig,1); } static void selpset() /* // Select the requested parts to part set */ { index L_CPART cpart /* Figure list index */; string pname /* Part name */; int upartfound = 0 /* Unselected part found */; // Check if part set full forall (cpart) if ((cpart.USED&CPART_SEL)==0) { upartfound=1; break; } // Check if selectable part found if (!upartfound) { // Empty the message queue while ((pname=getmsgitem())!="") ; return; } // Switch to part set popup bae_clriactqueue(); bae_storemenuiact(1,1,LMB); bae_storemenuiact(1,0,LMB); // Get the part name while ((pname=getmsgitem())!="") bae_storetextiact(1,pname); bae_storetextiact(1,UINPOPABORT); bae_storemenuiact(1,9,LMB); bae_callmenu(311); } static void optdselpset() /* // Optionally deselect all parts if all are selected */ { index L_CPART cpart /* Figure list index */; int upartfound = 0 /* Unselected part found */; // Check if part set full forall (cpart) if ((cpart.USED&CPART_SEL)==0) { upartfound=1; break; } // Check if selectable part found if (upartfound) return; // Switch to part set popup bae_clriactqueue(); bae_storemenuiact(1,1,LMB); bae_storemenuiact(1,1,LMB); // Get the part name forall (cpart) bae_storetextiact(1,cpart.NAME); bae_storetextiact(1,UINPOPABORT); bae_storemenuiact(1,9,LMB); bae_callmenu(311); } static void selhpset() /* // Select the requested hierarchical parts to part set */ { index L_CPART cpart /* Figure list index */; index L_ATTRIBUTE attr /* Attribute index */; string rplanname /* Requested part plan name */; string rbrefname /* Requested part block ref. name */; string rorgname /* Requested part original name */; string planname /* Part plan name */; string brefname /* Part block reference name */; string orgname /* Part original name */; string pname = "" /* Part name */; int upartfound = 0 /* Unselected part found */; // Check if part set full forall (cpart) if ((cpart.USED&CPART_SEL)==0) { upartfound=1; break; } // Check if selectable part found if (!upartfound) { // Empty the message queue while ((pname=getmsgitem())!="") ; return; } // Get the requested part data rorgname="*"+getmsgitem()+"*"; rbrefname="*"+getmsgitem()+"*"; rplanname="*"+getmsgitem()+"*"; forall (cpart) { planname=brefname,orgname=""; forall (attr of cpart) switch (attr.NAME) { case "$orgname" : orgname=attr.VALUE; break; case "$blkrname" : brefname=attr.VALUE; break; case "$pagename" : planname=attr.VALUE; break; } if (strmatch(orgname,rorgname) && strmatch(brefname,rbrefname) && strmatch(planname,rplanname)) { pname=cpart.NAME; break; } } if (pname=="") return; // Switch to part set popup bae_clriactqueue(); bae_storemenuiact(1,1,LMB); bae_storemenuiact(1,0,LMB); bae_storetextiact(1,pname); bae_storetextiact(1,UINPOPABORT); bae_storemenuiact(1,9,LMB); bae_callmenu(311); } static void setivar() /* // Set global integer variable */ { string varname /* Variable name */; string varvalue /* Variable value string */; // Get the variable name and value if ((varname=getmsgitem())=="" || (varvalue=getmsgitem())=="") return; // Set the variable varset(varname,atoi(varvalue)); } static void setdvar() /* // Set global double variable */ { string varname /* Variable name */; string varvalue /* Variable value string */; // Get the variable name and value if ((varname=getmsgitem())=="" || (varvalue=getmsgitem())=="") return; // Set the variable varset(varname,atof(varvalue)); } static void setsvar() /* // Set global string variable */ { string varname /* Variable name */; string varvalue /* Variable value string */; // Get the variable name and value if ((varname=getmsgitem())=="" || (varvalue=getmsgitem())=="") return; // Set the variable varset(varname,varvalue); } static void runulc() /* // Run ULC script */ { string progname /* Program name */; // Get the program name if ((progname=getmsgitem())=="") return; // Run the program ulsystem(progname,0); } static void loadpartmacro() /* // Load the requested part macro */ { string fname /* Library file name */; string ename /* Part macro name */; int LOADMACRO = bae_iniintval(PAR_LOADMACRO,1) /* Layout part macro load mode */; // Get the file and element name fname=getmsgqitem(); ename=getmsgqitem(); // Check the macro load mode switch (LOADMACRO) { // Don't load macro case 0 : return; // Always load macro case 1 : break; // Load if no layout in memory case 2 : default : if (bae_planddbclass()==DDBCLLAY) return; } // Save current element with verification on request verifysave(); // Load the part macro loadddbelem(fname,ename,DDBCLLPRT); } static void highlightzoomnet() /* // Highlight and zoom to the requested net */ { string netname /* Net name */; // Get the net name netname=getmsgitem(); varset(GV_HLREQUEST,netname); // Zoom to net bae_clriactqueue(); bae_storemenuiact(1,0,LMB); bae_storemenuiact(1,3,LMB); bae_storetextiact(1,netname); bae_storetextiact(1,"h"); ulsystem(UL_CONUTIL,1); } static void zoomtofig(index L_FIGURE fig) /* // Zoom to a given figure list element // Parameters: // index L_FIGURE fig : Figure list index */ { #define RANGEEXP 0.5 // Range expansion factor double rx,ry /* Range dimensions */; int rangedis /* Range check disabled flag */; // Disable range check bae_getintpar(0,rangedis); bae_setintpar(0,1); // Get the range rx=(fig.RUX-fig.RLX)*RANGEEXP; ry=(fig.RUY-fig.RLY)*RANGEEXP; // Zoom to window bae_clriactqueue(); bae_storemouseiact(1,fig.RLX-rx,fig.RLY-ry,0,LMB); bae_storemouseiact(1,fig.RUX+rx,fig.RUY+ry,0,LMB); call(MNU_BAEZOOMWND); // Restore old range check state bae_setintpar(0,rangedis); } static string getmsgitem() /* // Get the next message item from the message buffer */ { string item /* Message item string */; int spos /* Item seperator position */; // Get the item seperator position spos=strscannext(msgbuf," ",0,1); // Get the message item item=strextract(msgbuf,0,spos-2); // Truncate buffer msgbuf=strextract(msgbuf,spos,strlen(msgbuf)); // Return the message item return(item); } static string getmsgqitem() /* // Get the next message item from the quotation mark separated message buffer */ { string item /* Message item string */; int spos /* Item seperator position */; // Get the item seperator position spos=strscannext(msgbuf,"\"",0,1); // Get the message item item=strextract(msgbuf,0,spos-2); // Truncate buffer msgbuf=strextract(msgbuf,spos,strlen(msgbuf)); // Return the message item return(item); } // User Language program end