CDCutWireCommands.mesa (part of ChipNDale)
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Monier, July 24, 1984 11:31:03 am PDT
Last Edited by: Jacobi, Jacobi, April 11, 1985 9:18:19 am PST
Last Edited by: Bertrand Serlet October 6, 1985 6:44:38 pm PDT
Last Edited by: Jacobi, July 23, 1986 3:31:45 pm PDT
Last edited by: Christian Jacobi, September 12, 1986 1:43:48 pm PDT
CutInstance:
PROC [design:
CD.Design, inst:
CD.Instance, from, to:
CD.Position, gridding: CD.Number𡤁] = {
NearlyRoundToLambda:
PROC[x:
CD.Number]
RETURNS[r:
CD.Number] = {
r ← (x/gridding)*gridding;
};
cutPos: CD.Position;
L1, L2, W1, W2: CD.Number;
wireLeft, wireRight: CD.Object;
inter: CD.Position; -- the intersection of the two lines, if any, and the center of the wire
oldRect: CD.Rect ← CDInstances.InstRectI[inst]; -- the bounding box
oldSize: CD.Position ← CDBasics.SizeOfRect[oldRect];
vertical: BOOL ← oldSize.y > oldSize.x;
dx: CD.Number ← to.x-from.x; dy: CD.Number ← to.y-from.y;
ctr: CD.Position ← CDBasics.Center[oldRect];
--Test if vector parallel to wire
IF vertical AND (dx=0) OR (NOT vertical) AND (dy=0) THEN RETURN;
--Now we can divide and find the intersection of lines (not yet segments)
gridding ← MAX[1, gridding];
inter ←
IF vertical
THEN [ctr.x, (from.y+(dy*(ctr.x-from.x)/dx))/gridding*gridding]
ELSE [(dx*(ctr.y-from.y)/dy+from.x)/gridding*gridding, ctr.y];
--Monier-Sindhu theorem: if inter is in cursorBox and in oldRect, then it is the intersection of segments
IF NOT (CDBasics.InsidePos[inter, CDBasics.ToRect[from, to]] AND CDBasics.InsidePos[inter, CDBasics.Extend[oldRect, -1]]) THEN RETURN;
cutPos ← IF vertical THEN [oldRect.x1, inter.y] ELSE [inter.x, oldRect.y1];
IF vertical
THEN {
L1 ← cutPos.y - oldRect.y1;
L2 ← oldSize.y - L1;
W1 ← W2 ← oldSize.x;
}
ELSE {
L1 ← L2 ← oldSize.y;
W1 ← cutPos.x - oldRect.x1;
W2 ← oldSize.x - W1;
};
wireLeft ← CDRects.CreateRect[CDOrient.OrientedSize[[W1, L1], inst.orientation], inst.ob.layer];
wireRight ← CDRects.CreateRect[CDOrient.OrientedSize[[W2, L2], inst.orientation], inst.ob.layer];
CDOps.IncludeInstance[design, CDInstances.NewInstI[wireLeft, CDBasics.BaseOfRect[oldRect], inst.orientation, TRUE, CDProperties.DCopyProps[inst.properties]], FALSE];
CDOps.IncludeInstance[design, CDInstances.NewInstI[wireRight, cutPos, inst.orientation, TRUE, CDProperties.DCopyProps[inst.properties]], FALSE];
CDOps.RemoveInstance[design, inst];
};
CutWireComm:
PROC [comm: CDSequencer.Command] = {
grid: CD.Number ← GetGrid[comm];
TerminalIO.WriteRopes["cut selected with grid ", CDCommandOps.LambdaRope[grid, comm.design.technology.lambda], "\n"];
DoAllCuts[design: comm.design, from: comm.sPos, to: comm.pos, gridding: grid]
};