DIRECTORY RefStack, CDOrient, CDBasics, IPBasicOps, IPCoTab, IPCTG, IPTop, IPTopOpRecs, IPEditOps, IPPinNets, IPEditPrimitives, IPTopOpsPrivate, IPTopOps; IPTopEditOpsImpl: CEDAR PROGRAM IMPORTS CDOrient, RefStack, CDBasics, IPBasicOps, IPCoTab, IPCTG, IPTop, IPPinNets, IPEditOps, IPEditPrimitives, IPTopOps EXPORTS IPTopOps, IPTopOpsPrivate = BEGIN OPEN BO: IPBasicOps, TOR: IPTopOpRecs, EO: IPEditOps, EP: IPEditPrimitives, CoTab: IPCoTab, CTG: IPCTG, Top: IPTop, IPTopOps; FirstSideToTry: CTG.Side _ pos; --A minor detail-- WhichOneFirst: [1..2] _ 1; --Another minor detail-- InvalidArgs: PUBLIC ERROR[op: ATOM] = CODE; BreakCross: PUBLIC PROC [top: Top.Ref, refCh, chToBreak: CTG.Channel, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRBreakCross, ir: TOR.IRFormCross] ={ newCh1: CTG.Channel; IF NOT EP.BreakCrossChk[refCh, chToBreak] THEN ERROR InvalidArgs[$BreakCross]; --(1) Check args-- newCh1 _ top.CreateChannel[chToBreak.type]; EP.BreakCross[refCh, chToBreak, newCh1]; fr _ NEW[TOR.FRBreakCrossRec _ [refCh, chToBreak]]; --(2a) Setup fr-- ir _ NEW[TOR.IRFormCrossRec _ [refCh, chToBreak, newCh1]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --BreakCross-- FormCross: PUBLIC PROC[top: Top.Ref, ch1, ch2: CTG.Channel, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRFormCross, ir: TOR.IRBreakCross] = { refCh, negCh, posCh: CTG.Channel; IF CTG.End[ch1, neg].ch = CTG.End[ch2, pos].ch THEN {negCh _ ch2; posCh _ ch1} ELSE {negCh _ ch1; posCh _ ch2}; refCh _ CTG.End[negCh, pos].ch; IF NOT EP.FormCrossChk[refCh, negCh, posCh] THEN ERROR InvalidArgs[$FormCross]; --(1) Check args-- EP.FormCross[refCh, negCh, posCh]; top.DeActivateChannel[posCh]; fr _ NEW[TOR.FRFormCrossRec _ [ch1, ch2]]; --(2a) Setup fr-- ir _ NEW[TOR.IRBreakCrossRec _ [refCh, negCh, posCh]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --FormCross-- BreakCrosses: PUBLIC PROC[top: Top.Ref, refCh, chBnd1, chBnd2: CTG.Channel, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RComposite _ NIL] = { negCh, posCh: CTG.Channel; noXToBreak: NAT; startBreaking: BOOL _ FALSE; breakXPROC: CTG.EachIntersectionAction -- [i: CB.Intersection] RETURNS [quit: BOOL _ FALSE] -- = { tempFR: TOR.FRBreakCross; tempIR: TOR.IRFormCross; IF noXToBreak = 0 THEN RETURN [TRUE]; IF startBreaking AND i.type = CTG.Cross THEN { [tempFR, tempIR] _ BreakCross[top, refCh, i.ch]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- noXToBreak _ noXToBreak.PRED}; IF i.ch = negCh THEN startBreaking _ TRUE;}; --breakXPROC-- IF NOT (CTG.IntersectsCh[refCh, chBnd1] AND CTG.IntersectsCh[refCh, chBnd2]) THEN ERROR InvalidArgs[$BreakCrosses]; --(1) Check args-- IF EO.XCount[refCh, chBnd1] > EO.XCount[refCh, chBnd2] THEN {posCh _ chBnd1; negCh _ chBnd2} ELSE {posCh _ chBnd2; negCh _ chBnd1}; noXToBreak _ EO.XCount[refCh, posCh] - EO.XCount[refCh, negCh]; IF EO.CrossIn[refCh, negCh] THEN noXToBreak _ noXToBreak.PRED; IF CTG.EndCh[refCh, negCh] THEN startBreaking _ TRUE; IF CTG.ArmOn[refCh, negCh, neg] THEN [] _ CTG.Intersections[refCh, neg, breakXPROC] ELSE [] _ CTG.Intersections[refCh, pos, breakXPROC]; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --BreakCrosses-- FormZ: PUBLIC PROC[top: Top.Ref, comp1, comp2: CoTab.Component, zType: CTG.Side, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRFormZ, ir: TOR.IRRemoveZ] ={ et: CoTab.EdgeTypes _ south; refCh: CTG.Channel _ NIL; negComp, posComp: CoTab.Component; newCh1, newCh2: CTG.Channel; THROUGH [0..4) DO IF CoTab.GetPrinCh[comp1, et] = CoTab.GetPrinCh[comp2, BO.ETRotate[et, 2]] THEN {refCh _ CoTab.GetPrinCh[comp1, et]; EXIT}; et _ BO.ETRotate[et]; ENDLOOP; IF BO.ETDirectn[et] = neg THEN {negComp _ comp2; posComp _ comp1} ELSE {negComp _ comp1; posComp _ comp2}; IF refCh = NIL OR NOT EP.FormZChk[refCh, negComp, posComp, zType] THEN ERROR InvalidArgs[$FormZ]; --(1) Check args-- newCh1 _ top.CreateChannel[refCh.type]; newCh2 _ top.CreateChannel[BO.OTFlip[refCh.type]]; EP.FormZ[refCh, negComp, posComp, zType, newCh1, newCh2]; fr _ NEW[TOR.FRFormZRec _ [comp1, comp2, zType]]; --(2a) Setup fr-- ir _ NEW[TOR.IRRemoveZRec _ [newCh2]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --FormZ-- RemoveZ: PUBLIC PROC[top: Top.Ref, zSpine: CTG.Channel, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRRemoveZ, ir: TOR.IRFormZ] ={ refCh, newCh1: CTG.Channel; negComp, posComp: CoTab.Component; zType: CTG.Side; IF NOT EP.RemoveZChk[zSpine] THEN ERROR InvalidArgs[$RemoveZ]; --(1) Check args-- [refCh, newCh1, negComp, posComp, zType] _ EP.RemoveZ[zSpine]; top.DeActivateChannel[newCh1]; top.DeActivateChannel[zSpine]; fr _ NEW[TOR.FRRemoveZRec _ [zSpine]]; --(2a) Setup fr-- ir _ NEW[TOR.IRFormZRec _ [refCh, negComp, posComp, zType, newCh1, zSpine]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --RemoveZ-- LtoT: PUBLIC PROC[top: Top.Ref, ch: CTG.Channel, whichEnd: CTG.Side, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRLtoT, ir: TOR.RComposite] ={ lType: CTG.Side; endCo: CoTab.Component; otherCh, newCh1: CTG.Channel; okProc: PROC RETURNS [BOOL] = { otherInt: CTG.Intersection; SELECT CTG.End[ch, whichEnd].type FROM CTG.LNeg => otherInt _ CTG.NthIntersection[ch, pos, - BO.PTToInt[whichEnd]]; CTG.LPos => otherInt _ CTG.NthIntersection[ch, neg, - BO.PTToInt[whichEnd]]; CTG.TEnd => RETURN[FALSE]; ENDCASE => ERROR; IF otherInt = NIL OR (otherCh _ otherInt.ch) = NIL THEN RETURN [FALSE] ELSE RETURN [TRUE] }; --okProc-- IF NOT okProc[] THEN ERROR InvalidArgs[$LtoT]; --(1) Check args-- IF EO.CrossIn[ch, otherCh] THEN ir _LIST[BreakCross[top, ch, otherCh].ir]; [newCh1, lType, endCo] _ EP.LtoT[ch, whichEnd]; top.DeActivateChannel[newCh1]; fr _ NEW[TOR.FRLtoTRec _ [ch, whichEnd]]; --(2a) Setup fr-- ir _ CONS[NEW[TOR.IRTtoLRec _ [ch, whichEnd, lType, endCo, newCh1]], ir]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --LtoT-- TtoL: PUBLIC PROC [top: Top.Ref, co: CoTab.Component, ch: CTG.Channel, lType: CTG.Side, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRTtoL, ir: TOR.IRLtoT] ={ newCh1: CTG.Channel; whichEnd: CTG.Side; SELECT TRUE FROM --(1) Check args-- EP.TtoLChk[ch, neg, lType, co] => whichEnd _ neg; EP.TtoLChk[ch, pos, lType, co] => whichEnd _ pos; ENDCASE => ERROR InvalidArgs[$TtoL]; newCh1 _ top.CreateChannel[BO.OTFlip[ch.type]]; EP.TtoL[ch, whichEnd, lType, co, newCh1]; fr _ NEW[TOR.FRTtoLRec _ [co, ch, lType]]; --(2a) Setup fr-- ir _ NEW[TOR.IRLtoTRec _ [ch, whichEnd]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --TtoL-- FlexKnee: PUBLIC PROC [top: Top.Ref, leg, floor: CTG.Channel, whichEnd: CTG.Side, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRFlexKnee, ir: TOR.RComposite] ={ newCh1: CTG.Channel; chToAtt: CTG.Channel _ CTG.End[leg, whichEnd].ch; sideToAtt: CTG.Side _ BO.PTNot[whichEnd]; whichDirection: CTG.Side _ IF CTG.InCount[chToAtt, floor, sideToAtt] < CTG.InCount[chToAtt, leg, sideToAtt] THEN neg ELSE pos; flexOk: PROC RETURNS [BOOL] ={ parent: CoTab.Component _ CTG.NthComponent[leg, BO.PTNot[whichDirection], -BO.PTToInt[whichEnd]]; corner: CoTab.CornerTypes _ IF leg.type = hor THEN BO.CTFromPTs[hor: sideToAtt, ver: whichDirection] ELSE BO.CTFromPTs[hor: whichDirection, ver: sideToAtt]; IF CoTab.GetCornerSp[parent, corner] = NIL OR CoTab.GetCornerChs[parent, corner] # NIL THEN RETURN [FALSE]; IF CTG.End[leg, whichEnd].type # CTG.TEnd THEN RETURN [FALSE]; IF NOT CTG.ArmOn[chToAtt, floor, sideToAtt] THEN RETURN [FALSE]; RETURN [TRUE] }; --flexOk-- IF NOT flexOk[] THEN ERROR InvalidArgs[$FlexKnee]; --(1) Check args-- newCh1 _ top.CreateChannel[BO.OTFlip[leg.type]]; ir _ BreakCrosses[top, chToAtt, floor, leg].ir; EP.FlexKnee[leg, floor, whichEnd, whichDirection, newCh1]; fr _ NEW[TOR.FRFlexKneeRec _ [leg, floor, whichEnd]]; --(2a) Setup fr-- ir _ CONS[NEW[TOR.IRExtendKneeRec _ [newCh1]], ir]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --FlexKnee-- ExtendKnee: PUBLIC PROC [top: Top.Ref, shin: CTG.Channel, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRExtendKnee, ir: TOR.IRFlexKnee] ={ leg, floor: CTG.Channel; whichEnd, whichDirection: CTG.Side; IF NOT EP.ExtendKneeChk[shin] THEN ERROR InvalidArgs[$ExtendKnee]; --(1) Check args-- [leg, floor, whichEnd, whichDirection] _ EP.ExtendKnee[shin]; top.DeActivateChannel[shin]; fr _ NEW[TOR.FRExtendKneeRec _ [shin]]; --(2a) Setup fr-- ir _ NEW[TOR.IRFlexKneeRec _ [leg, floor, whichEnd, whichDirection, shin]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --ExtendKnee-- Grow: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, chToSplit, negBnd, posBnd: CTG.Channel, keepTrack: BOOL _ FALSE]RETURNS [fr, ir: TOR.RComposite _ NIL] ={ tempFR, tempIR: TOR.RAny; IF CTG.End[chToSplit, pos].ch = negBnd --Just to make Grow more General-- THEN {negBnd _ posBnd; posBnd _ CTG.End[chToSplit, pos].ch}; IF CTG.End[chToSplit, neg].ch = posBnd --Just to make Grow more General-- THEN {posBnd _ negBnd; negBnd _ CTG.End[chToSplit, neg].ch}; IF CoTab.CoActive[co] OR NOT EO.BndsOkChk[chToSplit, negBnd, posBnd] THEN ERROR InvalidArgs[$Grow]; --(1) Check args-- [tempFR, tempIR] _ BreakCrosses[top, chToSplit, negBnd, posBnd]; --Break All Crosses in between-- [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- [tempFR, tempIR] _ InsertCo[top, co, chToSplit, negBnd, posBnd, FirstSideToTry, WhichOneFirst]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --Grow-- Grow1: PUBLIC PROC[top: Top.Ref, co, host: CoTab.Component, hostCorner: CoTab.CornerTypes, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRGrow1, ir: TOR.IRRemoveCoAtCorner] ={ newHCh1, newVCh1: CTG.Channel; IF CoTab.CoActive[co] OR NOT EP.InsertCoAtCornerChk[host, co, hostCorner] THEN ERROR InvalidArgs[$Grow1]; --(1) Check args-- CoTab.ReActivateComponent[co]; newHCh1 _ top.CreateChannel[hor]; newVCh1 _ top.CreateChannel[ver]; EP.InsertCoAtCorner[host, co, hostCorner, newHCh1, newVCh1]; fr _ NEW[TOR.FRGrow1Rec _ [co, host, hostCorner]]; --(2a) Setup fr-- ir _ NEW[TOR.IRRemoveCoAtCornerRec _ [host, hostCorner]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --Grow1-- Shrink: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, shrinkDirectionHint: CTG.ChType, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RComposite _ NIL] ={ corner: CoTab.CornerTypes _ sw; hintNot: CTG.ChType _ BO.OTFlip[shrinkDirectionHint]; tempFR, tempIR: TOR.RAny; IF NOT CoTab.CoActive[co] THEN ERROR InvalidArgs[$Shrink]; --(1) Check args-- [tempFR, tempIR] _ ClearAllNegCorners[top, co, hintNot]; IF tempIR # NIL THEN [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- [tempFR, tempIR] _ ClearAllLCorners[top, co, shrinkDirectionHint]; IF tempIR # NIL THEN [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- THROUGH [0..4) DO frAny, irAny: TOR.RAny; [frAny, irAny] _ BreakXAtCorner[top, co, corner, hintNot]; IF irAny # NIL THEN [fr, ir] _ Cons2[frAny, fr, irAny, ir]; --Setup fr and ir-- corner _ BO.CTRotate[corner]; ENDLOOP; IF Shrink1Chk[co] THEN {[tempFR, tempIR]_ Shrink1[top, co]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir--} ELSE { [tempFR, tempIR] _ IF RemoveCoChk[co, shrinkDirectionHint] THEN RemoveCo[top, co, shrinkDirectionHint] ELSE RemoveCo[top, co, hintNot]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir--}; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --Shrink-- ClearNegCorner: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, corner: CoTab.CornerTypes, chToUse: CTG.ChType, breakOtherIfX, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RComposite _ NIL] ={ IF CoTab.GetCornerChs[co, corner] = NIL THEN GOTO done; -- nothing to do-- BEGIN chDn: CTG.Side _ BO.CTDirectnFor[corner, chToUse]; otherDn: CTG.Side _ BO.CTDirectnFor[corner, BO.OTFlip[chToUse]]; cornerCh: CTG.Channel _ CoTab.GetCornerChFor[co, corner, chToUse]; prinCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[corner, BO.OTFlip[chToUse]]]; tempFR, tempIR: TOR.RAny _ NIL; IF EO.CrossIn[cornerCh, prinCh] THEN { [tempFR, tempIR] _ IF breakOtherIfX THEN BreakCross[top, cornerCh, prinCh] ELSE BreakCross[top, prinCh, cornerCh]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- cornerCh _ CoTab.GetCornerChFor[co, corner, chToUse]; prinCh _ CoTab.GetPrinCh[co, BO.CTResolveFor[corner, BO.OTFlip[chToUse]]];}; IF NOT CTG.NoIntersection[cornerCh, BO.PTNot[otherDn]] THEN { [tempFR, tempIR] _ LtoT[top, cornerCh, BO.PTNot[chDn]]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- GOTO done}; IF CTG.End[cornerCh, chDn].type # CTG.TEnd THEN{ IF EO.NoIntersection[cornerCh] THEN {[tempFR, tempIR] _ RemoveZ[top, cornerCh]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- GOTO done} ELSE {[tempFR, tempIR] _ LtoT[top, cornerCh, chDn]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir--}}; [tempFR, tempIR] _ExtendKnee[top, cornerCh]; [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- GOTO done; END; EXITS done => IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --ClearNegCorner-- ClearAllNegCorners: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, chToUse: CTG.ChType, breakOtherIfX, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RComposite _ NIL] ={ corner: CoTab.CornerTypes _ sw; tempFR, tempIR: TOR.RAny _ NIL; IF NOT CoTab.CoActive[co] THEN ERROR InvalidArgs[$ClearAllNegCorners]; --(1) Check args-- THROUGH [0..4) DO [tempFR, tempIR] _ ClearNegCorner[top, co, corner, chToUse, breakOtherIfX]; IF tempIR # NIL THEN [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- corner _ BO.CTRotate[corner]; ENDLOOP; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --ClearAllNegCorners-- ClearLCorner: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, corner: CoTab.CornerTypes, hint: CTG.ChType, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RAny _ NIL] ={ IF CoTab.GetCornerChs[co, corner] # NIL THEN ERROR InvalidArgs [$ClearLCorner]; BEGIN hintNot: CTG.ChType _ BO.OTFlip[hint]; hintDn: CTG.Side _ BO.CTDirectnFor[corner, hint]; otherDn: CTG.Side _ BO.CTDirectnFor[corner, BO.OTFlip[hint]]; hintCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[corner, hint]]; otherCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[corner, hintNot]]; IF NOT EO.IsLCorner[hintCh, otherCh] THEN GOTO done; --Nothing to do-- IF NOT CTG.NoIntersection[hintCh, otherDn] THEN {[fr, ir] _ LtoT[top, hintCh, hintDn]; GOTO done}; IF NOT CTG.NoIntersection[otherCh, hintDn] THEN {[fr, ir] _ LtoT[top, otherCh, otherDn]; GOTO done}; GOTO done--Cant do anything-- EXITS done => IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- END; }; --ClearLCorner-- ClearAllLCorners: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, hint: CTG.ChType, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RComposite _ NIL] ={ corner: CoTab.CornerTypes _ sw; tempFR, tempIR: TOR.RAny; IF NOT CoTab.CoActive[co] THEN ERROR InvalidArgs[$ClearAllLCorners]; --(1) Check args-- THROUGH [0..4) DO [tempFR, tempIR] _ ClearLCorner[top, co, corner, hint]; IF tempIR # NIL THEN [fr, ir] _ Cons2[tempFR, fr, tempIR, ir]; --Setup fr and ir-- corner _ BO.CTRotate[corner]; ENDLOOP; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --ClearAllLCorners-- BreakXAtCorner: PUBLIC PROC [top: Top.Ref, co: CoTab.Component, corner: CoTab.CornerTypes, chToBreak: CTG.ChType, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RAny _ NIL] ={ IF CoTab.GetCornerChs[co, corner] # NIL THEN ERROR InvalidArgs [$BreakXAtCorner]; BEGIN hCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[corner, hor]]; vCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[corner, ver]]; IF EO.CrossIn[hCh, vCh] THEN [fr, ir] _ (IF chToBreak = hor THEN BreakCross[top, vCh, hCh] ELSE BreakCross[top, hCh, vCh]); IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- END; }; --BreakXAtCorner-- Mirror: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, mirrorOrientation: CTG.ChType, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.ROrient] ={ SELECT mirrorOrientation FROM ver => [fr, ir] _ Orient[top, co, CDOrient.mirrorX, keepTrack]; hor => [fr, ir] _ Orient[top, co, CDOrient.mirrorY, keepTrack]; ENDCASE => ERROR; }; --Mirror Rotate: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, numberOfRot: INT _ 1, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.ROrient] ={ SELECT numberOfRot MOD 4 FROM 0 => [fr, ir] _ Orient[top, co, CDOrient.original, keepTrack]; 1, -3 => [fr, ir] _ Orient[top, co, CDOrient.rotate90, keepTrack]; 2, -2 => [fr, ir] _ Orient[top, co, CDOrient.rotate180, keepTrack]; 3, -1 => [fr, ir] _ Orient[top, co, CDOrient.rotate270, keepTrack]; ENDCASE => ERROR; }; --Rotate Orient: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, operation: CDOrient.Orientation, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.ROrient] ={ IF ~ CoTab.OrientCoShapeChk[co, operation] THEN ERROR InvalidArgs[$Orient]; --(1) Check args-- fr _ NEW[TOR.ROrientRec _ [co, operation]]; --(2a) Setup fr-- ir _ NEW[TOR.ROrientRec _ [co, CDOrient.InverseOrient[operation]]]; --(2b) Setup ir-- CoTab.OrientCoShape[co, operation]; IPPinNets.OrientPinNets[co, operation]; --this must be done before co.orient _ ... co.orient _ CDOrient.ComposeOrient[co.orient, operation]; top.initialized _ FALSE; --Set Flags to indicate geometry is not right IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --Orient SetComponent: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, active: BOOL, atPosition: IPCoTab.IntVector _ [0, 0], keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RSetComponent] ={ IF ~ SetComponentChk[top, co, active] THEN ERROR InvalidArgs[$SetComponent];--(1) Check args fr _ NEW[TOR.RSetComponentRec _ [co, active, atPosition]]; --(2a) Setup fr-- ir _ NEW[TOR.RSetComponentRec _ [co, CoTab.CoActive[co], CoTab.GetOrigin[co]]]; --(2b) Setup ir-- IF active THEN {IF ~ CoTab.CoActive[co] THEN CoTab.ReActivateComponent[co]} ELSE {IF CoTab.CoActive[co] THEN CoTab.DeActivateComponent[co]}; CoTab.SetOrigin[co, atPosition]; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --SetComponent MoveComponent: PUBLIC PROC [top: Top.Ref, co: CoTab.Component, by: IPCoTab.IntVector, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RMoveComponent] ={ --(1) DONT have to Check args-- fr _ NEW[TOR.RMoveComponentRec _ [co, by]]; --(2a) Setup fr-- ir _ NEW[TOR.RMoveComponentRec _ [co, BO.IntVectorNegate[by]]]; --(2b) Setup ir-- CoTab.SetOrigin[co, CDBasics.AddPoints[CoTab.GetOrigin[co], by]]; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- };--MoveComponent SwapComponents: PUBLIC PROC[top: Top.Ref, co1, co2: CoTab.Component, keepTrack: BOOL _ FALSE] RETURNS [fr, ir: TOR.RSwapComponents] ={ IF ~ SwapComponentsChk[top, co1, co2] THEN ERROR InvalidArgs[$SwapComponents]; --(1) Check args BEGIN OPEN c1P: co1.prinChannels, c1C: co1.cornerChannels, c2P: co2.prinChannels, c2C: co2.cornerChannels; tActive: BOOL _ co1.active; tOrigin: CoTab.IntVector _ co1.origin; tSouth, tEast, tNorth, tWest: CTG.Channel; tSw, tSe, tNe, tNw: CoTab.CornerChannels; [tSouth, tEast, tNorth, tWest] _ co1.prinChannels; [tSw, tSe, tNe, tNw] _ co1.cornerChannels; IF co1.active # co2.active THEN { IF co2.active THEN IPCoTab.ReActivateComponent[co1] ELSE IPCoTab.DeActivateComponent[co1]}; co1.origin _ co2.origin; co1.prinChannels _ co2.prinChannels; co1.cornerChannels _ co2.cornerChannels; IF co2.active # tActive THEN { IF tActive THEN IPCoTab.ReActivateComponent[co2] ELSE IPCoTab.DeActivateComponent[co2]}; co2.origin _ tOrigin; co2.prinChannels _ [tSouth, tEast, tNorth, tWest]; co2.cornerChannels _ [tSw, tSe, tNe, tNw]; IF co1.active THEN CoTab.InsertComponent[co1, c1P.south, c1P.east, c1P.north, c1P.west, c1C.sw, c1C.se, c1C.ne, c1C.nw]; IF co2.active THEN CoTab.InsertComponent[co2, c2P.south, c2P.east, c2P.north, c2P.west, c2C.sw, c2C.se, c2C.ne, c2C.nw]; END; ir _ fr _ NEW[TOR.RSwapComponentsRep _ [co1, co2]]; --(2) Setup fr and ir. top.initialized _ FALSE; --Set Flags to indicate geometry not right IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --SwapComponents InsertCo: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, chToSplit, negBnd, posBnd: CTG.Channel, sideHint: CTG.Side, whichFirstHint: [1..2], keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRInsertCo, ir: TOR.RAny] ={ newCh1: CTG.Channel; sideToClHint: CTG.Side; shrinkDirectn: CTG.ChType _ BO.OTFlip[chToSplit.type]; IF CoTab.CoActive[co] OR (NOT EP.InsertCo1Chk[co, chToSplit, negBnd, posBnd] AND NOT EP.InsertCo2Chk[co, chToSplit, negBnd, posBnd] ) THEN ERROR InvalidArgs[$InsertCo]; --(1) Check args-- fr _ NEW[TOR.FRInsertCoRec _ [co, chToSplit, negBnd, posBnd, sideHint, whichFirstHint]]; --(2a) Setup fr-- SELECT whichFirstHint FROM 1 => IF NOT EP.InsertCo1Chk[co, chToSplit, negBnd, posBnd] THEN whichFirstHint _ 2; 2 => IF NOT EP.InsertCo2Chk[co, chToSplit, negBnd, posBnd] THEN whichFirstHint _ 1; ENDCASE => ERROR; IF whichFirstHint = 1 THEN { CoTab.ReActivateComponent[co]; newCh1 _ top.CreateChannel[chToSplit.type]; sideToClHint _ EP.InsertCo1[co, chToSplit, negBnd, posBnd, sideHint, newCh1]; ir _ NEW[TOR.IRRemoveCo1Rec _ [co, shrinkDirectn, sideToClHint]]--(2b) Setup ir--} ELSE { CoTab.ReActivateComponent[co]; newCh1 _ top.CreateChannel[chToSplit.type]; sideToClHint _ EP.InsertCo2[co, chToSplit, negBnd, posBnd, sideHint, newCh1]; ir _ NEW[TOR.IRRemoveCo2Rec _ [co, shrinkDirectn, sideToClHint]]--(2b) Setup ir--}; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --InsertCo-- RemoveCo: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, shrinkDirectn: BO.OrientationTypes, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRRemoveCo, ir: TOR.RAny] ={ chToSplit, negBnd, posBnd, newCh1: CTG.Channel; sideToOpHint: CTG.Side; IF NOT CoTab.CoActive[co] THEN ERROR InvalidArgs[$RemoveCo]; --(1) Check args-- fr _ NEW[TOR.FRRemoveCoRec _ [co, shrinkDirectn]]; --(2a) Setup fr-- SELECT TRUE FROM EP.RemoveCo1Chk[co, shrinkDirectn] => {[chToSplit, negBnd, posBnd, newCh1, sideToOpHint] _ EP.RemoveCo1[co, shrinkDirectn, FirstSideToTry]; CoTab.DeActivateComponent[co]; top.DeActivateChannel[newCh1]; ir _ NEW[TOR.IRInsertCo1Rec _ [co, chToSplit, negBnd, posBnd, sideToOpHint, newCh1]]; --(2b) Setup ir--}; EP.RemoveCo2Chk[co, shrinkDirectn] => {[chToSplit, negBnd, posBnd, newCh1, sideToOpHint] _ EP.RemoveCo2[co, shrinkDirectn, FirstSideToTry]; CoTab.DeActivateComponent[co]; top.DeActivateChannel[newCh1]; ir _ NEW[TOR.IRInsertCo2Rec _ [co, chToSplit, negBnd, posBnd, sideToOpHint, newCh1]]; --(2b) Setup ir--}; ENDCASE => ERROR InvalidArgs[$RemoveCo]; IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --RemoveCo-- RemoveCoChk: PROC[co: CoTab.Component, shrinkDirectn: BO.OrientationTypes] RETURNS [BOOL] ={RETURN [EP.RemoveCo1Chk[co, shrinkDirectn] OR EP.RemoveCo2Chk[co, shrinkDirectn]]}; --RemoveCoChk-- Shrink1: PUBLIC PROC[top: Top.Ref, co: CoTab.Component, keepTrack: BOOL _ FALSE] RETURNS [fr: TOR.FRShrink1, ir: TOR.IRInsertCoAtCorner] ={ host: CoTab.Component; corner: CoTab.CornerTypes; hCh, vCh: CTG.Channel; [host, corner] _ Shrink1FindHost[co]; IF NOT Shrink1Chk[co] THEN ERROR InvalidArgs[$Shrink1]; --(1) Check args-- [horCh: hCh, verCh: vCh] _ EP.RemoveCoAtCorner[host, corner]; CoTab.DeActivateComponent[co]; top.DeActivateChannel[hCh]; top.DeActivateChannel[vCh]; fr _ NEW[TOR.FRShrink1Rec _ [co]]; --(2a) Setup fr-- ir _ NEW[TOR.IRInsertCoAtCornerRec _ [host, co, corner, hCh, vCh]]; --(2b) Setup ir-- IF keepTrack THEN PushStacks[top, fr, ir]; --(3) Push Stacks?-- }; --Shrink1-- Shrink1Chk: PROC[co: CoTab.Component] RETURNS [BOOL] ={ host: CoTab.Component; corner: CoTab.CornerTypes; [host, corner] _ Shrink1FindHost[co]; IF NOT CoTab.CoActive[co] OR host = NIL THEN RETURN [FALSE] ELSE RETURN[EP.RemoveCoAtCornerChk[host, corner]]; }; --Shrink1Chk-- Shrink1FindHost: PROC [co: CoTab.Component] RETURNS [host: CoTab.Component _ NIL, hostCorner: CoTab.CornerTypes _ sw] ={ coCorner: CoTab.CornerTypes _ sw; findHostProc: PROC RETURNS [found: BOOL] ={ hCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[coCorner, hor]]; vCh: CTG.Channel _ CoTab.GetPrinCh[co, BO.CTResolveFor[coCorner, ver]]; IF NOT EO.IsLCorner[hCh, vCh] THEN RETURN [FALSE]; host _ CTG.NthComponent[vCh, BO.CTDirectnFor[coCorner, hor], BO.PTToInt[BO.CTInvDirectnFor[coCorner, ver]]]; IF host = NIL THEN RETURN [FALSE]; hostCorner _ BO.CTDiag[coCorner]; IF EP.RemoveCoAtCornerChk[host, hostCorner] THEN RETURN [TRUE] ELSE RETURN [FALSE]; }; --findHostProc-- THROUGH [0..4) DO IF findHostProc[] THEN EXIT; coCorner _ BO.CTRotate[coCorner]; ENDLOOP; }; --Shrink1FindHost-- SetComponentChk: PROC[top: Top.Ref, co: CoTab.Component, active: BOOL] RETURNS [BOOL] ={ RETURN [Top.NoTopology[top] OR active = CoTab.CoActive[co]]; }; --SetComponentChk SwapComponentsChk: PROC [top: Top.Ref, co1, co2: CoTab.Component] RETURNS [BOOL] ={ IF CoTab.CoActive[co1] THEN { FOR corner: CoTab.CornerTypes IN [sw..nw] DO IF CoTab.GetCornerChs[co1, corner] # NIL AND CoTab.GetCornerSp[co2, corner] = NIL THEN RETURN [FALSE] ENDLOOP;}; IF CoTab.CoActive[co2] THEN { FOR corner: CoTab.CornerTypes IN [sw..nw] DO IF CoTab.GetCornerChs[co2, corner] # NIL AND CoTab.GetCornerSp[co1, corner] = NIL THEN RETURN [FALSE] ENDLOOP;}; RETURN [TRUE]; }; --SwapComponentsChk END. ‚File: IPTopEditOpsImpl.mesa Last Edited by: CSChow, January 28, 1985 6:56:36 am PST --This is the only place where I did not obey the IPCoTab.Component abstraction -- (ie. accessing the fields directly) --(A) Keep temporary for co1 --(B) Assign to co1 -- (C) Assign to co2 --(D) Do insertion into surrounding channels -- NB: It's its own inverse --##Private Procedures##-- Ê;˜Jšœ™J™7J™J™šÏk ˜ J˜ Jšœ ˜ J˜ J˜ J˜Jšœ˜Jšœ˜Jšœ ˜ J˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ ˜ J˜—šœœœ˜!Jšœ4œ9˜yJšœœœœœœ œ$œœ˜§J˜Jšœœ Ïc˜2Jšœž˜3J˜Jš œ œœœœ˜+J˜J˜šÏn œœœ"œœœœœœ˜•Jšœœ ˜Icodeš œœœ!œœž˜aJšœ,˜,Jšœ&˜(Jšœœœ(ž˜EJšœœœ/ž˜LKšœ œž˜?Jšœž˜—K˜šŸ œœœœœœœœœ˜ŒKšœœ ˜!šœœœ˜/Kšœ˜Kšœ˜!—Kšœœ˜Kš œœœ#œœž˜bKšœ ˜"K˜Kšœœœž˜Kšœœœœ˜5šœœ˜ Kšœœ'˜4Kšœœ'˜4—Kšœ œž˜?Kšœž˜—J˜šŸœœœ5œœœœœœ˜™K˜Kšœœ œ˜Kšœ"˜"Kšœœ ˜šœ˜šœ6œ˜LKšœ&œ˜0—Kšœœ˜Kšœ˜—šœœ˜Kšœ#˜'Kšœ$˜(—Kšœ œœœœ*œœž˜tKšœ'˜'Kšœœ˜2Kšœ7˜9Kšœœœ&ž˜CKšœœœž˜8Kšœ œž˜?Kšœžœ˜ —K˜šŸœœœœœœœœœ ˜€Kšœœ ˜Kšœ"˜"Kšœœ˜Kš œœœœœž˜RKšœ+œ˜>Kšœ˜Kšœ˜Kšœœœž˜8KšœœœAž˜^Kšœ œž˜?Kšœž œ˜—K˜šŸœœœœœœœœœ œ˜Kšœœ˜Kšœ˜Kšœœ ˜šœœœœ˜Kšœ œ˜šœœ˜'Kšœœœ˜MKšœœœ˜LKšœ œœ˜Kšœœ˜—šœ œœœ˜3Kšœœœ˜Kšœœœ˜—Kšœž ˜ —K˜Kš œœ œœž˜AKšœœœœ"˜KK˜Kšœœ˜0Kšœ˜Kšœœœž˜;Kšœœœœ9ž˜[Kšœ œž˜?Kšœžœ˜ —šŸœœœ)œœœœœœ œ ˜œJšœœ ˜Jšœ œ˜šœœž˜%Kšœ0˜2Kšœ0˜2Kšœœ˜$—Kšœœ˜/Kšœ)˜+Kšœœœž˜Kš œœœ"œœœ˜@Kšœœ˜ Kšœž˜ —Kš œœ œœž˜EKšœœ˜0Kšœ/˜/Kšœ8˜:Kšœœœ)ž˜GKšœœœœ"ž˜EKšœ œž˜?Kšœž ˜—K˜šŸ œœœœœœœœœ˜ˆKšœ œ ˜Kšœœ˜#Kš œœœœœž˜UKšœ)œ˜=K˜Kšœœœž˜9Kšœœœ?ž˜]Kšœ œž˜?Kšœž˜—K˜šŸœœœ?œœœœ œœ˜žKšœœ˜šœœ"ž"˜JKšœœ˜<—šœœ"ž"˜JKšœœ˜<—Kš œœœœ&œœž˜vKšœAž ˜aKšœ*ž˜=Kšœ_˜_Kšœ*ž˜=Kšœ œž˜?Kšœžœ˜ —K˜šŸœœœTœœœœœ˜¬Jšœœ ˜Kš œœœœ+œœž˜|J˜K˜!K˜!Kšœ:˜˜>KšœB˜BKšœC˜CKšœC˜CKšœœ˜—Kšœž˜ —K˜šŸœœœPœœœ œ ˜‘Kšœ)œœž˜^Kšœœœ ž˜=Kšœœœ8ž˜UKšœ#˜#Kšœ(ž*˜RKšœ9˜9Kšœœž-˜FKšœ œž˜?Jšœž˜ —J˜šŸ œœœ,œ5œœœ œ˜²šœ$˜&Kšœœž˜6—Jšœœœ/ž˜LKšœœœDž˜ašœ˜ Kšœœœ˜AKšœœœ ˜@—K˜Kšœ ˜ Kšœ œž˜?Jšœž˜—K˜šŸ œœœGœœœ œ˜–Kšœž˜ Kšœœœ ž˜=Kšœœœœž˜QKšœA˜AKšœ œž˜?Kšœž˜—J˜šŸœœœ5œœœ œ˜†K™PK™'Kšœ$œœž˜_š œ_˜jK™Kšœ œ˜Kšœ&˜&Kšœœ ˜*Kšœ*˜*Kšœ2˜2Kšœ*˜*K˜K™šœœ˜!šœ ˜Kšœ!˜%Kšœ#˜'——Kšœ˜Kšœ$˜$K–[]šœ(˜(K˜K™šœœ˜šœ ˜ Kšœ!˜%Kšœ#˜'——Kšœ˜Kšœ2˜2Kšœ*˜*K˜K™,Kšœ œf˜xKšœ œf˜xKšœ˜—K˜šœ œœ#ž˜KKšœž™—Kšœœž+˜DKšœ œž˜?Kšœž˜—J˜J˜Kšž™K˜šŸœ œ?œœ*œœœœœ ˜ÓKšœœ ˜Kšœœ˜Kšœœ œ˜6Kšœœœœ-œœœ/œœž˜»J˜KšœœœMž˜jšœ˜Kš œœœœ-œ˜SKš œœœœ-œ˜SKšœœ˜—šœ˜šœ˜K˜Jšœ+˜+Kšœœ<˜MKšœœœ4žœ˜S—šœ˜K˜Jšœ+˜+Kšœœ<˜MKšœœœ4žœ˜S——Kšœ œž˜?Kšœž œ˜—K˜šŸœ œ3œœœœœœ ˜£Kšœ#œ ˜/Kšœœ˜Kš œœœœž˜OK˜Kšœœœ'ž˜Dšœœ˜šœYœ.˜‹K˜Kšœ˜KšœœœJžœ˜i—šœYœ.˜‹K˜Kšœ˜KšœœœJžœ˜i—Kšœœ˜(—K˜Kšœ œž˜?Kšœž ˜—J˜KšŸ œœ%œœœœœ!œœ$ž œ˜¿K˜šŸœ œ/œœœœœ˜‹Kšœ˜Kšœ˜Kšœ œ ˜Kšœ%˜%Kš œœœœž˜JKšœœ ˜=K˜Kšœ˜Kšœ˜K˜Kšœœœž˜4Kšœœœ8ž˜UKšœ œž˜?Kšœž œ˜—K˜šŸ œœœœ˜7Kšœ˜Kšœ˜Kšœ%˜%šœœœœ˜)Kšœœœ˜Kšœœœ$˜2Kšœž œ˜——K˜šŸœœœœ(˜xKšœ!˜!šœœœ œ˜+Kšœœœ˜GKšœœœ˜GKš œœœœœœ˜2Kš œœœœ œ"˜lKš œœœœœ˜"Kšœ œ˜!šœœ'˜,Kšœœœ˜Kšœœœ˜—Kšœž˜—šœ˜Kšœœœ˜Kšœ œ˜!Kšœ˜—Kšœž˜—K˜š Ÿœœ,œœœ˜XKšœœ˜