Introduction
Screenshots
License
Download
Userinterface
Function Index
White Papers
Community
Contact


no help |  | Macro Programming: groupSimple() return value ? by Toby Mangold - 9 Jul 2009, 16:08 CEST
Hi Jürgen,
at the moment I'm trying to set up a macro, which performs a multi-layer merge operation based on the boolean OR operation similar to the intrinsic merge command (is the merge working correclty in the latest release ? ... anyway ...)
Is there a protected, tmp working layer (e.g. 256) accessible from a macro, which will never contain elements ? At the moment I'm simply scanning for an invisible one starting from the back, 255. Is it possible to search for a disabled one from within a macro ?
One of my basic problems is related to the layout->drawing->groupSimple() command, which I need to put the current selection of elements subject to the merge operation into a temporary cell. (boolen APlusB cannot be called on a subgroup of the current selection without lossing the selection, right ?) Now, how do I get a handle to the newly created cell ? There's no return value for groupSimple().
My current workaround walks to the end of the global cell list assuming any cell addition will go to the end of the list. It seems to work, but is this assumption valid in any case ?
There are a lot of performance issues with the macro partly due to the lack of array variables for caching. But the biggest issue at the moment is a layout.exe crash after I've added the boolean AplusB operations and cleanup. I'm still debugging and wondering weather this macro will run on the latest GPL release to double check for any layout.exe errors in my old 2008 GPL release .
Any comments or suggeststions in general which might help debugging or performance ? Any kind of help is really appreciated.
Regards, Toby
#!/usr/bin/layout #name=boolean-merge #help=performs a merge of selected elements (no cells) based on boolean tools
int main(){ int l; int tmplay=255; cell *myCell= layout->drawing->currentCell; cell *myTmpCell; string tmpA; string tmpB; cellList *lastCellEntry= layout->drawing->firstCell; elementList *myElemL; # we don't want to include any selected cells layout->drawing->cDeselect();
# first of all, turn on all layers including selected elements myElemL=myCell->firstElement; while(myElemL!=NULL){ if(myElemL->thisElement!=NULL){ layers::num[myElemL->thisElement->layerNum].visible=true; } myElemL=myElemL->nextElement; } # try to find a non-visble, unused working layer while(layers::num[tmplay].visible && ( tmplay > 0) ) { tmplay--; } if ( (tmplay == 0) && layers::num[tmplay].visible ) { layout->showMessage("ERROR","Cannot find an invisible working layer"); return; } #DEBUG #layout->showMessage("working layer is","ID="+tmplay); # grouping all elements we'd like to merge layout->drawing->groupSimple(); layout->drawing->deselectAll(); # find last cell while(lastCellEntry->nextCell != NULL) { lastCellEntry=lastCellEntry->nextCell ; } # focus to newly added cell and flatten #layout->drawing->setCell(lastCellEntry->thisCell->cellName); layout->drawing->currentCell=lastCellEntry->thisCell; #DEBUG #layout->showMessage("temp. working cell is",lastCellEntry->thisCell->cellName); lastCellEntry->thisCell->selectAll(); lastCellEntry->thisCell->flatSelect(); # Since the temp. cell contains only elements on visible layers, # there's no need to clean the working layer. It has to be empty. lastCellEntry->thisCell->deselectAll(); for (l=0;l<255;l++){ if (layers::num[l].visible){ # merge this visible layer # layout->drawing->deselectAll(); layout->drawing->activeLayer=l; layout->drawing->selectActiveLayer(); # How to check for the number of selected elements to conditionally skip the boolean operation ? layout->drawing->currentCell->moveToLayerSelect(tmplay); # boolean merge operation; layout->booleanTool->setA(); # setA will deselect() layout->booleanTool->setB(); layout->booleanTool->APlusB(); } } # Done with merge operations #DEBUG #layout->showMessage("DEBUG","done with merge");
#DEBUG #layout->showMessage("DEBUG","go"); # need to find the cellref of my tmp. cell, which has been created by groupSimple() myElemL=myCell->firstElement; #DEBUG #layout->showMessage("DEBUG","go2"); # Is there some way to break out of the while-loop without lossing info # about the ciurrent element ? No ? ... for the moment we have to stick # with a tmp flag pointer. myTmpCell=NULL; #DEBUG #layout->showMessage("DEBUG","go3"); while( (myElemL !=NULL) && (myTmpCell==NULL)){ if(myElemL->thisElement!=NULL){ if(myElemL->thisElement->isCellref()){ myTmpCell=myElemL->thisElement->depend(); if( myTmpCell->cellName != lastCellEntry->thisCell->cellName ){ myTmpCell=NULL; myElemL=myElemL->nextElement; } #DEBUG #layout->showMessage("DEBUG","yes"); # keep myTmpCell, don't increment and exit loop } else { myElemL=myElemL->nextElement; } } } #DEBUG #layout->showMessage("scan for cellref returned",myTmpCell->cellName); if(myElemL->thisElement == NULL){ layout->showMessage("ERROR","cannot find automatically placed cellref ... strange ...."); return; } myElemL->thisElement->selectAll(); myCell->flatSelect();
#DEBUG #layout->showMessage("DEBUG","cellref removed"); layout->drawing->currentCell=lastCellEntry->thisCell; #layout->drawing->setCell(lastCellEntry->thisCell->cellName); layout->drawing->deleteActuellCell(); layout->drawing->currentCell=myCell; #layout->drawing->setCell(myCell->cellName); #DEBUG #layout->showMessage("DEBUG","finished"); }
by Juergen Thies - 9 Jul 2009, 18:37 CEST
This macro should do want you want:
#!/usr/bin/layout #name=boolean-merge #help=performs a merge of selected elements (no cells) based on boolean tools
int unusedLayer(){ layers::hideUnusedLayers(layout->drawing); int i,k=0; for (i=0;i<=255;i++) if (layers::num[i].visible==false) k=i; return k; }
int main(){ drawingField *d=layout->drawing; cell *tempCell=d->addCell()->thisCell; tempCell->cellName = "~myTempCell"; string cc=d->currentCell->cellName; d->cDeselect(); d->currentCell->group(tempCell); d->setCell("~myTempCell"); d->activeLayer=unusedLayer(); d->selectAll(); layout->booleanTool->setA(); layout->booleanTool->setB(); d->setCell(cc); layout->booleanTool->aPlusB(); d->setCell("~myTempCell"); d->deleteActuellCell(); d->setCell(cc); layers::hideUnusedLayers(layout->drawing); }
Some comments to your questions: - the merge command is aPlusB (not APlusB), the error message for that error was missing in the LayoutEditor. - internal pointers like currentCell, firstcell are write protected, use setCell() instead. - after groupSimple the new cell is always in firstCell->thisCell, cellname is noname_+unused number. - in a boolean operation you can use multiply setA or setting multi layers in one operation, - the boolean operation can be performed in an other cell than the source cell, - the merge operation uses the same merge algorithm than the boolean tool, but will respect layers and will merge path elements different. In result the merge feature has a lower performance than the boolean tool. by Toby Mangold - 10 Jul 2009, 10:18 CEST
Hi Jürgen,
Thanks a lot for all your comments and your macros. But I've to dissapoint you: I cannot test it, because the demo version of the latest download binaries seems to have expired, and the gpl version doesn't allow to run macros.
Furthermore, I cannot run it on the older sep 2008 gpl release, because hideUnusedLayers() isn't available there.
I'm going to try porting it back to a 2008 gpl release merging your suggestions into my own macro code. Are there any additional features used in your code, which are missing in the sep 2008 GPL version ? Maybe I simply add the hideUnusedLayers() funciton to the code. I'm using a patched branch of the GPL code anyway (e.g. I've added an optional auto-enable of layers during file open/import). Wel'll see ...
Regarding the merge feature: Did you improve it a lot in 2009 ? I've a very basic test file which gives very strange/poor results for all 2008 releases I'm able to check. Could you please check the file or provide me a working demo version to test it on my own ?
(Since I canot attach data in this form, I've open a bug report on sourceforge and added the file there: ID: 2819440 , https://sourceforge.net/tracker/?func=detail&aid=2819440&group_id=121668&atid=691076)
Now, let's go try to backport your macro.
Regards, Toby by Juergen Thies - 10 Jul 2009, 10:43 CEST
To the merge feature: Since the 2008 release i have change the algorithm for it. Now the same algorithm than for the boolean operations is used. This algorithm works more reliable than the old one.
Since the 2008 version more than 400 fixes and new feature have been added. Quite a lot of it affect the macro interface. (any new feature, some smaler bugs in the macro parsing, ...)
I will send you a evaluation license key, so you can test it on the newest release.
by Toby Mangold - 10 Jul 2009, 13:00 CEST
Thanks for getting me an eval license key.
Meanwhile it's working. The real basic problem was the layer_max in my old 2008 binary. 128!=256. This caused a lot of trouble. I was able to strip down a lot thanks to your tips. Make use of boolean tools working across cells made a big difference (no need for temp. layer). Further, I wish I had been aware of the fact that deleteActuellCell() automatically removes any cellrefs, too.
Now, here's the final macro:
#!/usr/bin/layout #name=boolean-merge #help=performs a layer-by-layer merge of selected elements (no cells) based on boolean tools
int main(){ int l; drawingField *d=layout->drawing; cell *myCell= d->currentCell; cell *myTmpCell; elementList *myElemL; # we don't want to include any selected cells d->cDeselect();
# first of all, turn on all layers including a selected element myElemL=myCell->firstElement; while(myElemL!=NULL){ if(myElemL->thisElement!=NULL){ layers::num[myElemL->thisElement->layerNum].visible=true; } myElemL=myElemL->nextElement; } # grouping all elements we'd like to merge cell *myTmpCell=d->addCell()->thisCell; myTmpCell->cellName = "~boolean-merge-tmp"; myCell->group(myTmpCell); myTmpCell->deselectAll(); for (l=0;l<256;l++){ if (layers::num[l].visible ){ # merge this active layer back to the original cell d->activeLayer=l; # focus to newly added cell, otherwise either myTmpCell->selectLayer(l) or booleanTool->setA() cause trouble ... I don't care d->setCell(myTmpCell->cellName); d->selectActiveLayer(); layout->booleanTool->setA(); layout->booleanTool->setB(); d->setCell(myCell->cellName); layout->booleanTool->aPlusB(); } } d->setCell(myTmpCell->cellName); d->deleteActuellCell(); d->setCell(myCell->cellName); }
Please log in to post! The LayoutEditor™ is a program to design and edit layouts for MEMS/IC fabrication and CMOS IC design .Designing these layouts require a high precision. In IC design a sufficient resolution and a possibility of a high scaling is required. The resolution of the LayoutEditor can be set in a wide range and is normally set to 1 nano meter. A higher resolution makes no sense due to atomar structures. With this resolution the LayoutEditor can draw elements up to 4 meters. In many IC design houses this is enough for IC/MEMS which extend usually less than 0.1 meters.
The productions of MEMS/IC is done in many layers. For each of these physical CAD layers a belonging layer had to exist in the drawing. Additional logical layers are required for describing/naming purpose. So a lot of layers are needed. By default the LayoutEditor is limited to 128 layers. But it can easily be adjusted, if more layers are required.
IC Designs often contain a plenty of repeating structures. Essential for micro fabrication of these designs is therefor a hierarchical design. This means, that the complete repeating structure only exists once in a single cell. These cell is then referred multiple times in the main drawing.
Beside the above mems packaging mentioned IC design fundaments it is important to have sophisticated functions to handle all drawing elements. The layout handler has all required functions: all basic design functions, all angle elements, boolean operations, macros, fontgenerator, design rule checker, mems tools, supported format: GDSII, DXF, OASIS, CIF. If you still missing a function, you are free to write a feature request
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |  |

|