It looks like you're new here. If you want to get involved, click one of these buttons!

Hi sir,

I have some question about rounded_corners function .

here is my code below....

```
customer_psv_layer=input(86,0)
outter_corner=10
inner_corner=2
shrink_value=10
customer_psv_layer.sized(-shrink_value.um).rounded_corners(inner_corner.um,outter_corner.um,100).output(50,5)
```

and here is what the pattern we have , you can check with the attatched also.

after this script running , that is result and it is what the question do I meantion.

As you can see , most outter corner can usnig the round corner value to do trim/cut corner and base on the value do I provided.

I knew that , some of shape didn't have enought size to make the round corner base on that value .

Look like them still been make round corner , but the key is....what the value of round corner is?

Can I control that or can I measure that ?

please help it , Thanks.

## Comments

Hi jiunnweiyeh

There's a limitation for corner rounding radius, like you mensioned, if the size is smaller then the rounded value, the result will not be matched.

And

`round_corner`

cannot recognize chamfered corners, the two coner of this chamfered edge wil be rounded separately so the 45deg slant edge (side-1 in following image) needs to be long enough for rounding.The maximum rounding that can be applied to a corner is as below, the slant part

`side-1`

is 9.11 um,`d`

is 4.555um, the max radius that can be applied`Max r`

is 10.996 um, which is larger than 10umso if you look closely, you'll see the countour is not a single arc from 10um circle, instead it's form by connecting two arcs.

In cases that

`Max_r`

is smaller than 10um,`Max_r`

will be applied instead of 10umA de-chamfer process can be applied to avoid the rounding limitation issue from chamfered shapes

de-chamfered result, white dash-lines removes chamfering while preserves step like features.

by filter out vertical, horiozontal and slant edges, we can use their relation to narrow down to chamfer corners.

For slant edge that interacted with both H and V edges and with length < cetran length, we preserve them for further process.

Extracting the bound box of chamfer edges automatically generates the patch shapes for the corner

combined with input layer and merge generates the final result.

sizing and rounding can be applied and shoud gives you what you need.

Hi @RawrRanger

Thanks a lot for your help , I will check it and make it into what my code.

Thanks.

If you're in particular interested in the inner corners and the objects you treat are larger than 40µm in dimension, you can also consider using the Minkowski sum with a circle. The Minkowski sum acts like a "pen" that is drawn around the perimeter of the polygon (like illustrated here: https://demonstrations.wolfram.com/TheMinkowskiSumOfADiskAndAPolygon/).

The Minkowski sum is not readily available in DRC, but can be emulated.

The code is that:

Here is the output:

The yellow dashed polygon in the pre-Minkowski layer.

Matthias

Hi @RawrRanger @Matthias

Do you have idea for how to check what the min/max value round_corner done in GDS?

as previsouly mention.if the edge is not long enough for rounding.

After round_corner function , the real value of rounding (as your picture , 10.996um) will not match with what the code we command.

what the code I can "GUESS" would be that...

Using "xor" function to boolean the pattern of "before_round" and "after_round"

But look like the bbox value is not what the answer I need.

Do you have any idea for that to check outter /inner rounding value?

HI jiunnweiyeh,

Basically what following code does is to loop through all shapes and edges to check their angle/length relation

the length / angle relation check basically does what my previous post shows.

the runnung result of your example layout is

`0.0853um`

reason due to there's a small segment in this shapeto avoid this, a threshold should be applied to reject those results that is too small.

Hi RawrRanger ,

sorry for that due to my depiction not accurate to make some gap.

please check with the attached file.

we have 2 layers , 151/11 layer is before round , 151/1 is after round.

I want to check what is the min corner rounding value by inner and outter side.

it is why my previsouly metnion I guess that I need using not or xor function.

But I knew bbox should be not the correct answer , and base on this code , I can't separate the inner/outter value .

This is base on when I am a checker not designer .

Designer will base on this code to make trim/shrink/rounding (that is not final version , I am working for combine your code into mind)

But for Checker , whom have the result GDS 86,0 / 151,1 / 151,11 layers only.

our team need to measure the rouding corner by manual .

This is why/what I ask....

could you please help ?

Thanks.

Hi jiunnweiyeh,

The process can be split into four steps.

(1) Pre-Process oroginal laye to remove chamfers

(2) Feed processed layers to check max inner/outer radius

(3) Apply rounding to layer

(4) compare pre-processed layer to rounded layer and extract rounded part for measurement

The processed gds is as attaehed.

Original layer : L(151/11)

Chamfer patched layer : L(151/12)

Rounded patched layer : L(151/13)

Rounded inner corner layer : L(151/14)

Rounded outer corner layer : L(151/15)

(1) pre processing:basically the exact copy of my previous post, works the same way.

(2) For extracting max radius and (3) apply rounding:similar code, except now we determine the corner type (inner/outer) and find max separately

(4) For extracting rounded region and apply measurement:The arc finding part is like this, first get edges, use extend in/out to form a polygon and merge it

check small length edges, which should be the target end piece pushed out by extended_in

it should have two of them,

`e1`

and`e2`

, finallyget any given point from other edges as`ec`

feed them for annotation measurement

@RawrRanger

After check your code 3 (autoMeasuer(originalLayer, roundedLayer)) that is workable.

Thanks.

Cause code1 /2 should be merged into the code of designer.

for Checker , they should using what the layers in GDS file and check/measure it.

Your code is workable for measure , but can we get the min value for inner / outter corner round ?

Now , I get the measure result in GDS as below figure.

but human (checker) need to check the value by each measure, how can I get the min. vlaue ?

by the way , what the programming command I make corner round is outter by 10um and inner 2um.

as this figure shown , some of measure result is 9.9935...um , I knew that will be gap in measure due to grid .

is that reason?

Hi jiunnweiyeh,

Glad this works, unfortunatelly the annotation (Ruler) cannot provid radius data, so we'll need to implement a fit function.

example as below, this was modified from this source

I can't read math, but the code seems works fine.

by adding this line

after this should generate all radius results.

as to the question of 10.00 um to 9.9935...um mis-match, the source of differences can be :

(1) Fit circle error

(2) Off grid of the layout

(3) The macig from edge extension

The (1) (2) is quite intuitive, the (3) probably makes most of the contribtion to this difference.

because we extend the edges to polygon for easy of operation, and loop through edges and filter our

`e1`

,`e2`

by their length, so they might not always appears in sequence, means either one of these edges could be

`e1`

depends on the shape of the objectthis could leads to situations like this, where

`e1.p1`

is registered, but is not the point that is exactly on it's original edgeand because I kind of just choos a randon point from the polygon, by deviding the edge list in to

`3`

so it might also happens to be points that is on the other side, like the example shows.Hi jiunnweiyeh,

To minimize the error mensioned above, which was caused by measurement point not exactly on the edge,

I've implement a

`pick3Points`

function, which first uses the`cut_point`

of the two side to determine the curved side.Due to the nature of how these two small sides were generated, the cut point will always located at the curved-in side of the arc.

By comparing the distance between

`e1.p1`

/`e1.p2`

and cut_point`cp`

we can properly choose the correct point that is on the actual Arc, the one that is on the far side.Similar approach applies to

`e2`

and`ec`

, the mid point of Arc.With the help of cut_point

`cp`

we can cast a edge from`cp`

and throuth the Arc polygon at a roughly center location.This should always generates two edgs

`ecs`

that intersects the cast edge, by choosing the one that is far away from the`ec`

, we can determine our last point on the Arc polygon.So as image shown, the three

`far`

points can be choosen and feed to circle fittingA slighe improvement, around 1~3 dbu of accuracy is observed using previous test cases

`try.gds`

.Hi @RawrRanger

Thanks very much for your hard work and coding.

it is helpful.

But look like the puts result mix both of inner / outter value.

Do you have any idea for that?

Wow ... @RawrRanger I need to digest this first.

But a brief comment: There is the "Radius Ruler" type. It can measure a radius when you provide three points (clicks):

The measurements are precise only to the actual values which are subject to DBU rounding (1nm in this case).

Matthias

Hi @Matthias

Let me talk you a long story~

totolay , we have 2 function , 1 for designer , 1 for checker.

The first code is for designer

I am working for bumping house , our customer provide what the passivation layer (as picture shown , it is polygon) to us.

we need to do some process like this in our design team ...

After that , finally , when the designer finished a lot modify for the layer 151,12

our check team need to base on the GDSII file Designer provided to check if any DRC or anything wrong.

when that moment , checker only have the GDSII file include what the original layer customer provided (86,0) as my code.

and 151,11 layer (after shrink) and 151,12 (after round corner).(designer make it)

As the previosuly mention , sometimes when the polygon shape didn't have enought length to make chamfer. (10um for outter in this case)

The round_corner function will base on what the real length of shape to make it corner routing .

That is what /reason our checker need to confirm---the real rounding value is not 10um (outter) / 2um (inner) , we have to check what is the min one.

And it is what the code RawrRanger provied .

As what I said , RawrRanger's function is workable , but checker need to know what /where the min. value for inner /outter rounding.

It is hard to check the auto-measure result by human .

I have try to make a array to store circle_interpolation(p1, pc, p2) (follow RawrRanger's code)

Unfortunate , I can't seprater the value by inner / outter....

Can you help it?

Hi jiunnweiyeh,

The round data are stored in

`outerRoundGroup`

and`innerRoundGroup`

respectively, because my previous example group then into a list, so the output results will be mixed together.Extract this part into a separate function

`measureGroup`

which takes a`view`

object (for insert annotation) and group data.this provides measurement results separately for inner/outer rounding.

the rest of the parts stays the same.

Hi @RawrRanger

Here , I combine both of your code to let our checker to easy check the round value and location...

some of case , this code is workable , but some of case I got error message as below

Do you have any idea for how the fixt it?

Hi jiunnweiyeh,

The error message :

`undefined method of 'distance' for nil:NilClass`

Means you are trying to access the

`distance`

attribute of a empty object.This error is caused by function

`def pick3Points(sides, edges)`

the code that causes this error are lines that contains

`cp.distance(XXX)`

, which suggests the point`cp`

is not being generated properly by

`e1.cut_point(e2)`

, the only possible reason for this isthe two edge

`e1`

and`e2`

just happens to be in parellel, and no crossing point is foundfor an ideal Arc shaped object this should not occur.

This revised version will try to diliver less accurate results if the arc is not a ideal shape,

if the value is off by too much then the rest of the rounded corners, you can apply filters to hightlight the area,

Hi @RawrRanger

I have update the code as you provied , and I keep these function cause each function can help us to find the trim value , size , location.

The detail (full coding) please check with the second attached file.

And runing that in the attached 1 , you will get the error message , that been shown as below.

please help it.

Thanks.

Hi jiunnweiyeh,

Thanks for the test case, and regarding to the error of

`undefined method 'x'`

this is due to I for got to access the edge with

`p1`

attribute, the intention here is to return a point from edge instead of returning an edge.the code above has been updated with a correct return

As to how

`undefined method of 'distance' for nil:NilClass`

this issue is triggered, I found the error is related to this shape, the vertex generated by rounding (red) snapped to a grid in a way that the whole edge shift slightly awayfrom original edge (white), which makes this straight line being falsely recognized as an rounded corner, due to I use`edges.select_not_interacting`

to separate rounded Arcs.Hi @RawrRanger

Got the udpate and I will try it ASAP.

Thanks very much for your help.

Hi jiunnweiyeh,

few update about the code, I see you use autoMeasure/autoMeasure2 to process shapes and analyze results separately.

So i've revised this part so it retuens a list of dictionary which contains radius info and collection of points for adding annotation, now this main function is renamed to

`measuerResults`

.Hi @RawrRanger

Thanks , look like that will make a exception caught named "cut_point" .

Hi jiunnweiyeh,

This should be related to edge lengh check part, of

`measureGroup`

`p.each_edge{|e| ((e.length < dbu * 2) ? sides : edges) << e }`

which did not get sufficient amount of edges, results in input value

`e1`

in`pick3Points`

becomse nilIn normal case, this should gurantee at least 2 edge is generated, which was from extend function

`Edges.extended_in(1).merged`

I've checked the result using sample

`try.gds`

and new sample`9999.gds`

, but cannot successfully triggger this exception, a sample of layout that triggers this message will be very helpful.Hi @RawrRanger

I got the answer ,cause some of pattern didn't have "patchedLayer" , so your code is workable .

I just need to add a simple code to filter it .

Thanks very much for your kindly help.

Hi @RawrRanger and @jiunnweiyeh,

your collaboration is amazing ... I really appreciate this, specifically the nice visualizations of @RawrRanger!

I just wanted to come back to @jiunnweiyeh 's comment at Jan 8:

The rules by which the

`round_corner`

functions works are not very elaborate and can be evaluated.Basically, two connecting edges make a circular corner. Three edges form two corners. Here is one with an inner (r1) and outer corner (r2):

This is a well-formed case where the given radii can be implemented. The parts denoted by "s1" and "s2" and their counterparts on the attached edges are converted into circular sections.

However, when

`s1 + s2 == length(E2)`

, E2 is entirely consumed by the circular sections. If`s1 + s2 > length(E2)`

, the circular sections cannot be formed any longer without introducing polygon path inversion - this is something we like to avoid.To avoid this, the radii r1 and r2 are reduced in this case:

In general, each radius will potentially need to be reduced twice: r1 needs to both fit into E2 (together with r2) and E1 (together with the predecessor leftmost r0 which is not shown in the picture).

So the full scheme is that:

So with this knowledge we can basically compute the minimum radius.

Here is some code that performs this evaluation for one selected polygon and two sample radii (inner: 0.5 and outer: 1.0 µm):

The results for this polygon:

Are these:

The minimum values correspond well to the critical situation here, within the limits of measurement accuracy of the radii:

Best regards,

Matthias

P.S: I am aware that the quality of the drawings do NOT match those of @RawrRanger

Hi @Matthias,

Thanks for your code, let me digestion it.

in my side , our design team have another idea for corner rounding by programming.

--Maybe I can check if the shape single-edge size small than rule value (maybe 10.um)

Let the programming process all of other shape for corner_rounding (if the single -edge length > 10um)

The others , let designer to check and process by manufature.

I will check if I can do that or I need your help.

Thanks very much for all your help.

Hi sir ,

Do you have function to check the single-edge length < rule ?

such as ..

look like I have to change polygon layer to a edge layer , but I have no idea for how to make it....

update , I got answer , it should be ...

psv=input(86,0)

chklayer=psv.edges.with_length(0.um..5.um)

psv.interacting(chklayer.extended(:out => 1.0)).output(100,50)

Thanks.

Hi @RawrRanger

Could you please help to check why I can't measure the cut corner value in this pattern?

here the GDS file and what the meausre script as below.