Select all objects visible in the current view

edited July 2015 in Ruby Scripting
Hello,

I am stuck looking over the documentation, but I cannot seem to find a simple way to select all objects currently visible in the view? I want to adjust the total area calculation script without having to select the objects by hand. In fact, I want to be able to select the objects in the current view do some analysis on them, then pan, repeat the analysis and so on. Panning and object analysis seem to be pretty straight forward, but how can I select all the objects visible in the view right now?

Thanks!
Alex

Comments

  • edited July 2015

    Alex,

    Matthias probably has some good idea to help solve your problem, but in case it helps:

    There isn't really a straightforward way to 'select' and then act on selected objects via RBA. I struggled with this idea too when I started, because I wanted RBA to act just like I as the user would act -- I would show certain shapes, then select them with the mouse, then do some action.

    I think instead, a better model of how to interact with objects via RBA is to write some logic that chooses object references and then acts on them (rather than choosing them by actually selecting them as if you had clicked them).

    This is actually just as limitless.

    For example you could choose all shapes in the layout, or all shapes on a certain layer, or all shapes within cell "CELL_NAME" on a certain layer, or all shapes with valid layers, or all shapes with invalid layers, or whatever.

    So for example if you wanted all shapes that are both in cell "CELL_NAME" and drawn on layer 1 to change to layer 2, you might do:

    include RBA
    app = Application.instance
    mw = app.main_window
    lv = mw.current_view
    ly = lv.active_cellview.layout
    
    cell = ly.cell("CELL_NAME")
    
    from_li = ly.layer(1,0)
    to_li   = ly.layer(2,0)
    
    cell.each_shape(from_li) { |shape|
      shape.layer = to_li
    }
    

    However, if after all that explanation you still really want to select things via script, you could use a hack like this:

    include RBA
    app = Application.instance
    mw = app.main_window
    
    menu = mw.menu    
    menu.action("edit_menu.select_menu.select_all").trigger
    
    lv = mw.current_view
    lv.each_object_selected { |obj|
      p obj
    }
    

    This is just a hack. And of course this selects all objects even those outside the viewport, which is not wha tyou want.

    But as I said above I don't think what you want is the usual way of accomplishing the task with RBA and there are probably alternatives available to you.

    Tell us more about what action you want to apply, and we can help you select the shape references via RBA without ever actually doing a GUI-like 'select' action.

    David

  • edited November -1
    Hi David,

    Wow, awesome! Thanks for such a blazing fast reply!

    I get what you say: scripting ought to have a different mentality than GUI interaction. It is probably my lack of knowledge about RBA that limits me here, but let me explain briefly what I want to do and what I was thinking could be a way to actually do it.

    Problem: I have a GDS file that has some layers of interest. All those layers can be sort-of flattened (merged maybe?) and that is where the fun begins. The entire GDS file describes a pretty large area, and I want to section it out into a grid-like matrix (here I though each cell of the matrix would be my current view). For each cell on the grid I want to grab all the objects within the cell and do some calculation on their shapes, export their 'look' as a PNG, etc. That's about it.

    My solution: I can manually zoom so that my current view represents one cell of the grid. Then I can use the pan commands to move across that grid. I could also adapt the screen shot script to grab the 'look' of the GDS and export that as a PNG. What I am missing is how to choose the objects within my grid-cell to do a calculation on their shapes?

    Do you think it could be possible to figure out the boundaries of my current view, then select all the objects in all the visible layers and go through them throwing out all the objects that are outside the boundaries of the current view? That would then leave me with just those objects that are in fact visible in the current view.

    Thank you so much for the explanation and all your help!
    Alex.
  • edited July 2015

    Hi Alex,

    I believe you can do this with 'clips' which are available via script (and also via GUI).

    I actually haven't used clips before, and don't have time to try in the next couple of days due to other commitments, but you can start to take a look.

    Regarding the scripted version: here are some discussions, and here is the class you want (scroll to clip, clip_into, multi_clip, multi_clip_into)

    Regarding the GUI version: It's in Edit > Utilities > Clip tool, and it's doc is here: http://www.klayout.de/doc/manual/clip.html

    You would probably make a clip from some rectangular region, then automate a screenshot on just that clip. Then repeat.

    David

  • edited November -1

    Hi all,

    thanks for that interesting discussion!

    Maybe "density maps" are what you are looking for. Here is an interesting discussion regarding that: http://klayout.de/forum/comments.php?DiscussionID=476.

    Matthias

  • edited July 2015
    Hi David, Matthias,

    I have not had that much success with the clip tool, I will give it another try though. The density map is approach is also nice, but... here is my problem:

    My GDS is huge... very big. In fact, I cannot even select all the items in the GDS because I run out of memory. But I can do all the operation I need if I zoom in close enough. That is my thinking: zoom in and attack it one small bit at a time. Only I need to automate it.

    Coincidentally, I saw this method QItemSelection() in documentation, do you know if I could possible use it to construct a selection on a given region?

    Thanks!
    Alex.
  • edited July 2015

    Hi Alex,

    The density map approach is based on the TilingProcessor class which has been created exactly for these kind of applications.

    Basically, KLayout can load really huge layouts. But for processing them, advanced algorithms are required. The tiling processor provides such an algorithm. It can be used for local operations. These are operations where the output can be derived from a clip of the layout. The tiling processor provides a generic and scalable approach.

    You basically need to supply the following information

    • Where to take the data from
    • What to do with the data
    • Where to put the results to

    The tiling processor then will divide the layout or a specified part of that into an array of rectangular regions of configurable size ("tiles") and performs the requested operation on them. The tiling processor can be configured to include a margin when deriving the regions, so you can work with the neighbourhood of the region as well.

    A useful feature of the tiling processor is the ability to distribute the tiles on multiple cores.

    After all, it's the right tool to do processing on huge layouts. Have a look at the documentation provided and the density map sample. That should give enough information for a start.

    Matthias

    BTW: "QItemSelection" is something entirely different. It's provided by the Qt library.

  • edited November -1
    Hi Matthias,

    I think I am starting to understand why tiling is the way to go. Let me give it a try based on your density map sample.

    Thanks!!
    Alex.
Sign In or Register to comment.