I have some C code that converts a path into a polygon. It might help. This
code can mostly be converted to SKILL line-by-line. It seems to work for my
application, but let me know if you spot an error or if you know of a
cleaner way to do this.
Frank
void path_to_polygon(path &path0, polygon &poly) {
unsigned i, pa, pb, npts;
double width, width2, b_ext = 0.0, e_ext = 0.0, vx, vy, ux, uy, vmag, umag,
denom, x1, x2, y1, y2, l1, l2;
point *points, *points2;
npts = 2*path0.npts;
poly.layer = path0.layer;
poly.npts = npts;
width = path0.width;
width2 = 0.5*width;
pa = 0;
pb = npts - 1;
points2 = path0.points;
points = new point[npts];
if (path0.type == PATH_TYPE2) { // begin and end extension by half width
b_ext = 0.5*width;
e_ext = 0.5*width;
}
for (i = 0; i < path0.npts; ++i) {
if (i == 0) {
vx = points2[i+1].x - points2[i].x;
vy = points2[i+1].y - points2[i].y;
}
else {
vx = points2[i].x - points2[i-1].x;
vy = points2[i].y - points2[i-1].y;
}
vmag = sqrt(vx*vx + vy*vy);
vx /= vmag;
vy /= vmag;
if (i == 0) { // start
points[pa].x = points2[i].x - b_ext*vx + width2*vy;
points[pa].y = points2[i].y - b_ext*vy - width2*vx;
points[pb].x = points2[i].x - b_ext*vx - width2*vy;
points[pb].y = points2[i].y - b_ext*vy + width2*vx;
}
else if (i == (unsigned)(path0.npts-1)) { // end
points[pa].x = points2[i].x + e_ext*vx + width2*vy;
points[pa].y = points2[i].y + e_ext*vy - width2*vx;
points[pb].x = points2[i].x + e_ext*vx - width2*vy;
points[pb].y = points2[i].y + e_ext*vy + width2*vx;
}
else { // line-line intersection
ux = points2[i+1].x - points2[i].x;
uy = points2[i+1].y - points2[i].y;
umag = sqrt(ux*ux + uy*uy);
ux /= umag;
uy /= umag;
denom = ux*vy - vx*uy;
if (denom == 0.0) { // should be an invalid path
printf("Warning: Path has three colinear points.\n");
points[pa] = points[pa-1]; // duplicate last point
points[pb] = points[pb+1];
}
else {
x1 = points2[i].x + width2*vy;
x2 = points2[i].x + width2*uy;
y1 = points2[i].y - width2*vx;
y2 = points2[i].y - width2*ux;
l1 = x1*(y1 + vy) - (x1 + vx)*y1;
l2 = x2*(y2 + uy) - (x2 + ux)*y2;
points[pa].x = (ux*l1 - vx*l2)/denom;
points[pa].y = (uy*l1 - vy*l2)/denom;
x1 = points2[i].x - width2*vy;
x2 = points2[i].x - width2*uy;
y1 = points2[i].y + width2*vx;
y2 = points2[i].y + width2*ux;
l1 = x1*(y1 + vy) - (x1 + vx)*y1;
l2 = x2*(y2 + uy) - (x2 + ux)*y2;
points[pb].x = (ux*l1 - vx*l2)/denom;
points[pb].y = (uy*l1 - vy*l2)/denom;
}
}
++pa;
--pb;
}
poly.points = points;
}
Post by ParthaManju,
I will not be able to send the code since it was not developed by me.
Am sorry. But you could ask cadence for the source code that converts
the offgrid paths to on grid by sizing them
Thanks
Partha
Post by Manju ArasaiahPartha,
Can you get me the SKILL code which on-grids the points?
Thanks, Manju
Post by ParthaThe 45-deg sections of a path have to have a different width compared
to the manhattan sections to stay on grid and Opus paths don't have
that capability. Off-grids are still possible at intersecting 45's,
and if the ends of the path are 45's.
We overcome this problem by having a custom bus pcell creator, that
handles 45 degree paths by replacing the 45 degree paths to
polygons(snapping to the grid as required).
Also, cadence supplies a skill code that converts these off grid
diagonal paths to ongrid by growing the path widths till they become
ongrid.
The calculation of rounding of a path by cadence is done on the basis
of DBUPerUU( 2*(1/DBUPerUU)) and not by manufacturinggrid.
I did file a enhancement PCR 281306, quite a while back indicating
this "issue"
Partha
Post by Manju ArasaiahWhen we draw a metal-path with 45 degree angle in VLE, only the
centerline corner points are on-grid. The other 2 points (corners)
where the bend occurs are off-grid. Is it not a problem because unless
all the points (corners) are on-grid, the geometry can not be
fabricated?
Thanks, Manju