/* GEDGROUP (GED) -- GED Group Functions */ /* GEDGROUP (GED) -- GED-Gruppenfunktionen */ /* -- INTENDED FOR KEY-CALL USE -- */ /* // Copyright (c) 1993-2012 Oliver Bartels F+E, Muenchen // Author: Manfred Baumeister // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (110531) ENHANCEMENT: // Added text selection function. // rl (110520) ENHANCEMENT: // Added coordinate list clipboard copy function. // rl (110426) ENHANCEMENT: // Added negated attribute/macro selection options. // rl (110311) ENHANCEMENT: // Added group element report function. // rl (101019) RELEASED FOR BAE V7.6. // rl (100730) ENHANCEMENT: // Added hierachical block support to matrix copy function. // jw/rl (100421) ENHANCEMENT: // Improved error handling of trace width change function. // rl (091027) RELEASED FOR BAE V7.4. // rl (090327) ENHANCEMENT: // Added part trace route selection option. // rl (081014) RELEASED FOR BAE V7.2. // rl (071029) RELEASED FOR BAE V7.0. // rl (060926) RELEASED FOR BAE V6.8. // rl (060814) ENHANCEMENT: // Added graphical matrix size definition option. // Added group matrix autoselection option. // rl (060614) ENHANCEMENT: // Added single pin tree select functions. // rl (060419) ENHANCEMENT: // Added area resize function. // Added pen width set function. // Combined layer set functions. // rl (060207) ENHANCEMENT: // Added tree name pattern support in select functions. // rl (060109) ENHANCEMENT: // Added incremental trace width change function. // 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 (040929) ENHANCEMENT: // Added configurable via placement in cross hierarchy load. // rl (040811) RELEASED FOR BAE V6.4. // rl (040301) ENHANCEMENT: // Added trace width change with DRC function. // rl (040216) ENHANCEMENT: // Added name/attribute move transfer function. // rl (031204) ENHANCEMENT: // Added macro name list sorting. // rl (030904) RELEASED FOR BAE V6.2. // rl (030408) ENHANCEMENT: // Added rule preservation in hierarchy less load. // rl (021211) RELEASED FOR BAE V6.0. // rl (021031) BUGFIX: // Fixed disfunctional signal layer documentary area/line // layer change. // rl (020618) RELEASED FOR BAE V5.4. // rl (020320) ENHANCEMENT: // Added group name support functions. // rl (020314) ENHANCEMENT: // Added group selection by part name(s) function. // Added group selection by area type function. // Added group area type change function. // rl (020118) BUGFIX: // Fixed erroneous menu definition on pad/padstack level in // side menu configuration. // rl (010711) RELEASED FOR BAE V5.0. // rl (010628) ENHANCEMENT: // Added group selection by part attribute value. // rl (010528) ENHANCEMENT: // Added polygon to netlist connection check to make // con-element selection uniform for traces and polygons. // rl (010320) ENHANCEMENT: // Added optional parameter settings from bae.ini file. // rl (001208) ENHANCEMENT: // Added element fix state restore for copy/change functions. // rl (000524) RELEASED FOR BAE V4.6. // rl (990924) RELEASED FOR BAE V4.4. // rl (990924) ENHANCEMENT: // Added load group command with different hierarchy level // support. // rl (990716) ENHANCEMENT: // Added part text position reset function. // rl (990616) ENHANCEMENT: // Added small angle adjust for problem polygons. // rl (980929) RELEASED FOR BAE V4.2. // mb (980710) ENHANCEMENT: // Pulldown menu delimiters introduced. // mb (980710) ENHANCEMENT: // Dynamic multi-language support introduced. // rl (980331) ENHANCEMENT: // Added macro name pattern selection. // rl (971120) ENHANCEMENT: // Added visibility selection. // rl (970929) RELEASED FOR BAE V4.0. // mb (970114) ENHANCEMENT: // New option for (de)selecting macro types/macros. // mb (960919) RELEASED FOR BAE V3.4. // mb (95) RELEASED FOR BAE V3.2. // mb (950209) ENHANCEMENT/NEW: // New option for changing size of group-selected texts. // New option for changing width of group-selected traces. // mb (941121) ENHANCEMENT: // Integrated GRPCPMAT, GRPCPTRC. // mb (94) RELEASED FOR BAE V3.0. // mb (94) IMPROVEMENT: // New options for single element selection/deselection. // Featuring ged_layergrpchg function for layer-specific select. // New options for text/polygon/path layer change. // mb (93) RELEASED FOR BAE V2.6. // mb (93) ORIGINAL CODING. // // DESCRIPTION // // The gedgroup User Language program provides a menu with // advanced Layout Editor group functions such as automatic // selection and/or de-selection of specially defined groups // of elements of the currently loaded layout element (e.g. // all objects of a selectable type, all fixed/unfixed, all // mirrored/unmirrored, all on selectable layer, etc.). // Moreover functions are 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 "baeparam.ulh" // User Language BAE param. access #include "pop.ulh" // User Language popup utilities #include "mnu.ulh" // User Language menu utilities #include "lay.ulh" // User Language layout utilities // Disable undo state request #pragma ULCALLERNOUNDO // INI file parameter name definitions #define PAR_GPARTSUF "GPARTSUF_GED" // Group part name suffix #define PAR_GPRECTSEL "GPRECTSEL_GED" // Group rectangle selection flag #define PAR_VIAHIERL "VIAHIERL_GED" // Cross hierarchy via place mode #define PAR_GEDTRCWL "PATHWIDTHL_GED" // Layout path width list // Messages string UPRABORT = M_UPRABORT(); string UPRFEXIT = M_UPRFEXIT(); string REPDONE = M("Es wurden keine Fehler festgestellt.", "Operation completed without errors."); string REPLCTEXT = M("Text-Lagen aendern...", "Changing text layers..."); string REPLCPOLYD = M("Polygon-Dokumentarlagen aendern...", "Changing documentary polygon layers..."); string REPLCPOLYS = M("Polygon-Signallagen aendern...", "Changing signal polygon layers..."); string REPTCPOLY = M("Polygontyp aendern...", "Changing polygon types..."); string REPLCPATH = M("Leiterbahn-Lagen aendern...", "Changing path layers..."); string REPSCTEXT = M("Text-Groessen aendern...", "Changing text sizes..."); string REPSCPOLY = M("Polygon-Groessen aendern...", "Changing polygon sizes..."); string REPSCPATH = M("Leiterbahnbreiten aendern (%smm,%d/%d)...", "Changing path widths (%smm,%d/%d)..."); string REPLCDONE = M(" Lagenaenderungen durchgefuehrt.", " layer changes performed."); string REPTCDONE = M(" Polygontypaenderungen durchgefuehrt.", " polygon type changes performed."); string REPSCDONE = M(" Groessenaenderungen durchgefuehrt.", " size changes performed."); string REPSCPDONE = M("%d Groessenaenderungen durchgefuehrt (%d Problemflaechen unveraendert).", "%d size changes performed (%d problem areas unchanged)."); string REPGRPNSCAN = M("Scannen Gruppennamen...", "Scanning group names..."); string REPELEMSEL = M("%d Element(e) hinzuselektiert. Jetzt %d Elemente in Gruppe.", "%d element(s) selected. Now %d elements in group."); string REPELEMDSEL = M("%d Element(e) deselektiert. Jetzt %d Elemente in Gruppe.", "%d element(s) deselected. Now %d elements in group."); string REPMACLIST = M("Auswahl Makrotyp %s :", "Selection Menu Macro Type %s :"); string REPNAMELIST = M("Auswahl Name(n) :","Name(s) Selection :"); string REPTEXTLIST = M("Auswahl Text(e) :","Text(s) Selection :"); string REPTRCWLIST = M("Auswahl Bahnbreite :","Trace Width 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 UPRGRPFCT = M("%d Elemente in Gruppe. Gruppenfunktion selektieren!", "%d Elements in Group. Select Group Function!"); string UPRGRPMFCT = 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("%L&agen aendern","%C&hange Layers"); string UPRFCT7 = M("&Flaechen groesser","Resize &Areas"); string UPRFCT8 = M("Polygon-T&yp aendern","Change Polygon &Types"); string UPRFCT9 = M("Stift&breite Polygone/Texte", "Change Polygon/Text &Pen Width"); string UPRFCT10 = M("Text&groessen aendern","Change Text Si&zes"); string UPRFCT11 = M("Ba&hnbreiten aendern","Change Path &Widths"); string UPRFCT12 = M("%&Namens-/Attributpositionen uebernehmen", "%Trans&fer Name/Attribute Positions"); string UPRFCT13 = M("Bauteiltexte &Reset","&Reset Part Texts"); string UPRFCT14 = M("%Bahnen-&Kopie","%&Copy Traces"); string UPRFCT15 = M("Matri&x-Kopie","Copy Matri&x"); string UPRFCT16 = M("%Gr&uppennamen setzen","Set Gr&oup Name"); string UPRFCT17 = M("%&Laden ohne Hierarchie","&Load without Hierarchy"); string UPRFCT18 = M("%Gruppe nach Schaltplan","%Group in Schematic"); string UPRFCT19 = M("%Gruppenreport","%Group Report"); string UPRSELALL = M("A&lles","A&ll"); string UPRSELPRT = M("&Bauteile","&Parts"); string UPRSELPRTF = M("%Bauteile aus &Datei","%Parts from &File"); string UPRSELAPRT = M("Alle &Bauteile","All &Parts"); 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 UPRSELPTYP = M("%Polygont&yp","%Polygon T&ype"); string UPRSELNET = M("%&Netz","%&Net"); 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 UPRSELTRCW = M("%B&ahnbreite","%Trace &Width"); string UPRSELSNET = M("%Single Pin Netze","%Single Pin Nets"); string UPRSELPTRC = M("Bauteilbahnzuege","Part Trace Routes"); string UPRSELCHG = M("%Letzte Aenderungen","Last Changes"); string UPRUNDOL = M("Letzte Aenderungen (mehrere Eintraege markierbar)", "Last changes (multiple entries markable)"); string UPRSELWINS = M("Gruppenrechteck Startpunkt waehlen!", "Select Group Rectangle Start Point!"); string UPRSELWINE = M("Gruppenrechteck Endpunkt waehlen!", "Select Group Rectangle End Point!"); string UPRBLOCKBUT = M("%s %d benannte Blockkopie(n)", "%s %d Named Block Copies"); string UPRBLOCKH = M("&Reihenplatzierung","&Row Placement"); string UPRBLOCKV = M("&Spaltenplatzierung","&Column Placement"); string UPRLAYER = M("Lage waehlen!","Select Layer!"); string UPRLAYCHG = M("Neue Lage %s","New layer %d"); string UPRALLTEXT = M("&Alle ruecksetzen","Reset &All"); string UPRLAYTEXT = M("&Lagentexte ruecksetzen","Reset &Layer Texts"); string UPRNAMETEXT = M("&Namen bewegen ruecksetzen","Reset &Name Moves"); string UPRPINTEXT = M("&Pin bewegen ruecksetzen","Reset &Pin Moves"); string UPRTEXT = M("&Texte aendern","Process &Texts"); string UPRNTEXT = M("Texte &nicht aendern","&Ignore Texts"); string UPRPOLY = M("&Polygone aendern","Process &Polygons"); string UPRNPOLY = M("Polygone &nicht aendern","&Ignore Polygons"); string UPRPATH = M("&Bahnen aendern","Process &Traces"); string UPRNPATH = M("Bahnen &nicht aendern","&Ignore Traces"); string UPRSELTRCT = M("Bahnbearbeitungsmodus waehlen!", "Select Trace Process Mode!"); string UPRTRCTD = M("Bahnbearbeitungsmodus :","Trace Process Mode :"); string UPRTRCALL = M("&Alle","&All"); string UPRTRCDRC = M("Mit &DRC","With &DRC"); string UPRTRCSDRC = M("&Schrittweise mit DRC","&Incremental with DRC"); string UPRSELTRCG = M("Bahnsegmentmodus waehlen", "Select Trace Segment Mode :"); string UPRTRCGOFF = M("Nur &ganze Segmente","&Full Segments only"); string UPRTRCGON = M("Segmente &rastern","&Split Segments"); string UPRPPROC = M("Bauteilmodus selektieren!","Select Part Mode!"); string UPRPPROC1 = M("Einzelbauteil","Single Part"); string UPRPPROC2 = M("Gruppenbauteile","Group Parts"); string UPRPTYP = M("Polygon-Typ selektieren!","Select Polygon Type!"); string UPRTSIZEM = M("Neue Textgroesse [mm] ? ","New Text Size [mm] ? "); string UPRTSIZEI = M("Neue Textgroesse [Inch] ? ", "New Text Size [Inch] ? "); string UPRPSIZEM = M("Expansionswert [mm] ? ","Expansion Value [mm] ? "); string UPRPSIZEI = M("Expansionswert [Inch] ? ", "Expansion Value [Inch] ? "); string UPRPWIDTHS = M("Parameter Bahnbreitenaenderung", "Trace Width Change Settings"); string UPRPWIDTH = M("Neue Leiterbreite :","New Trace Width :"); string UPRPWIDTHM = M("Neue Leiterbreite [mm] ? ", "New Trace Width [mm] ? "); string UPRPWIDTHI = M("Neue Leiterbreite [Inch] ? ", "New Trace Width [Inch] ? "); string UPRLWIDTHM = M("Neue Stiftbreite [mm] ? ","New Pen Width [mm] ? "); string UPRLWIDTHI = M("Neue Stiftbreite [Inch] ? ", "New Pen Width [Inch] ? "); string UPRLWIDTH = M("Neue Stiftbreite :","New Pen Width :"); string UPRPENWIDTH = M("Stiftbreite setzen","Set Pen Width"); string UPRSWIDTHM = M("Schrittweite [mm] ? ","Step Width [mm] ? "); string UPRSWIDTHI = M("Schrittweite [Inch] ? ","Step 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 UPRGRPMATNS = M("Anzahl mit Fadenkreuz","Crosshair Count 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 Position Endkopie waehlen!", "Select Matrix End Copy Position!"); string UPRSELNEND = M("Matrix Begrenzungsposition waehlen!", "Select Matrix Border Position!"); string UPRSELANAM = M("Attributname ? ","Attribute Name ?"); string UPRSELAVAL = M("Attributwert(e) ? ","Attribute Value(s) ?"); string UPRSELMACTP = M("Makrotyp fuer Selektion waehlen!", "Select Macro Type to select!"); string UPRDSELMACTP = M("Makrotyp fuer Deselektion waehlen!", "Select Macro Type to deselect!"); string UPRMACPRT = M("&Bauteil","&Part"); string UPRMACNPRT = M("%Bauteil &negiert","%Part &Negated"); string UPRMACSTK = M("Pad&stack","Pad&stack"); string UPRMACNSTK = M("Padstack n&egiert","Padstack N&egated"); string UPRMACPAD = M("&Pad","&Pad"); string UPRMACNPAD = M("Pad &negiert","Pad &Negated"); 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(n) fuer Selektion ? ","Name(s) to select ? "); string UPRDSELNAME = M("Name(n) fuer Deselektion ? ", "Name(s) to deselect ? "); string UPRSELTEXT = M("Text(e) fuer Selektion ? ","Text(s) to select ? "); string UPRDSELTEXT = M("Text(e) fuer Deselektion ? ", "Text(s) to deselect ? "); string UPRSELGNAME = M("Gruppenname fuer Selektion ? ", "Group name to select ? "); string UPRDSELGNAME = M("Gruppenname fuer Deselektion ? ", "Group name to deselect ? "); string UPRGRPNAME = M("Gruppenname ? ","Group Name ? "); string UPRPARTFILE = M("Bauteilnamenslistendatei ? ", "Part Name List File ? "); string UPRTRCWIDTH = M("Bahnbreitenselektion","Trace Width Selection"); string UPRGRPRESET = M("Gruppenname zuruecksetzen ?", "Reset Group Name ? "); string UPRSELMPART = M("Masterbauteil selektieren!","Select Master Part!"); string UPRSELPART = M("Bauteil selektieren!","Select Part!"); #define DE_UPRFILE "Dateiname ? " #define EN_UPRFILE "File Name ? " string UPRFILE = M(DE_UPRFILE,EN_UPRFILE); #define UPRCLLAY "&Layout" string UPRCLLPRT = M("&Bauteil","&Part"); #define UPRCLLSTK "Pad&stack" #define UPRCLLPAD "Pa&d" #define UPRTRCWMM "%s mm" #define UPRTRCWMIL "%s mil" string UPRDUNITMM = M("&mm","&mm"); string UPRDUNITMIL = M("mi&l","mi&l"); string REPGRPCNT = M("%d Elemente in der Gruppe","%d Group Elements"); string REPLAYER = M("%s: %d Gruppenelemente:","%s: %d Group Elements:"); string REPPARTCNT = M("%6d Bauteile","%6d Parts"); string REPPINCNT = M("%6d Pins","%6d Pins"); string REPTEXTCNT = M("%6d Texte","%6d Texts"); string REPTPOLYCNT = M("%6d Flaechen","%6d Areas"); string REPPOLYCNT = M("%6d %s","%6d %s"); string REPPATHCNT = M("%6d Leiterbahnen","%6d Traces"); string REPVIACNT = M("%6d Vias","%6d Vias"); string REPPARTHD = M("Gruppenbauteile:","Group Parts:"); string REPPINHD = M("Gruppenpins:","Group Pins:"); string REPVIAHD = M("Gruppenvias:","Group Vias:"); string REPTEXTHD = M("Gruppentexte:","Group Texts:"); string REPCENTRY = M("%6d %s","%6d %s"); string REPENTRY = M(" %s"," %s"); string REPGRPELEM = M("%d Elemente, %s","%d Elements, %s"); string ERRNOPICK = M_ERRNOPICK(); string ERRNOUNDO = M("Undo-Buffer ist leer!", "Undo/Redo buffer is empty!"); string ERRNOGRP = M("Gruppe enthaelt kein Element von Interesse!", "Group contains no element of interest!"); string ERRNONET = M("Netz '%s' nicht gefunden!","Net '%s' not found!"); string ERRCOORD = M("Ungueltige Koordinaten!","Invalid coordinates!"); string ERRCREATE = M("Fehler beim Erzeugen eines neuen Elementes!", "Error creating new element!"); string ERRPTYP = M(" Fehler beim Aendern des Polygontyps!", " error changing polygon type!"); string ERRPATH = M("Fehler beim Erzeugen der neuen Leiterbahn!", "Error creating new trace!"); string ERRPATHCRD = M("Fehler beim Erzeugen der neuen Leiterbahn (%s %s %.1fmm,%.1fmm)!", "Error creating new trace (%s %s %.1fmm,%.1fmm)!"); 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 ERRFMIS = M("Bauteilnamensdatei '%s' nicht gefunden!", "Part name file '%s' not found!"); string ERRINPVAL = M_ERRINPVAL(); string WRNPGLUED = M(" Gruppenbauteil(e) wegen Verankerung nicht bearbeitet!", " glued group part(s) not processed!"); 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 */; int VIAHIERL = bae_iniintval(PAR_VIAHIERL,1) /* Cross hierarchy via place mode */; #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 #define GV_TRCSEGWIDTH "trcseg_width" // Trace segment width variable #define GV_GRPTMODE "grp_trcmode" // Group trace process mode #define GV_GRPTGSCAN "grp_trcgscan" // Group trace grid scan glag #define FIGTYPALL 0 // Figure list type all #define FONTASP (2.0/3.0) // Font aspect ratio #define SD 0.000001 // Small distance value #define SMALLVAL 0.00000001 // Small compare value int ddbclass = bae_planddbclass() /* Layout plan DDB class */; int plcelems = 0 /* Placed element bit field */; int grpelems = 0 /* Group element bit field */; int grpelemn = 0 /* Group element count */; int grpscan = 0 /* Group scan flag */; string sd_dis = "" /* Padstack/pad items disable */; string s_dis = "" /* Padstack items disable */; string d_dis = "" /* Pad 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 polytreename /* Polygon tree name */; 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 */; index L_LEVEL plevel /* Path level */; int toplay = lay_plantoplay() /* Plan top layer */; int brdaltlay = LAYERINV /* Board outline alternate layer */; int ilaycnt = lay_planmidlaycnt() /* Inner layer count */; // Main program void main() { string msg /* Message buffer */; string hgp_dis = "," /* HighEnd group prt.funct. disable */; // Check if coordinate copy call if (bae_peekiact()==2 && askstr("",MAXTEXTLEN)=="coordcopy") { coordcopy(); exit(0); } // Check if call inside function check_fctactive(); // Test the plan class switch (ddbclass) { case DDBCLLAY : if (bae_swconfig(0)==BAE_HighEnd) hgp_dis=""; break; case DDBCLLPRT : break; case DDBCLLSTK : s_dis=sd_dis=","; break; case DDBCLLPAD : d_dis=sd_dis=","; break; default : error_class(); } bae_defmenusel(-1); // Check if element type scan if (bae_iniintval(PAR_METYPSCAN,1)==1 && !bae_peekiact()) { groupscan(); if (grpelems==0) g_dis=","; if ((plcelems&(1<=0 && layer6) // 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); } // Group element functions static void selectall(int etyp) /* // Group select/deselect all // Parameters : // int etyp : Element type */ { // Select/deselect all elements grpcount(); prtgrpcount(ged_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 grpcount(); prtgrpcount(ged_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 grpcount(); prtgrpcount(ged_groupselect(2,fixflag,selectmode)); } static void selectmir(int mirflag) /* // Select all elements with given mirror flag // Parameters : // int mirflag : Mirror flag */ { index L_FIGURE fig /* Figure list index */; int etyp /* Element type */; int changes = 0 /* Changes count */; // Loop for all elements grpcount(); forall (fig where fig.MIRROR==mirflag && fig.GROUP!=selectmode) // Test the element type if ((etyp=fig.TYP)==L_FIGNREF || etyp==L_FIGUREF || etyp==L_FIGTEXT) { // Select/deselect element to group ged_elemgrpchg(fig,selectmode); changes++; } // Done prtgrpcount(changes); } static void selectattr() /* // Group select parts by attribute values */ { index L_CPART cpart /* Connection part index */; index L_FIGURE fig /* Figure list index */; index L_ATTRIBUTE attr /* Attribute index */; string attnam /* Attribute name */; string vattnam /* Variant attribute name */; STRINGS hl /* Popup menu header list */; int hn = 0 /* Popup menu header count */; STRINGS selentryl /* Selected entry string list */; int selentryn = 0 /* Selected entry count */; int changes = 0 /* Changes count */; string prompt = "" /* Prompt string */; int found /* Attribute found flag */; int act_var /* Active variant */; int negsel = 0 /* Negative selection */; int i /* Loop control variable */; // Build attribute name list bae_prtdialog(REPSCANATT); forall (cpart where cpart.USED&CPART_PLC) forall (attr of cpart) gcname(strmatch(attr.NAME,"*\003*\003") ? strextract(attr.NAME,0,strlen(attr.NAME)-5) : 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,3050); if ((attnam=popupmenu(4,UPRSELANAM,hl,hn,namel,namen, UINPOPABORT,0,-1,-1,0,0,0,UINPOPABORT))=="" || attnam==UINPOPABORT || attnam[0]!='$') error_abort(); // Query the current active variant if (lay_rulequery(RS_OCPLAN,0,RS_PCBSUBJ,RS_VARIANT,"?d",act_var)<1) // Set default variant act_var=0; // Build attribute value list bae_prtdialog(REPSCANATT); namen=0; vattnam=varattrname(attnam,act_var); forall (cpart where cpart.USED&CPART_PLC) { if (lay_nrefsearch(cpart.NAME,fig)==0 && fig.GROUP==selectmode) continue; found=0; if (act_var) forall (attr of cpart where attr.NAME==vattnam) { gcname(attr.VALUE); found=1; break; } if (found) continue; forall (attr of cpart where attr.NAME==attnam) { gcname(attr.VALUE); break; } } // 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,3051); popupmulmenu(5,0,UPRSELAVAL,hl,hn,namel,namen, 0,-1,hn+namen+2,100,selentryl,selentryn,negsel); // Abort if no values selected if (selentryn<=0) error_abort(); // Loop for all parts forall (cpart where cpart.USED&CPART_PLC) { found=0; if (act_var) forall (attr of cpart where attr.NAME==vattnam) { found=1; for (i=0;i=selentryn)) && lay_nrefsearch(cpart.NAME,fig)==0 && fig.GROUP!=selectmode) { ged_elemgrpchg(fig,selectmode); changes++; } break; } if (found) continue; // Search attribute forall (attr of cpart where attr.NAME==attnam) { for (i=0;i=selentryn)) && lay_nrefsearch(cpart.NAME,fig)==0 && fig.GROUP!=selectmode) { ged_elemgrpchg(fig,selectmode); changes++; } break; } } // Done prtgrpcount(changes); } 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 L_FIGURE fig /* Figure list index */; int changes = 0 /* Changes count */; grpcount(); // 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 ged_elemgrpchg(fig,selectmode); changes++; } } 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 ged_elemgrpchg(fig,selectmode); changes++; } } prtgrpcount(changes); } static int isconelem(index L_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 L_FIGURE fig : Figure list index */ { index L_POLY poly /* Polygon index */; index L_CPART cpart /* Connection part index */; index L_CNET cnet /* Connection net index */; string netname /* Net name */; // Perform special check on named reference if (fig.TYP==L_FIGNREF) { return(lay_findconpart(fig.NAME,cpart)==0); } else if (fig.TYP==L_FIGPOLY && fig.TREE==(-1)) { // Check if copper fill polygon poly=fig.POLY; if (poly.TYP==L_POLYCOPFILL) return(poly.TREE!=(-1) && lay_gettreeidx(poly.TREE,cnet)==0 && cnet.PINN>1); // Scan the polygon data polytfound=0; if (lay_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,tpolyfunc,NULL,NULL,NULL,NULL,NULL)) error_scan(); return(polytfound); } else if (fig.TYP==L_FIGUREF && fig.TREE==(-1) && fig.RULEOBJID>=0) { // Query group name predicate if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_VIAFILLNET, "?s",netname)>0 && lay_findcontree(netname,cnet)==0 && cnet.PINN>1) return(1); } // Perform tree number check return(fig.TREE!=(-1) && lay_gettreeidx(fig.TREE,cnet)==0 && cnet.PINN>1); } static int tpolyfunc(index L_POLY poly,int layer, int polyinws,int tree,index L_LEVEL level) /* // Store polygon tree check function // Return value : // zero if done or (-1) on file error // Parameters : // index L_POLY poly : Polygon // int layer : Polygon layer // int polyinws : Poly in workspace flag // int tree : Polygon tree number // index L_LEVEL level : Polygon level */ { index L_CNET cnet /* Connection list index */; if (level>=0 && lay_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 L_MACRO macro /* Macro index */; index L_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 prt_dis = "," /* Part macro disable */; string stk_dis = "," /* Padstack macro disable */; int changes = 0 /* Changes count */; int negsel = 0 /* Negative selection */; int i /* Loop control variable */; if (bae_iniintval(PAR_METYPSCAN,1)==1 && !bae_peekiact()) groupscan(); // Select macro type to be selected switch (ddbclass) { // Select parts/padstacks on layout level case DDBCLLAY : prt_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,3052); 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 grpcount(); forall (fig where fig.GROUP!=selectmode) { if (fig.TYP==figtyp1) macname=fig.NREF.MACRO.NAME; else if (fig.TYP==figtyp2) macname=fig.UREF.MACRO.NAME; else continue; if ((!negsel && strmatch(macname,selmacroname)) || (negsel && !strmatch(macname,selmacroname))) { ged_elemgrpchg(fig,selectmode); changes++; } } // Done prtgrpcount(changes); } // Group name functions static void selectnames() /* // Select name specified elements */ { index L_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 changes = 0 /* Changes count */; string p_dis = "," /* Part function disable */; string t_dis = "," /* Text function disable */; int elemtyp /* Selection element type */; string selname /* Selection name */; string infname /* Input file name */; int fh /* Input file handle */; string readbuf /* Input buffer */; int i /* Loop control variable */; char c /* Character buffer */; forall (fig where fig.GROUP!=selectmode && fig.TYP==L_FIGNREF) { p_dis=""; break; } forall (fig where fig.GROUP!=selectmode && fig.TYP==L_FIGTEXT) { t_dis=""; break; } // Get selection element class if ((elemtyp=bae_askmenu(4,p_dis+UPRSELPRT, t_dis+UPRSELTXT,p_dis+UPRSELPRTF,UPRABORT))<0 || elemtyp>2) error_abort(); if (elemtyp==2) { // Get attribute list file name if (bae_askfilename(infname,"",UPRPARTFILE) || infname=="") return; grpcount(); // Set file error mode fseterrmode(0); // Open part name file if ((fh=fopen(infname,0))<0) { fseterrmode(1); errormsg(ERRFMIS,infname); } // Loop for all lines while (fgets(readbuf,1024,fh)==0) { switch (c=readbuf[0]) { case '\'' : for (i=1;(c=readbuf[i])!='\0';i++) if (c=='\'') break; selname=strextract(readbuf,1,i-1); break; case '"' : for (i=1;(c=readbuf[i])!='\0';i++) if (c=='"') break; selname=strextract(readbuf,1,i-1); break; default : selname=readbuf; for (i=0;(c=selname[i])!='\0';i++) if (c==' ' || c=='*' || c=='?' || c=='\'' || c=='"' || c==0x0A || c==0x0D) { selname[i]='\0'; break; } } if (lay_nrefsearch(selname,fig)==0 && fig.GROUP!=selectmode) { ged_elemgrpchg(fig,selectmode); changes++; } } // Close the file fclose(fh); fseterrmode(1); // Done prtgrpcount(changes); return; } bae_nameclr(); if (elemtyp) { forall (fig where fig.GROUP!=selectmode && fig.TYP==L_FIGTEXT) bae_nameadd(fig.NAME,"","","",2); } else { forall (fig where fig.GROUP!=selectmode && fig.TYP==L_FIGNREF) bae_nameadd(fig.NAME,"","","",2); } while (bae_nameget(nn,nl[nn],"","","",0)==0) nn++; // Select name with popup menu hl[0]=elemtyp ? REPTEXTLIST : REPNAMELIST; hl[1]=""; // Show the multiple selection menu bae_setintpar(16,3045); popupmulmenu(1,0,elemtyp ? (selectmode ? UPRSELTEXT : UPRDSELTEXT) : (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 grpcount(); if (elemtyp) { for (i=0;i=0) { // Query group name predicate if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_GROUPNAME, "?s",grpname)<1) continue; bae_nameadd(grpname,"","","",2); } // Select group name bae_setintpar(16,3123); if (bae_askname( selgrpname,selectmode ? UPRSELGNAME : UPRDSELGNAME,MAXKEYLEN)) // Aborted error_abort(); // Change selection state grpcount(); forall (fig where fig.GROUP!=selectmode) { // Query group name predicate if (fig.RULEOBJID<0 || lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ, RS_GROUPNAME,"?s",grpname)<1) grpname=""; if (grpname!=selgrpname) continue; // Select/deselect element to group ged_elemgrpchg(fig,selectmode); changes++; } prtgrpcount(changes); } static void selchanges() /* // Select last changed elements */ { index L_FIGURE fig /* Figure list index */; string msg /* Message buffer */; STRINGS ul /* Undo list */; int ual[] /* Undo age list */; int agel[] /* Undo used age list */; int undocnt = 0 /* Undo items count */; int changes = 0 /* Changes count */; int curundo = baegetintpar(45) /* Cur. undo age */; double cy /* Current y value */; double dialwidth /* Dialog box width */; double dialheight /* Dialog box height */; double baseheight /* Dialog box base height */; int lbidx /* List box item index */; int res /* Result buffer */; int i /* Loop control variable */; for (i=curundo;i>=0;i--) agel[i]=0; forall (fig) agel[fig.INSAGE]++; for (i=curundo;i>0;i--) if (agel[i]!=0) { if (bae_getcmdbuf(curundo-i+1000,"",ul[undocnt])!=1) ul[undocnt]=""; ual[undocnt]=i; undocnt++; } if (undocnt==0) error(ERRNOUNDO); // Check if listbox needed if (bae_dialclr()==0) { baseheight=DIAL_TOPMARG+2.0*DIAL_SEPVSTEP+DIAL_BUTVSTEP; // Perform the input loop do { bae_dialclr(); dial_getboxsizemin(3138,dialwidth,dialheight, DIAL_LEFTMARG+45.0+DIAL_RIGHTSMARG, baseheight+16.0,DIAL_LEFTMARG+45.0+DIAL_RIGHTSMARG, baseheight+2.0); // Store list box cy=DIAL_TOPMARG; lbidx=bae_dialadvcontrol( PA_MULLB|PA_OKSEL|PA_HBRDREL|PA_HSCROLL,(-1),0,0, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,DIAL_RIGHTSMARG, dialheight-baseheight,""); // Store list box entries for (i=0;i=0;i--) agel[i]=0; for (i=0;i=0;i--) agel[i]=0; agel[1]=1; } // Change selection state grpcount(); forall (fig where fig.GROUP!=selectmode && agel[fig.INSAGE]) { // Select/deselect element to group ged_elemgrpchg(fig,selectmode); changes++; } prtgrpcount(changes); } static void selecttrcwidth() /* // Select elements by trace width */ { index L_FIGURE fig /* Figure list index */; index L_LINE path /* Path index */; STRINGS headl /* Header list */; int headn = 0 /* Header count */; STRINGS entryl /* Entry list */; int entryn = 0 /* Entry count */; int popcols /* Requested popup columns */; string answer /* Answer string */; double selwidth /* Selected trace width */; double trcwl[] /* Track width list */; int trcwn = 0 /* Track width count */; int changes = 0 /* Changes count */; int i /* Loop control variable */; // Scan path widths forall (path) { selwidth=path.WIDTH; // Search the path width for (i=0;i=trcwn) { // Add the new path width for (i=trcwn;i>0;i--) if (trcwl[i-1]>selwidth) trcwl[i]=trcwl[i-1]; else break; trcwl[i]=selwidth; trcwn++; } } // Build the trace width name menu headl[0]=REPTRCWLIST; headn=1; popcols=strlen(headl[0])+1; if (bae_getcoorddisp()) { for (entryn=0;entryn=trcwn) selwidth=cvtlength(atof(answer),bae_getcoorddisp() ? 3 : 2,0); // Change selection state grpcount(); forall (fig where fig.GROUP!=selectmode && fig.TYP==L_FIGPATH && fabs(fig.SIZE-selwidth)=0) { // Query group name predicate if (lay_rulequery(RS_OCFIG,fig,RS_PCBSUBJ,RS_GROUPNAME, "?s",grpname)<1) continue; bae_nameadd(grpname,"","","",2); } grpname=""; // Select group name bae_setintpar(16,3123); if (bae_askname(grpname,UPRGRPNAME,MAXKEYLEN)) // Aborted error_abort(); // Check if group reset request if (grpname=="" && bae_msgboxverify(UPRGRPRESET,"")!=1) // Aborted error_abort(); // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); // Loop for all group elements forall (fig where fig.GROUP) // Assign the group name predicate rule rs_assfigstrpred(fig,RS_GROUPNAME,grpname,"",""); } static void grouptranstextpos() /* // Transfer name/attribute moves of group symbols */ { index L_FIGURE sfig /* Source figure list index */; index L_FIGURE fig /* Figure list index */; index L_NREF nref /* Named reference index */; index L_MACRO macro /* Macro index */; index L_REFTEXT rmod /* Ref. text modifier index */; double ang /* Element angle */; double tang /* Text angle */; double btx, bty /* Back transf. text coords. */; double asin, acos /* Angle sin, cos values */; int mirr /* Element mirror mode */; int tmirr /* Text mirror mode */; string lastname = "" /* Last processed name */; int cflag = 0 /* Change flag */; // Pick symbol bae_promptdialog(UPRSELMPART); if (ged_pickelem(sfig,L_FIGNREF)==0) { // Get the macro name nref=sfig.NREF; macro=nref.MACRO; // Get part data ang=sfig.ANGLE; mirr=sfig.MIRROR; nref=sfig.NREF; asin=sin(mirr ? -ang : ang); acos=cos(mirr ? -ang : ang); forall (fig where fig.GROUP && fig!=sfig && lastname!=fig.NAME && fig.NREF.MACRO==macro) { lastname=fig.NAME; // Transfer name moves forall (rmod of nref) { // Transform rel. to abs. position btx=acos*(rmod.X-macro.MNX)- asin*(rmod.Y-macro.MNY); bty=asin*(rmod.X-macro.MNX)+ acos*(rmod.Y-macro.MNY); bty= mirr ? (-bty) : bty ; tmirr= (rmod.MIRROR!=0)!=(mirr!=0) ? 1 : 0 ; tang=rmod.ANGLE; tang+=tmirr ? -ang : ang ; // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Store the text position if (ged_attachtextpos(fig,rmod.STR,rmod.LAYER, fig.X+btx,fig.Y+bty,tang,rmod.SIZE,tmirr)==0) lay_lastfigelem(fig); } } } } /*________________________________________________________________*/ // Group layer delete routines static void gpdellayer() /* // Delete all elements of selectable layer */ { index L_FIGURE fig /* Figure list index */; index L_FIGURE dfig /* Delete figure list index */; int layer /* Layer */; int deldone = 0 /* Delete done flag */; // Set default layer layer= ged_getlaydefmode()==2 ? ged_getlayerdefault() : ged_getpickpreflay(); // Select layer if (bae_promptdialog(UPRLAYER),ged_asklayer(layer,5)) error_abort(); // Loop for all group elements forall (fig where fig.GROUP && !(fig.FIXED&2)) { // Check if element on selected layer if (fig.LAYER==layer) { // Save current state for undo if (deldone==0) bae_callmenu(MNU_BAESAVESTATE); // Delete element dfig=fig; if (ged_delelem(dfig)) error(ERRDELETE); // Set the delete done flag deldone=1; } } // Test the delete done flag if (!deldone) // No element in group/deleted error(ERRNOGRP); // Zoom all zoomall(); // Return without errors bae_prtdialog(REPDONE); } /*________________________________________________________________*/ // Group layer change routines static void grouplayer() /* // Set layer of group-selected elements */ { index L_FIGURE fig /* Figure list element */; string msg /* Message buffer */; double cy = DIAL_TOPMARG /* Current y value */; int textflag = 1 /* Text layer change flag */; int polyflag = 1 /* Polygon layer change flag */; int pathflag = 1 /* Path layer change flag */; int txtidx = (-1) /* Text flag parameter index */; int plyidx = (-1) /* Polygon flag parameter index */; int pthidx = (-1) /* Path flag parameter index */; int layer /* Layer */; int oldlay /* Old polygon layer */; int changes = 0 /* Changes count */; // Set default layer layer= ged_getlaydefmode()==2 ? ged_getlayerdefault() : ged_getpickpreflay(); // Select any layer if (bae_promptdialog(UPRLAYER),ged_asklayer(layer,5)) error_abort(); // Set new default layer ged_setlayerdefault(layer); // Check for dialog support if (bae_dialclr()) { bae_defmenusel(textflag); if ((textflag= bae_askmenu(3,UPRNTEXT,UPRTEXT,UPRABORT))<0 || textflag>1) error_abort(); bae_defmenusel(polyflag); if ((polyflag= bae_askmenu(3,UPRNPOLY,UPRPOLY,UPRABORT))<0 || polyflag>1) error_abort(); if (ddbclass==DDBCLLAY || ddbclass==DDBCLLPRT) { bae_defmenusel(pathflag); if ((pathflag=bae_askmenu(3, UPRNPATH,UPRPATH,UPRABORT))<0 || pathflag>1) error_abort(); } else { pathflag=0; } } else { txtidx=bae_dialaddcontrol(PA_TOGGLE,0,0,textflag, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,0.0,UPRTEXT); cy+=DIAL_CTRVSTEP; plyidx=bae_dialaddcontrol(PA_TOGGLE,0,0,polyflag, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,0.0,UPRPOLY); cy+=DIAL_CTRVSTEP; if ((ddbclass==DDBCLLAY || ddbclass==DDBCLLPRT) && ((layer>=0 && layer=0) bae_dialgetdata(txtidx,textflag,0.0,""); if (plyidx>=0) bae_dialgetdata(plyidx,polyflag,0.0,""); if (pthidx>=0) bae_dialgetdata(pthidx,pathflag,0.0,""); } // Loop thru all group selected texts not on layer if (textflag) { bae_prtdialog(REPLCTEXT); forall (fig where fig.GROUP && !(fig.FIXED&2) && fig.TYP==L_FIGTEXT && fig.LAYER!=layer) { // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Change layer if (ged_elemlaychg(fig,layer)) error(ERRLCTEXT); // Increment the changes count changes++; } } if (polyflag) { // Test the requested layer type if (layer>=DOCLAYBASE) { // Change documentary layers bae_prtdialog(REPLCPOLYD); // Loop thru all doc layer polygons not on layer forall (fig where fig.GROUP && (fig.POLY.TYP==L_POLYDOCAREA || fig.POLY.TYP==L_POLYKEEPOUT || fig.POLY.TYP==L_POLYDOCLINE) && fig.LAYER!=layer && !(fig.FIXED&2)) { // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Change layer if (ged_elemlaychg(fig,layer)) error(ERRLCPOLY); // Increment the changes count changes++; } } else { // Change signal layers bae_prtdialog(REPLCPOLYS); // Loop thru all signal layer polygons not on layer forall (fig where fig.GROUP && fig.TYP==L_FIGPOLY && ((oldlay=fig.LAYER)=DOCLAYBASE) || (siglexc && oldlay=POWLAYBASE && oldlay=0 && lay_gettreeidx(poly.TREE,net)==0) { // Store tree name treename=net.NAME; } else { // No tree name treename=""; } } // Store polygon points bae_clearpoints(); forall (p of poly) bae_storepoint(p.X,p.Y,p.TYP); // Check if first point repetition needed if (newtyp==L_POLYDOCLINE && poly.TYP!=L_POLYDOCLINE) forall (p of poly) { bae_storepoint(p.X,p.Y,p.TYP); break; } // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Store new polygon if (ged_storepoly(poly.LAYER,newtyp,treename,poly.MVIS&0x13)) { errcnt++; continue; } // Transfer rules if (fig.RULEOBJID>=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); // Set group selection flag of new polygon if (lay_lastfigelem(nfig)==0) ged_elemgrpchg(nfig,1); // Delete the old polygon dfig=fig; if (ged_delelem(dfig)) error(ERRDELETE); // Change type // Increment the changes count changes++; } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Done if (errcnt) error(itoa(changes)+REPTCDONE+" "+itoa(errcnt)+ERRPTYP); else bae_prtdialog(itoa(changes)+REPTCDONE); } /*________________________________________________________________*/ // Group size change routines static void grouptextsize() /* // Set size of group-selected texts */ { index L_FIGURE fig /* Figure list element */; int changes = 0 /* Changes count */; double newsize /* New text size */; // Select new text size newsize=baepar_dblval(LAYPAR_DEFTEXTSIZE); if (askdist(newsize,bae_getcoorddisp()?UPRTSIZEI:UPRTSIZEM,0) || newsize==0.0) // Invalid input value error(ERRINPVAL); // Loop thru all group selected texts bae_prtdialog(REPSCTEXT); forall (fig where fig.GROUP && fig.TYP==L_FIGTEXT && !(fig.FIXED&2)) { // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Change size if (ged_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 grouppenwidth() /* // Set pen width of group-selected polygons */ { index L_FIGURE fig /* Figure list element */; index L_POLY poly /* Polygon index */; double pcol = 23.0 /* Parameter column */; double cy = DIAL_TOPMARG /* Current y value */; int textflag = 1 /* Text layer change flag */; int polyflag = 1 /* Polygon layer change flag */; int pwidx /* Pen width parameter index */; int txtidx = (-1) /* Text flag parameter index */; int plyidx = (-1) /* Polygon flag parameter index */; int changes = 0 /* Changes count */; int cunits /* Coordinate display units */; int repflag /* Repeat flag */; int res /* Result */; double newsize = 0.0 /* New pen width */; // Query last used plot width if (varget(VAR_PLOTW,newsize)) // Use default path width ged_getpathwidth(newsize,0.0); // Check for dialog support if (bae_dialclr()) { // Select new pen width if (askdist(newsize, bae_getcoorddisp()?UPRLWIDTHI:UPRLWIDTHM,0)) // Invalid input value error(ERRINPVAL); if ((textflag= bae_askmenu(3,UPRTEXT,UPRNTEXT,UPRABORT))<0 || textflag>1) error_abort(); if ((polyflag= bae_askmenu(3,UPRPOLY,UPRNPOLY,UPRABORT))<0 || polyflag>1) error_abort(); } else { // Store coordinate unit controls cunits= bae_getcoorddisp() ? 2 : 0; // Perform the dialog input loop repflag=1; do { bae_dialclr(); // Init. the y coordinate cy=DIAL_TOPMARG; pwidx=dial_distpar(UPRLWIDTH,5,newsize,pcol,cy); txtidx=bae_dialaddcontrol(PA_TOGGLE,0,0,textflag, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy,0.0,UPRTEXT); cy+=DIAL_CTRVSTEP; plyidx=bae_dialaddcontrol(PA_TOGGLE,0,0,polyflag, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG+pcol,cy,0.0,UPRPOLY); cy+=DIAL_CTRVSTEP; // Store the OK and abort button with seperator dial_hsep(cy); bae_dialaddcontrol(PA_RBF,0,1,cunits,0.0,0.0, 0.0,"",0,DIAL_LEFTMARG+pcol,cy,0.0,UPRDUNITMM); bae_dialaddcontrol(PA_RBN,2,2,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+pcol+6.0,cy,0.0,UPRDUNITMIL); dial_okabort(cy); // Call the dialog function bae_setintpar(16,3007); res=bae_dialaskparams(UPRPENWIDTH,cunits, DIAL_LEFTMARG+pcol+21.0+DIAL_RIGHTSMARG,cy); bae_dialgetdata(pwidx,0.0,newsize,""); // Get the element process flags if (txtidx>=0) bae_dialgetdata(txtidx,textflag,0.0,""); if (plyidx>=0) bae_dialgetdata(plyidx,polyflag,0.0,""); switch (res) { case 0 : repflag=0; break; // Switch to mm units case 1 : cunits=0; break; // Switch to mil units case 2 : cunits=2; break; // Fail/abort case (-1) : default : error_abort(); } // Stop if no further repeat requests } while (repflag); } // Preserve width data for next call varset(VAR_PLOTW,newsize); // Loop thru all group selected texts if (textflag) { bae_prtdialog(REPSCTEXT); forall (fig where fig.GROUP && fig.TYP==L_FIGTEXT && !(fig.FIXED&2)) { // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Change pen width rs_assfigdblpred(fig,RS_PLOTWIDTH,newsize,0.0,""); // Increment the changes count changes++; } } // Loop thru all group selected polygons if (polyflag) { bae_prtdialog(REPSCPOLY); forall (fig where fig.GROUP && fig.TYP==L_FIGPOLY && !(fig.FIXED&2)) { // Check the polygon type poly=fig.POLY; if (poly.TYP!=L_POLYDOCLINE && poly.TYP!=L_POLYSPPAREA) continue; // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Change pen width rs_assfigdblpred(fig,RS_PLOTWIDTH,newsize,0.0,""); // Increment the changes count changes++; } } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Redraw the screen bae_callmenu(MNU_BAEREDISPL); // Done bae_prtdialog(itoa(changes)+REPSCDONE); } static void grouppathwidth() /* // Set width of group-selected paths */ { index L_FIGURE fig /* Figure list element */; index L_FIGURE dfig /* Delete figure list element */; index L_FIGURE nfig /* New figure list index */; index L_LINE trace /* Trace index */; index L_CNET cnet /* Net index */; index L_POINT p /* Polygon point index */; string msg /* Message buffer */; STRINGS msgl /* Message list */; int msgn = 0 /* Message count */; double pcol = 23.0 /* Parameter column */; double cy = DIAL_TOPMARG /* Current y value */; int gridscan /* Segment grid scan flag */; int twidx /* Trace width parameter index */; int tmidx /* Trace mode parameter index */; int gsidx /* Grid scan flag parameter index */; int cunits /* Coordinate display units */; int repflag /* Repeat flag */; int res /* Result */; STRINGS rl /* Rule list */; int rn /* Rule count */; int trcmode /* Trace process mode */; int changes = 0 /* Changes count */; double newwidth /* New path width */; double minwidth /* Minimum path width */; double stepwidth /* Path step width */; int gridlock = bae_getgridlock() /* Grid lock flag */; double gridstep /* Path grid step */; double x, y /* Current path coordinates */; double wsnx = bae_planwsnx()/* Workspace X origin */; double wsny = bae_planwsny()/* Workspace Y origin */; double px, py /* Path previous coordinates */; double vx, vy /* Path segment vector */; double pslen /* Path segment length */; double pso /* Path segment offset */; int chkres /* Path segment check result */; struct point { // Point descriptor double x /* Point x coordinate */; double y /* Point y coordinate */; int t /* Point type */; int f /* Segment valid flag */; } pl[], pol[] /* Polygon point list */; int pn /* Polygon point count */; int pon /* Output polygon point count */; double sizel[] /* Size list */; int sizen /* Size count */; int sidx /* Size scan index */; int valid /* Any valid segment found flag */; int curcnt = 0 /* Current trace count */; int totcnt /* Total trace count */; int errflag /* Error flag */; int i, j /* Loop control variables */; // Abort if invalid plan class if (ddbclass!=DDBCLLAY && ddbclass!=DDBCLLPRT) error_class(); // Get the input grid if (gridlock) bae_getinpgrid(gridstep,0.0); else gridstep=0.0; if (varget(GV_TRCSEGWIDTH,newwidth)) // Use default path width ged_getpathwidth(newwidth,0.0); if (varget(GV_GRPTMODE,trcmode)) trcmode=0; if (varget(GV_GRPTGSCAN,gridscan)) gridscan=0; // Check for dialog support if (bae_dialclr()) { // Select trace process mode bae_defmenusel(-1); bae_promptdialog(UPRSELTRCT); if ((trcmode=bae_askmenu(4, UPRTRCALL,UPRTRCDRC,UPRTRCSDRC,UPRABORT))<0 || trcmode>2) error_abort(); // Select new path width if (askdist(newwidth,bae_getcoorddisp()?UPRPWIDTHI:UPRPWIDTHM,0) || newwidth==0.0) // Invalid input value error(ERRINPVAL); // Select grid scan mode bae_defmenusel(-1); bae_promptdialog(UPRSELTRCG); if ((gridscan=bae_askmenu(3, UPRTRCGOFF,UPRTRCGON,UPRABORT))<0 || gridscan>1) error_abort(); } else { // Store coordinate unit controls cunits= bae_getcoorddisp() ? 2 : 0; // Perform the dialog input loop repflag=1; do { bae_dialclr(); // Init. the y coordinate cy=DIAL_TOPMARG; tmidx=dial_selboxpar(UPRTRCTD,trcmode,pcol,cy); dial_sbentry(3,0,UPRTRCALL); dial_sbentry(3,1,UPRTRCDRC); dial_sbentry(3,2,UPRTRCSDRC); twidx=dial_distpar(UPRPWIDTH,5,newwidth,pcol,cy); gsidx=bae_dialaddcontrol( PA_RBF|(trcmode==0 ? PA_GRAYED : 0),0,0,gridscan, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG,cy,0.0,UPRTRCGOFF); bae_dialaddcontrol( PA_RBN|(trcmode==0 ? PA_GRAYED : 0),1,0,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+pcol,cy,0.0,UPRTRCGON); cy+=DIAL_CTRVSTEP; // Store the OK and abort button with seperator dial_hsep(cy); bae_dialaddcontrol(PA_RBF,0,1,cunits,0.0,0.0, 0.0,"",0,DIAL_LEFTMARG+pcol,cy,0.0,UPRDUNITMM); bae_dialaddcontrol(PA_RBN,2,2,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+pcol+6.0,cy,0.0,UPRDUNITMIL); dial_okabort(cy); // Call the dialog function bae_setintpar(16,3104); res=bae_dialaskparams(UPRPWIDTHS,cunits, DIAL_LEFTMARG+pcol+21.0+DIAL_RIGHTSMARG,cy); bae_dialgetdata(twidx,0,newwidth,""); bae_dialgetdata(tmidx,trcmode,0.0,""); bae_dialgetdata(gsidx,gridscan,0.0,""); switch (res) { case 0 : repflag=0; break; // Switch to mm units case 1 : cunits=0; break; // Switch to mil units case 2 : cunits=2; break; // Trace mode change case 3 : break; // Fail/abort case (-1) : default : error_abort(); } // Stop if no further repeat requests } while (repflag); } // Preserve width data for next call varset(GV_TRCSEGWIDTH,newwidth); varset(GV_GRPTMODE,trcmode); varset(GV_GRPTGSCAN,gridscan); if (trcmode==2) { // Get size list for (sizen=0;sizen<1000;sizen++) if ((sizel[sizen]=bae_inidblval(bae_iniarrayvarname( PAR_GEDTRCWL,sizen),0.0))==0.0) break; // Get minimum path width minwidth=newwidth; forall (fig where fig.GROUP && fig.TYP==L_FIGPATH && !(fig.FIXED&2)) if (fig.SIZEnewwidth) break; } } else { // Store target width sizel[0]=newwidth; sizen=1; sidx=0; } for (;sidx=newwidth) continue; // Update process status display curcnt++; sprintf(msg,REPSCPATH,bae_numstring(cvtlength(newwidth,0,2),2), curcnt,totcnt); bae_prtdialog(msg); // Abort on request if (kbhit()) { getchr(); if (verify(UPRFEXIT,1)) break; } // Check trace change mode if (trcmode) { // Get trace points trace=fig.LINE; pn=0; forall (p of trace) { pl[pn].x=p.X; pl[pn].y=p.Y; pl[pn].t=p.TYP; pl[pn].f=0; pn++; } // Get trace level if (lay_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,NULL,pathlfunc,NULL,NULL,NULL,NULL)) error_scan(); // Check all trace segments valid=0; for (i=0;ipslen) pso=pslen; bae_storepoint( x+pso*vx,y+pso*vy,0); if (ged_drcpath( fig.LAYER,newwidth, plevel,1)==0) { pl[i].f=2; valid=1; break; } } } } else { pl[i].f=1; valid=1; } } // Check if any valid segment found if (!valid) { ged_elemgrpchg(fig,0); continue; } // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Get rules rn= fig.RULEOBJID>=0 ? rs_getfigrules(fig,rl) : 0; // Store all trace segments pon=0; errflag=0; valid=pl[0].f; for (i=0;ipslen) pso=pslen; bae_storepoint(x+pso*vx,y+pso*vy,0); chkres=ged_drcpath(fig.LAYER,newwidth, plevel,1)==0 ? 1 : 0 ; if (valid==2) valid=chkres; if (valid!=chkres) { bae_clearpoints(); for (j=0;j0 && lay_lastfigelem(nfig)==0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); pon=0; pol[pon].x=px; pol[pon].y=py; pol[pon].t=0; pon++; pol[pon].x=x+pso*vx; pol[pon].y=y+pso*vy; pol[pon].t=0; pon++; } valid=chkres; } if (errflag) break; pl[i].f=valid; } else { pol[pon].x=x; pol[pon].y=y; pol[pon].t=pl[i].t; pon++; } if (i==(pn-1) || valid!=pl[i].f) { bae_clearpoints(); for (j=0;j0 && lay_lastfigelem(nfig)==0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); pon=0; if (i==(pn-1)) break; pol[pon].x=x; pol[pon].y=y; pol[pon].t=pl[i].t; pon++; } if (pl[i+1].t) { pol[pon].x=pl[i+1].x; pol[pon].y=pl[i+1].y; pol[pon].t=pl[i+1].t; pon++; } valid=pl[i].f; } if (errflag) continue; // Delete the old path bae_setintpar(2,1); dfig=fig; if (ged_delelem(dfig)) { bae_setintpar(2,0); error(ERRDELETE); } bae_setintpar(2,0); // Generate connectivity to include new trace(s) in DRC bae_postprocess(); // Increment the changes count changes++; } else { if (fabs(fig.SIZE-newwidth)<=SMALLVAL) continue; // Save current state for undo if (changes==0) bae_callmenu(MNU_BAESAVESTATE); // Change width bae_setintpar(2,1); if (ged_elemsizechg(fig,newwidth)) { bae_setintpar(2,0); error(ERRSCPATH); } bae_setintpar(2,0); // Increment the changes count changes++; } } } if (msgn) { msgl[msgn]=itoa(changes)+REPSCDONE; bae_setintpar(16,3108); mnu_poptext(msgl,0,0,-1,0,0); return; } // Check the changes count if (!changes) // No element in group/changed error(ERRNOGRP); // Redraw the screen bae_callmenu(MNU_BAEREDISPL); // Done bae_prtdialog(itoa(changes)+REPSCDONE); } void normvect(double x,double y,double len) /* // Normalize vector // Parameters : // double x : Vector X coordinate // double y : Vector Y coordinate // double len : Vector original length return */ { // Get length len=sqrt(x*x+y*y); if (len==0.0) return; // Normalize data x/=len; y/=len; } /*________________________________________________________________*/ // Part text routines void resetparttexts() /* // Reset text positions of mouse-selectable parts */ { index L_FIGURE fig /* Figure list index */; index L_FIGURE dfig /* Delete figure list element */; index L_FIGURE nfig /* New figure list index */; index L_NREF nref /* Named reference index */; index L_MACRO macro /* Macro index */; index L_REFTEXT rmod /* Reference text modifier index */; struct refmoddes { // Reference text modifier descriptor double x,y /* Text position */; double ang /* Text angle */; double size /* Text size */; int mirr /* Text mirror flag */; int layer /* Text layer */; string str /* Text string */; } rtml[] /* Reference text modifier list */; int rtmn = 0 /* Part ref. text modifier count */; string name = "" /* Part name buffer */; string macname /* Part macro name buffer */; double x,y /* Part position buffer */; double ang /* Part angle buffer */; int mirr /* Part mirror buffer */; int robjid /* Part rule object id */; int fix /* Part fix state */; double btx, bty /* Transformed text position */; double tang /* Transformed rotation angle */; double asin, acos /* Angle sin, cos values */; int tmirr /* Transformed mirror flag */; int gluecnt = 0 /* Glued parts count */; int layer /* Part text layer */; int cflag = 0 /* Change flag */; STRINGS rl /* Rule list */; int i /* Loop control variable */; // Abort if invalid plan class if (ddbclass!=DDBCLLAY && ddbclass!=DDBCLLPRT) error_class(); // Select the process mode bae_defmenusel(-1); switch (bae_askmenu(5,UPRALLTEXT,UPRLAYTEXT,UPRNAMETEXT,UPRPINTEXT, UPRABORT)) { /* All part texts */ case 0 : layer=0; break; /* Layer part texts */ case 1 : // Select documentary layer if (bae_promptdialog(UPRLAYER),ged_asklayer(layer,3)) error_abort(); break; /* Name moves */ case 2 : layer=LAYERINV; break; /* Pin moves */ case 3 : layer=LAYERALL; break; default : error_abort(); } // Count glued parts forall (fig where fig.TYP==L_FIGNREF && fig.GROUP && (fig.FIXED&2)) gluecnt++; // Loop for all unglued group parts forall (fig where fig.TYP==L_FIGNREF && fig.GROUP && !(fig.FIXED&2)) { // Buffer the part data nref=fig.NREF; name=nref.NAME; macro=nref.MACRO; macname=macro.NAME; x=nref.X; y=nref.Y; ang=nref.ANGLE; mirr=nref.MIRROR; fix=fig.FIXED; if ((robjid=fig.RULEOBJID)>=0) // Get rules if (rs_getfigrules(fig,rl)<=0) robjid=(-1); rtmn=0; if (layer!=0) forall (rmod of nref where rmod.LAYER!=layer) { // Transform rel. to abs. position asin=sin(mirr ? -ang : ang); acos=cos(mirr ? -ang : ang); btx=acos*(rmod.X-macro.MNX)- asin*(rmod.Y-macro.MNY); bty=asin*(rmod.X-macro.MNX)+ acos*(rmod.Y-macro.MNY); bty= mirr ? (-bty) : bty ; tmirr=(rmod.MIRROR!=0)!=(mirr!=0) ? 1 : 0 ; tang=rmod.ANGLE; tang+=tmirr ? -ang : ang ; rtml[rtmn].x=btx; rtml[rtmn].y=bty; rtml[rtmn].ang=tang; rtml[rtmn].size=rmod.SIZE; rtml[rtmn].mirr=tmirr; rtml[rtmn].layer=rmod.LAYER; rtml[rtmn].str=rmod.STR; rtmn++; } // Save current state for undo if (cflag==0) { bae_callmenu(MNU_BAESAVESTATE); cflag=1; } // Delete the old part dfig=fig; if (ged_delelem(dfig)) error(ERRDELETE); // Place part at same position if (ged_storepart(name,macname,x,y,ang,mirr)<0) error(ERRCREATE); // Check if part should be fixed if (fix && lay_lastfigelem(nfig)==0) ged_elemfixchg(nfig,fix); // Transfer rules if (robjid>=0 && lay_lastfigelem(nfig)==0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); for (i=0;igux) gux=fig.RUX; if (fig.RLYguy) guy=fig.RUY; } switch (fig.TYP) { // Path case L_FIGPATH : // Scan the path data if (lay_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,NULL,pathfunc,NULL,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;j=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } } break; // Via case L_FIGUREF : // Scan the via data vianame=""; if (lay_scanfelem(fig,0.0,0.0,0.0,1,0, viamac,NULL,NULL,NULL,NULL,NULL,NULL)) error_scan(); if (vianame!="") { vx=fig.X; vy=fig.Y; for (i=1;i<=grpcnt;i++) { if (ged_storeuref(vianame, vx+i*xstep,vy+i*ystep,0.0,0,0)) error(ERRPATH); // Check if via should be fixed if (fig.FIXED && lay_lastfigelem(nfig)==0) ged_elemfixchg(nfig,fig.FIXED); // Transfer rules if (fig.RULEOBJID>=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } } break; } } if (!first) { // Get source range gw=gux-glx; gh=guy-gly; // Calculate destination range if (ystep>0.0) guy=gly+grpcnt*ystep+gh; else gly=guy+grpcnt*ystep-gh; if (xstep>0.0) gux=glx+grpcnt*xstep+gw; else glx=gux+grpcnt*xstep-gw; // Ensure group destination range display winadjust(glx,gly,gux,guy); } // Return without errors bae_prtdialog(REPDONE); } static void groupcopymatrix() /* // Group Copy Matrix */ { struct blocktrans { // Block name transfer descriptor string blkname /* Block name */; string srcpref /* Source block instance prefix */; string dstprefl[] /* Destination block instance list */; int dstprefn /* Destination block instance count */; } btnl[] /* Block name transfer list */; int btnn = 0 /* Block name transfer count */; int blockproc = 0 /* Block processing flag */; int curdpref = (-1) /* Current destination prefix */; index L_CPART cpart /* Connection part index */; index L_FIGURE fig,sfig /* Figure list index */; index L_FIGURE nfig /* New figure list index */; index L_NREF nref /* Named reference index */; index L_MACRO macro /* Macro index */; index L_REFTEXT rmod /* Ref. text modifier index */; string srcpref /* Source block instance name prefix */; string namepref /* Block instance name prefix */; string suffix /* Part name suffix */; string blkname /* Block name */; string msg /* Message string */; int grpxcnt = 1 /* Number of group x copies */; int grpycnt = 1 /* Number of group y copies */; double x1,y1 /* Group origin coordinates */; double x2,y2 /* Group first copy coordinates */; double xstep,ystep /* Group matrix element vector */; double xoff,yoff /* Group offset vector */; double x,y /* Element coordinates */; double ang /* Element angle */; double tang /* Text angle */; double size /* Element size */; double btx, bty /* Back transf. text coords. */; double asin, acos /* Angle sin, cos values */; double glx, gly /* Group lower left coordinates */; double gux, guy /* Group upper right coordinates */; double gw, gh /* Group dimensions */; int first = 1 /* First group element flag */; int layer /* Element layer */; int mirr /* Element mirror mode */; int tmirr /* Text mirror mode */; int gpidx = 1 /* Group part name index */; STRINGS rl /* Rule list */; double pcol = 25.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 gxcidx = (-1) /* X count dialog box item idx. */; int gycidx = (-1) /* Y count dialog box item idx. */; int grsidx = (-1) /* Rect. sel. dialog box item idx. */; int sizemode = 0 /* Matrix size input mode */; int i,j,k /* Loop control variables */; if (varget(GV_GRPXCNT,grpxcnt)) grpxcnt=1; if (varget(GV_GRPYCNT,grpycnt)) grpycnt=1; ged_getintpar(115,brdaltlay); // Scan for hierarchic blocks bae_nameclr(); forall (fig where fig.GROUP && fig.TYP==L_FIGNREF && lay_findconpart(fig.NAME,cpart)==0 && (srcpref=getblockpref(fig.NAME,suffix))!="" && (blkname=getpartblock(cpart))!="") bae_nameadd(srcpref,"","",blkname,2); for (i=0;bae_nameget(i,srcpref,"","",blkname,0)==0;i++) { btnl[btnn].blkname=blkname; btnl[btnn].srcpref=srcpref; btnl[btnn].dstprefn=0; forall (cpart where (cpart.USED&1)==0 && (namepref=getblockpref(cpart.NAME,suffix))!=srcpref && getpartblock(cpart)==blkname) { for (j=0;j=btnl[btnn].dstprefn) { for (k=btnl[btnn].dstprefn;k>0;k--) if (numstrcmp(btnl[btnn].dstprefl[k], namepref)>0) btnl[btnn].dstprefl[k]= btnl[btnn].dstprefl[k-1]; else break; btnl[btnn].dstprefl[k]=namepref; btnl[btnn].dstprefn++; } } if (btnl[btnn].dstprefn>0) btnn++; } if (bae_dialclr()) { // Ask for x copy count and test it if (askint(grpxcnt,UPRGRPXCNT,5) || grpxcnt<=0) error(ERRINPVAL); // Ask for y copy count and test it if (askint(grpycnt,UPRGRPYCNT,5) || grpycnt<=0) error(ERRINPVAL); } else { cy=DIAL_TOPMARG; // Store group x count controls dial_label(0.0,cy,UPRGRPXCNTD); gxcidx=bae_dialaddcontrol(PA_INT|PA_CHKLL|PA_HBRDREL,1,0, grpxcnt,0.0,0.0,0.0,"",30,DIAL_LEFTMARG+pcol,cy, DIAL_RIGHTEMARG,""); cy+=DIAL_CTRVSTEP; // Store group y count controls dial_label(0.0,cy,UPRGRPYCNTD); gycidx=bae_dialaddcontrol(PA_INT|PA_CHKLL|PA_HBRDREL,1,0, grpycnt,0.0,0.0,0.0,"",30,DIAL_LEFTMARG+pcol,cy, DIAL_RIGHTEMARG,""); cy+=DIAL_CTRVSTEP; grsidx=dial_toggle(GPRECTSEL,0.0,cy,UPRGRPMATRS); dial_action(DIAL_LEFTMARG,cy,1,UPRGRPMATGS); dial_action(DIAL_LEFTMARG+17.0,cy,2,UPRGRPMATNS); cy+=DIAL_BUTVSTEP; if (btnn>0) { dial_hsep(cy); for (i=0;i=4 && res<=(4+btnn)) { res-=4; blockproc=1; srcpref=btnl[res].srcpref; // Check if matrix matches block count if (grpxcnt*grpycnt!= (btnl[res].dstprefn+1)) switch (bae_askmenu(3,UPRBLOCKH, UPRBLOCKV,UPRABORT)) { case 0 : grpxcnt= btnl[res].dstprefn+1; grpycnt=1; break; case 1 : grpxcnt=1; grpycnt= btnl[res].dstprefn+1; break; default : error_abort(); } repflag=0; sizemode=0; break; } error_abort(); } // Stop if no further repeat requests } while (repflag); } // Store settings for next call varset(GV_GRPXCNT,grpxcnt); varset(GV_GRPYCNT,grpycnt); varset(PAR_GPRECTSEL,GPRECTSEL); // Test if group empty groupscan(); if (!GPRECTSEL && grpelemn==0) // Group empty; abort error(ERRNOGRP); // Select group origin coordinates bae_promptdialog(UPRSELORG); if (bae_inpoint(bae_planwsnx(),bae_planwsnx(),x1,y1,0)) error_abort(); // Select matrix diagonal coordinates if (bae_promptdialog(UPRSELMVEC),bae_inpoint(x1,y1,x2,y2,1)) error_abort(); // Calculate grid steps xstep=x2-x1; ystep=y2-y1; if (xstep==0.0 && ystep==0.0) error(ERRCOORD); if (GPRECTSEL) { // Reset group bae_clriactqueue(); if (grpelemn) call(MNU_GEDGRPRESE); // Select matrix rectangle bae_storemenuiact(1,4,LMB); bae_storemenuiact(1,0,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); } if (sizemode) { // Select matrix diagonal coordinates bae_promptdialog(sizemode==1 ? UPRSELMEND : UPRSELNEND); if (bae_inpoint(x1,y1,x2,y2,1)) error_abort(); if (xstep==0.0) grpxcnt=0; else if (x2>x1) grpxcnt=floor((x2-x1+SMALLVAL)/fabs(xstep)); else grpxcnt=floor((x1-x2+SMALLVAL)/fabs(xstep)); if (sizemode==2) grpxcnt++; if (ystep==0.0) grpycnt=0; else if (y2>y1) grpycnt=floor((y2-y1+SMALLVAL)/fabs(ystep)); else grpycnt=floor((y1-y2+SMALLVAL)/fabs(ystep)); if (sizemode==2) grpycnt++; if (grpxcnt<=0 || grpycnt<=0) error(ERRCOORD); } strlower(PARTSUFFIX); // Loop for all figure list elements first=1; forall (fig where fig.GROUP) { // Update group range if (first) { glx=fig.RLX; gly=fig.RLY; gux=fig.RUX; guy=fig.RUY; first=0; // Save current state for undo bae_callmenu(MNU_BAESAVESTATE); } else { if (fig.RLXgux) gux=fig.RUX; if (fig.RLYguy) guy=fig.RUY; } switch (fig.TYP) { // Polygon case L_FIGPOLY : // Scan the polygon data if (lay_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,polyfunc,NULL,NULL,NULL,NULL,NULL)) error_scan(); // Check if polygon points found if (ppcnt==0) continue; // Get polygon data layer= fig.POLY.TYP==L_POLYBRDOUT ? brdaltlay : fig.LAYER; mirr=fig.MIRROR; // Loop for all matrix elements for (i=0;i=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } break; // Path case L_FIGPATH : // Scan the path data if (lay_scanfelem(fig,0.0,0.0,0.0,1,0, NULL,NULL,pathfunc,NULL,NULL,NULL,NULL)) error_scan(); // Check if path points found if (ppcnt==0) continue; // Get path data size=fig.SIZE; layer=fig.LAYER; // Loop for all matrix elements for (i=0;i=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } break; // Part case L_FIGNREF : // Get the macro name macroname=fig.NREF.MACRO.NAME; // Check if macro name found if (macroname=="") error(ERRCREATE); // Get part data x=fig.X; y=fig.Y; ang=fig.ANGLE; mirr=fig.MIRROR; nref=fig.NREF; macro=nref.MACRO; // Loop for all matrix elements curdpref=0; for (i=0;i=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); // Transfer name moves forall (rmod of nref) if (lay_lastfigelem(nfig)==0) { // Transform rel. to abs. position asin=sin(mirr ? -ang : ang); acos=cos(mirr ? -ang : ang); btx=acos*(rmod.X-macro.MNX)- asin*(rmod.Y-macro.MNY); bty=asin*(rmod.X-macro.MNX)+ acos*(rmod.Y-macro.MNY); bty= mirr ? (-bty) : bty ; tmirr= (rmod.MIRROR!=0)!=(mirr!=0) ? 1 : 0 ; tang=rmod.ANGLE; tang+=tmirr ? -ang : ang ; // Store the text position ged_attachtextpos(nfig,rmod.STR, rmod.LAYER,x+btx+xoff, y+bty+yoff,tang,rmod.SIZE,tmirr); } } break; // Via case L_FIGUREF : // Get the macro name macroname=fig.UREF.MACRO.NAME; // Check if macro found if (macroname=="") error(ERRCREATE); // Get via position x=fig.X; y=fig.Y; ang=fig.ANGLE; mirr=fig.MIRROR; layer=fig.LAYER; // Loop for all matrix elements for (i=0;i=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } break; // Text case L_FIGTEXT : // Get the text string textstr=fig.NAME; // Check if text string found if (textstr=="") continue; // Get text placement data x=fig.X; y=fig.Y; ang=fig.ANGLE; size=fig.SIZE; layer=fig.LAYER; mirr=fig.MIRROR|(fig.TEXT.MODE&TEXTEMSK); // Loop for all matrix elements for (i=0;i=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } break; // Drill case L_FIGDRILL : // Get drill position x=fig.X; y=fig.Y; size=fig.SIZE; layer=fig.LAYER; // Loop for all matrix elements for (i=0;i=0 && lay_lastfigelem(nfig)==0) // Get rules if (rs_getfigrules(fig,rl)>0) // Attach rules if (lay_rulefigatt(nfig,rl)) rs_error(-1); } break; } } if (!first) { // Get source range gw=gux-glx; gh=guy-gly; // Calculate destination range if (ystep>0.0) guy=gly+((grpycnt==1 ? grpxcnt : grpycnt)-1)*ystep+gh; else gly=guy+((grpycnt==1 ? grpxcnt : grpycnt)-1)*ystep-gh; if (xstep>0.0) gux=glx+((grpxcnt==1 ? grpycnt : grpxcnt)-1)*xstep+gw; else glx=gux+((grpxcnt==1 ? grpycnt : grpxcnt)-1)*xstep-gw; // Ensure group destination range display winadjust(glx,gly,gux,guy); } // Return without errors bae_prtdialog(REPDONE); } static string getblockpref(string name,string suffix) /* // Block name prefix scan function // Return value : // Block name prefix or empty string if not a block name // Parameters : // string name : Part name // string suffix : Part name suffix return */ { string res /* Result buffer */; char c /* Character buffer */; int sidx /* Scan index */; if (name[0]!='[' || name[1]!='p') return(""); res="[p"; for (sidx=2;(c=name[sidx])!='\0';sidx++) { res[sidx]=c; if (!isdigit(c)) break; } if (c!=']') return(""); sidx++; res[sidx]='\0'; suffix=strextract(name,sidx,strlen(name)); return(res); } static string getpartblock(index L_CPART cpart) /* // Get block name of given connection part // Return value : // Block name or empty string if not a block part // Parameters : // index L_CPART cpart : Connection part index */ { index L_ATTRIBUTE att /* Attribute index */; // Search block name forall (att of cpart where att.NAME=="$blkname") return(att.VALUE); // No block name found return(""); } /*________________________________________________________________*/ // Group load routines static void grouploadhierless() /* // Group Load without Hierarchy */ { index L_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(5, UPRCLLAY,UPRCLLPRT,UPRCLLSTK,UPRCLLPAD,UPRABORT)) { /* Layout */ case 0 : grpeclass=DDBCLLAY; break; /* Part */ case 1 : grpeclass=DDBCLLPRT; break; /* Stack */ case 2 : grpeclass=DDBCLLSTK; break; /* Pad */ case 3 : grpeclass=DDBCLLPAD; 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_planwsnx(),x,y,0)) error_abort(); // Load the symbol macro if (lay_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 (lay_scanpool(pool,-x,-y,0.0,1,1, lmacfunc,lpolyfunc,lpathfunc,ltextfunc,NULL,NULL,NULL)!=0) { // Release the macro element lay_macrelease(pool); error_scan(); } // Release the macro element lay_macrelease(pool); } static int lmacfunc(index L_MACRO macro,index L_POOL pool, int macinws,string refname,index L_LEVEL level) /* // Via macro scan function // Return value : // zero if scan abort or 1 if scan continue // Parameters : // index L_MACRO macro : Macro index // index L_POOL pool : Macro pool element index // int macinws : Macro in workspace flag // string refname : Macro reference name // index L_LEVEL level : Macro level */ { double x,y /* Pad coordinates */; double ang /* Pad angle */; int mirr /* Pad mirror flag */; int layer /* Pad layer offset */; // Continue scan if not via padstack if (VIAHIERL==0 || macro.CLASS!=DDBCLLSTK || refname!="" || ddbclass==DDBCLLPAD) return(1); // Get via placement data lay_maccoords(x,y,ang,mirr,layer); // Store via if (ged_storeuref(macro.NAME,x,y,ang,layer,mirr)) error(ERRPATH); // Abort scan return(0); } static int lpolyfunc(index L_POOL polyp,int layer, int polyinws,int tree,index L_LEVEL level) /* // Store an already transformed polygon data block // Return value : // zero if done or (-1) on file error // Parameters : // index L_POOL polyp : Polygon pool index // int layer : Polygon layer // int polyinws : Poly in workspace flag // int tree : Polygon tree number // index L_LEVEL level : Polygon level */ { index L_CNET cnet /* Connection list index */; index L_POLY poly /* Polygon index */; index L_POINT point /* Polygon point */; index L_FIGURE fig /* Figure list index */; STRINGS rl /* Rule list */; string treename /* Polygon tree name */; // Store the polygon points bae_clearpoints(); poly=polyp.POLY; forall (point of poly) bae_storepoint(point.X,point.Y,point.TYP); treename= lay_gettreeidx(tree,cnet)==0 ? cnet.NAME : "" ; // Store the polygon ged_storepoly(layer,poly.TYP,treename,poly.MVIS&0x13); // Select new polygon to group if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); if (lay_lastfigelem(fig)==0) if (rs_getpoolrules(polyp,rl)>0) // Attach rules if (lay_rulefigatt(fig,rl)) rs_error(-1); // Return without errors return(0); } static int lpathfunc(index L_POOL pathp, int layer,int pathinws,index L_LEVEL level) /* // Store an already transformed path data block // Return value : // zero if done or (-1) on file error // Parameters : // index L_POOL pathp : Path // int layer : Path layer // int pathinws : Path in workspace flag // index L_LEVEL level : Path level */ { index L_LINE path /* Path index */; index L_POINT point /* Path point */; index L_FIGURE fig /* Figure list index */; STRINGS rl /* Rule list */; // Store the trace bae_clearpoints(); path=pathp.LINE; forall (point of path) bae_storepoint(point.X,point.Y,point.TYP); ged_storepath(layer,path.WIDTH); // Select new trace to group if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); if (lay_lastfigelem(fig)==0) if (rs_getpoolrules(pathp,rl)>0) // Attach rules if (lay_rulefigatt(fig,rl)) rs_error(-1); // Return without errors return(0); } static int ltextfunc(index L_POOL 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 L_POOL textp : Text pool 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 L_FIGURE fig /* Figure list index */; STRINGS rl /* Rule list */; double lx, ly /* Text line vector coordinates */; double flen /* Text frame length */; double vx,vy /* Text angle vector */; // Check if horizontal center vector back translation if (textp.TEXT.MODE&TEXTHCENT) { // Get the text correction length flen=0.5*tsize*FONTASP*strlen(tstr); // Get the text angle vector vx=cos(tangle); vy=sin(tangle); // Get the corrected text coordinates tx+=vx*flen; ty+=vy*flen; } // Check if vertical center vector back translation if (textp.TEXT.MODE&TEXTVCENT) { // Get the text correction length flen=0.5*tsize; // Get the text angle vector vx=cos(tangle); vy=sin(tangle); // Get the corrected text coordinates tx-=vy*flen; ty+=vx*flen; } // Check if attribute line display if (lay_getsctextdest(lx,ly)==1) { // Store the line polygon points bae_clearpoints(); bae_storepoint(tx,ty,0); bae_storepoint(lx,ly,0); // Store the polygon ged_storepoly(layer,L_POLYDOCLINE,"",0); } // Store the text ged_storetext(tstr,tx,ty,tangle,tsize,layer, mirrflag|(textp.TEXT.MODE&TEXTEMSK)); // Select new text to group if (lay_lastfigelem(fig)==0) ged_elemgrpchg(fig,1); if (lay_lastfigelem(fig)==0) if (rs_getpoolrules(textp,rl)>0) // Attach rules if (lay_rulefigatt(fig,rl)) rs_error(-1); // Return without errors return(0); } // Scan functions static int viamac(index L_MACRO macro,index L_POOL pool, int macinws,string refname,index L_LEVEL level) /* // Via macro scan function // Return value : // zero if scan abort or 1 if scan continue // Parameters : // index L_MACRO macro : Macro index // index L_POOL pool : Macro pool element index // int macinws : Macro in workspace flag // string refname : Macro reference name // index L_LEVEL level : Macro level */ { // Abort scan if not padstack if (macro.CLASS!=DDBCLLSTK) 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 L_POLY poly,int layer, int polyinws,int tree,index L_LEVEL level) /* // Polygon scan function; generates polygon point list // Return value : // zero if done or (-1) on error // Parameters : // index L_POLY poly : Polygon data // int layer : Polygon layer // int polyinws : Polygon in workspace flag // int tree : Polygon level // index L_LEVEL level : Polygon level */ { index L_POINT point /* Polygon point index */; index L_CNET net /* Connection list index */; // Reset point count ppcnt=0; // Check if hatched copper outline if (poly.TYP==L_POLYHTCHCOP) return(0); // Check if board outline if (poly.TYP==L_POLYBRDOUT && brdaltlay==LAYERINV) 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++; } // Check if transformed board outline if (poly.TYP==L_POLYBRDOUT) { pplist[ppcnt]=pplist[0]; ppcnt++; polytyp=L_POLYDOCLINE; } else { polytyp=poly.TYP; } // Store polygon data if (lay_gettreeidx(poly.TREE,net)) polytreename=""; else polytreename=net.NAME; // Return without errors return(0); } static int pathfunc( index L_LINE path,int layer,int pathinws,index L_LEVEL level) /* // Path scan function. Generates path point list // Return value : // zero if done or (-1) on error // Parameters : // index L_LINE path : Path data // int layer : Path layer // int pathinws : Path in workspace flag // index L_LEVEL level : Path level */ { index L_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 int pathlfunc( index L_LINE path,int layer,int pathinws,index L_LEVEL level) /* // Path level scan function. Generates path point list // Return value : // zero if done or (-1) on error // Parameters : // index L_LINE path : Path data // int layer : Path layer // int pathinws : Path in workspace flag // index L_LEVEL level : Path level */ { // Store path level plevel=level; // Return without errors return(0); } static void groupscan() /* // Scan group element types */ { index L_FIGURE fig /* Figure list index */; // Avoid double group scan if (grpscan) return; // Count group elements forall (fig where fig.GROUP) grpelemn++; if (grpelemn!=0) { forall (fig where fig.GROUP && fig.TYP==L_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); } } /*________________________________________________________________*/ // Group message system functions static void groupselscmsymbols() /* // Select the corresponding schematic symbols for group selected parts */ { index L_FIGURE fig /* Figure list index */; string msg /* Message string */; // Build the selection request message sprintf(msg,"%d",MSGID_SELPGRP); forall (fig where fig.TYP==L_FIGNREF && fig.GROUP) // Build the selection request message msg+=" "+fig.NAME; // Send the selection request message bae_sendmsg(msg,1); } /*________________________________________________________________*/ // Group report functions static void groupreport() /* // Display group elements statistic */ { index L_FIGURE fig /* Figure list index */; STRINGS msgl /* Message list */; int msgn = 0 /* Message count */; string msg /* Message string */; int cnt = 0 /* Group element count */; int maxlay = DOCLAYBASE+DOCLAYMAX*DOCLAYSHIFT+DOCSIDEMAX /* Max. Layer index */; int polycnt[] /* Polygon element counts */; int partcnt = 0 /* Part count */; int textcnt = 0 /* Text count */; int trccnt = 0 /* Trace count */; int viacnt = 0 /* Via count */; struct statdes { // Element statistic descriptor int polycnt /* Polygon element count */; int textcnt /* Text count */; int trccnt /* Trace count */; int totcnt /* Total element count */; } layel[] /* Layer element statistic array */; int layidx /* Layer index */; int i /* Loop control variable */; for (i=1;i<=L_POLYMAX;i++) polycnt[i]=0; for (i=0;i=maxlay) break; layel[layidx].textcnt++; layel[layidx].totcnt++; break; case L_FIGPATH : trccnt++; if ((layidx=fig.LAYER+5)<0 || layidx>=maxlay) break; layel[layidx].trccnt++; layel[layidx].totcnt++; break; case L_FIGPOLY : polycnt[fig.POLY.TYP]++; if ((layidx=fig.LAYER+5)<0 || layidx>=maxlay) break; layel[layidx].polycnt++; layel[layidx].totcnt++; break; } cnt++; } sprintf(msgl[0],bae_plainmenutext(UPRFCT19),cnt); msgl[1]=" "; sprintf(msgl[2],REPGRPCNT,cnt); msgl[3]=" "; msgn=4; if (partcnt!=0) { sprintf(msgl[msgn], ddbclass==DDBCLLAY ? REPPARTCNT : REPPINCNT,partcnt); msgn++; } if (trccnt!=0) { sprintf(msgl[msgn],REPPATHCNT,trccnt); msgn++; } if (viacnt!=0) { sprintf(msgl[msgn],REPVIACNT,viacnt); msgn++; } if (textcnt!=0) { sprintf(msgl[msgn],REPTEXTCNT,textcnt); msgn++; } for (i=0;i