DIRECTORY CD, CDApplications, CDBasics, CDRects, CDSequencer, CDCallSpecific, CDOps, CDOrient, CDProperties, TerminalIO; CDSplitWireCommands: CEDAR PROGRAM IMPORTS CDApplications, CDBasics, CDOps, CDOrient, CDProperties, CDSequencer, TerminalIO, CDRects = BEGIN SplitApplication: PROC [design: CD.Design, aPtr: CD.ApplicationPtr, from, to: CD.DesignPosition] = BEGIN cutPos, oldRectPos, oldSize: CD.DesignPosition; oldRect: CD.DesignRect; -- the bounding box L1, L2, W1, W2: CD.DesignNumber; wireLeft, wireRight: CD.ObPtr; vertical, intersect: BOOL; NearlyRoundToLambda: PROC[x: CD.DesignNumber] RETURNS[r: CD.DesignNumber] = BEGIN r _ (x/CD.lambda)*CD.lambda; IF x=0 THEN r _ CD.lambda; END; FindCut: PROC[from, to: CD.DesignPosition, oldRect: CD.DesignRect, vertical: BOOL] RETURNS[cutPos: CD.DesignPosition, intersect: BOOL _ TRUE] = BEGIN inter, ctr: CD.DesignPosition; -- the intersection of the two lines, if any, and the center of the wire dx, dy: CD.DesignNumber; cursorBox: CD.DesignRect; cursorBox _ CDBasics.ToRect[from, to]; dx _ to.x-from.x; dy _ to.y-from.y; ctr _ CDBasics.Center[oldRect]; IF vertical AND (dx=0) OR (NOT vertical) AND (dy=0) THEN RETURN[[0,0], FALSE]; inter _ IF vertical THEN [ctr.x, from.y+(dy*(ctr.x-from.x)/dx)] ELSE [dx*(ctr.y-from.y)/dy+from.x, ctr.y]; IF NOT (CDBasics.InsidePos[inter, cursorBox] AND CDBasics.InsidePos[inter, oldRect]) THEN RETURN[[0,0], FALSE]; cutPos _ IF vertical THEN [oldRect.x1, NearlyRoundToLambda[inter.y]] ELSE [NearlyRoundToLambda[inter.x], oldRect.y1]; END; oldRect _ CDApplications.ARectI[aPtr]; oldRectPos _ CDBasics.BaseOfRect[oldRect]; oldSize _ CDBasics.SizeOfRect[oldRect]; vertical _ oldSize.y > oldSize.x; [cutPos, intersect] _ FindCut[from, to, oldRect, vertical]; IF NOT intersect THEN RETURN; 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], aPtr.orientation], aPtr.ob.layer]; wireRight _ CDRects.CreateRect[CDOrient.OrientedSize[[W2, L2], aPtr.orientation], aPtr.ob.layer]; CDOps.IncludeApplication[design, CDApplications.NewApplicationI[wireLeft, oldRectPos, aPtr.orientation, TRUE, CDProperties.CopyProps[aPtr.properties]], FALSE]; CDOps.IncludeApplication[design, CDApplications.NewApplicationI[wireRight, cutPos, aPtr.orientation, TRUE, CDProperties.CopyProps[aPtr.properties]], FALSE]; CDOps.RemoveApplication[design, aPtr]; END; DoAllSplits: PROC [design: CD.Design, from, to: CD.DesignPosition, pointed: BOOL_FALSE] = BEGIN FOR list: CD.ApplicationList _ CDOps.AppList[design], list.rest WHILE list#NIL DO IF list.first.selected AND list.first.ob.p.wireTyped THEN SplitApplication[design, list.first, from, to]; ENDLOOP; END; SplitWireCommandS: PROC [comm: CDSequencer.Command] = BEGIN TerminalIO.WriteRope["Split selected\n"]; DoAllSplits[design: comm.design, from: comm.sPos, to: comm.pos, pointed: FALSE] END; CDSequencer.ImplementCommand[$SplitWireS, SplitWireCommandS]; END. ¸CDSplitWireCommands.mesa (part of Chipndale) Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Last Edited by: Monier, July 24, 1984 11:31:03 am PDT Last Edited by: Jacobi, April 11, 1985 9:18:19 am PST For now OK, but check if there is any risk to make anything smaller than one lambda Test if vector parallel to wire Now we can divide and find the intersection of lines (not yet segments) Monier-Sindhu theorem: if inter is in cursorBox and in oldRect, then it is the intersection of segments The mouse track defines the cut vector. Let's define the "spine" of a wire as the centerline, roughly in the middle (lambda) and following the visible length, i.e. the longer edge, not the CD length. Then we cut the wire at the position where the spine meets the cut vector. The cut always reduces the visible length of the wire. (Pff, not easy to describe without drawing!) A vertical wire freshly drawn has even (0) orientation. Ê͘šœ.™.Jšœ Ïmœ7™BJ™5J™5—J˜šÏk ˜ Jšžœ˜J˜Jšœ ˜ J˜J˜ J˜Jšœ˜J˜ J˜ J˜ J˜—šÏbœžœž˜"Jšžœ]˜d—Jšž˜J˜š Ïnœžœ žœžœžœ˜bJšž˜Jšœžœ˜/Jšœ žœ Ïc˜+Jšœžœ˜ Jšœžœ˜Jšœžœ˜J˜š  œžœžœžœžœ˜KJšž˜Jšœžœ žœ˜Jšžœžœžœ˜Jšžœ˜—J˜š œžœ žœžœžœžœ žœžœžœ˜Jšž˜JšœS™SJšœ žœ¡H˜gJšœžœ˜Jšœ žœ ˜J˜Jšœ&˜&Jšœ#˜#Jšœ˜J™Jšœ™Jšžœ žœžœžœ žœžœžœžœ˜NJšœG™Gšœžœ ˜Jšžœ'˜+Jšžœ&˜*—Jšœg™gJš žœžœ'žœ%žœžœžœ˜oJšœ žœ žœ,žœ,˜uJšžœ˜—J˜Jšœ&˜&Jšœ*˜*Jšœ'˜'Jšœ!˜!J˜Jšœ;˜;Jšžœžœ žœžœ˜J˜šžœ žœ˜Jšœ˜Jšœ˜Jšœ˜J˜—šžœ˜Jšœ˜Jšœ˜Jšœ˜J˜J˜—Jšœ`˜`Jšœa˜aJ˜Jšœhžœ,žœ˜ŸJšœežœ,žœ˜œJšœ&˜&Jšžœ˜—J˜š   œžœ žœžœžœžœ˜YJšž˜Jšœö™öJ™7J˜š žœžœ4žœžœž˜QJšžœžœžœ0˜iJšžœ˜—Jšžœ˜—J˜š œžœ˜5Jšž˜J˜)JšœIžœ˜OJšžœ˜—J˜J˜Jšœ=˜=Jšžœ˜J˜—…— ‡