It looks like you're new here. If you want to get involved, click one of these buttons!
Hi,
When I run the following script that I wrote, any boxes on layer2 are subtracted from any overlapping boxes on layer1. However the boxes have to all be in the same cell.
module BoxBoxSubtract
app = RBA::Application.instance
mw = app.main_window
lv = mw.current_view
if lv == nil
raise "No view selected"
end
lv.transaction("Box box subtract")
begin
# put code here
outerboxes=[] #layer 401
innerboxes=[] #layer 400
result_cell=[]
result_layer=[]
lv.each_object_selected do |obj|
shape = obj.shape
layout = lv.cellview(obj.cv_index).layout
lnum = 1 # GDS Layer 1
dtnum = 0
outerbox_layer = layout.layer_indices.find do |li|
info = layout.get_info(li)
info.layer == lnum && info.datatype == dtnum
end
lnum = 2 # GDS Layer 2
dtnum = 0
innerbox_layer = layout.layer_indices.find do |li|
info = layout.get_info(li)
info.layer == lnum && info.datatype == dtnum
end
lnum = 3 # GDS Layer 3
dtnum = 0
result_layer = layout.layer_indices.find do |li|
info = layout.get_info(li)
info.layer == lnum && info.datatype == dtnum
end
if shape.is_box? && obj.layer == outerbox_layer
# add it to the array
outerboxes << obj
# save a reference to the cell it's on, as this is the one we'll write our result on
result_cell = layout.cell(obj.cell_index)
elsif shape.is_box? && obj.layer == innerbox_layer
# add it to the array
innerboxes << obj
end
end
test1 = []
test2 = []
outerboxes.each do |b|
test1 << RBA::Polygon::new(b.shape.box)
end
innerboxes.each do |b|
test2 << RBA::Polygon::new(b.shape.box)
end
ep = RBA::EdgeProcessor::new
outerMinusInner = ep.boolean_p2p( test1 , test2 , RBA::EdgeProcessor::ModeANotB, false, false)
outerMinusInner.each do |p|
result_cell.shapes(result_layer).insert(p)
end
p 'Done'
ensure
lv.commit
end
end
Now I need to extend that to operate over multiple cells.
Imagine in the most general case I have three cells: "top", "child1", "child2".
On "child1" there is a large box.
On "child2" there is a small box.
On "top", child1 and child2 are instanced, overlapping each other.
When I instance multiple instances of child2 (multiple small boxes on top of one big box), I want the result to be the big boxes minus ALL the small boxes.
Any ideas how to access those cells? I tried duplicating all small boxes onto result_layer first, then doing the boolean subtraction. (Basically, replace
# add it to the array
innerboxes << obj
with
# add it to the array
new_shape = obj.shape.dup
result_cell.shapes(innerbox_layer).insert(new_shape)
innerboxes << new_shape
HOWEVER, this only seems to duplicate one box over to result_cell, not all instanced boxes in their relative positions; and besides it is strange -- the duplicated cell does not show up at the same xy location as the original instanced cell! I guess I need to find the xy location of the instanced cells, then duplicate onto result_cell and place them to exactly fall on top of their original instances. But have searched and cannot seem to find a way to get the xy location of the instance!
Hope that is clear. Any ideas? Thanks!
Comments
Hi David,
again, please be patient. I'll need some days to comment on this. Acually I am on vacation and my laptop's battery is running low ... :-)
Matthias
Hi David,
it's basically quite simple - you have to apply the relevant transformations. It's easy if you choose to output the results to the current cell, because then the transformation is readily available through ObjectInstPath#trans as a CplxTrans object. In order to stay within integer coordinates we have to create a ICplxTrans object thereof:
(BTW: I'd suggest to take the layer search out of the each_object_selected loop. Plus I have used Shape#polygon which is more generic than using Shape#box and creating a polygon from that box).
The above code does not account for the case of multiple loaded layouts. Basically the two kind of shapes can reside in different layouts then. The corresponding extension is possible but adds a lot of special case handling and additional transformations because of potentially different database units to that code.
Matthias
Fantastic, thanks! I didn't understand about this transformation meant before. The code is working and I paste final code below for future reference of anyone reading this. It may not be the most efficient or best code but it works..
hello David, I am not familiar to script, but I suffered similar problem. if I have child1 and child2 are polygon, i dont need transformed_cplx. Is it correct?
I don't think it makes sense to do this operation box by box. You could do it but then first you have to transform all the shapes up to a common top cell which is more work. Instead do a Boolean "not" operation on the shapes of two layers. In Python something like:
The resulting shapes are in layer3, as polygons. See the docs for kl.ShapeProcessor().
I'd like to point out that the original post is almost ten years old
Today there is the DRC functionality for which this problem boils down to a layer generation operation. If you use deep mode, hierarchy is preserved as far as possible. So the following two-liner may do the job:
DRC is very powerful - you can do implement more layer generation logic there.
Matthias