DIRECTORY CD, CDInstances, CDBasics, CDCommandOps, CDCallSpecific, CDCurves, CDLayers, CDOps, CDOrient, CDPrivate, CDSequencer, CDSymbolicObjects, IO, PriorityQueue, Real, Rope, TerminalIO; CDCurvesCommands: CEDAR PROGRAM IMPORTS CDBasics, CDCallSpecific, CDCommandOps, CDCurves, CDLayers, CDOps, CDOrient, CDSequencer, CDSymbolicObjects, IO, PriorityQueue, Real, Rope, TerminalIO SHARES CDCurves = BEGIN LP: TYPE = LIST OF CD.Position; Write: PROC[r: Rope.ROPE] = {TerminalIO.WriteRope[r]}; DistanceSq: PROC[p1, p2: CD.Position] RETURNS [REAL] = BEGIN dx: REAL = Real.Float[p1.x]-Real.Float[p2.x]; dy: REAL = Real.Float[p1.y]-Real.Float[p2.y]; RETURN [dx*dx+dy*dy] END; Distance: PROC [p1, p2: CD.Position] RETURNS [REAL] = BEGIN RETURN [Real.SqRt[DistanceSq[p1, p2]]] END; DistancePairP: PROC[p1, p2, p: CD.Position] RETURNS [REAL] = BEGIN RETURN [ABS[Distance[p1, p]+Distance[p2, p]-Distance[p2, p1]]] END; StretchPoints: PROC [points: LP, from, to: CD.Position] RETURNS [new: LP_NIL] = BEGIN pos: INT _ 0; cnt: INT _ 0; dmin: REAL _ LAST[INT]; FOR p: LP _ points, p.rest WHILE p#NIL DO d: REAL = DistanceSq[p.first, from]; cnt _ cnt+1; IF d3 THEN points _ points.rest ELSE Write["degenerated polygon not created\n"]; FOR p: LP _ points, p.rest WHILE p#NIL DO new _ CONS[p.first, new]; ENDLOOP; END; OffsetInPlace: PROC [pl: LP, off: CD.Number] = { FOR l: LP _ pl, l.rest WHILE l#NIL DO l.first _ [l.first.x+off, l.first.y+off] ENDLOOP; }; OrientedPoints: PROC [inst: CD.Instance] RETURNS [copy: LP_NIL] = BEGIN pl: LP; WITH inst.ob.specificRef SELECT FROM cp: CDCurves.CurvePtr => pl _ cp.points; ENDCASE => ERROR; FOR p: LP _ pl, p.rest WHILE p#NIL DO orientedP: CD.Position = CDOrient.MapPoint[ pointInCell: p.first, cellSize: inst.ob.size, cellInstOrient: inst.orientation, cellInstPos: inst.location].pointInWorld; copy _ CONS[orientedP, copy]; ENDLOOP; END; FindMarks: PROC [design: CD.Design, predicate: CDSymbolicObjects.InstEnumerator_NIL] RETURNS [pq: PriorityQueue.Ref] = { pq _ PriorityQueue.Create[SortPred]; FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF CDSymbolicObjects.IsMark[w.first.ob] AND (predicate=NIL OR predicate[w.first]) THEN PriorityQueue.Insert[pq, w.first]; ENDLOOP; }; SelectPMarksComm: PROC [comm: CDSequencer.Command] = { cnt: INT _ 0; FOR w: CD.InstanceList _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO IF CDSymbolicObjects.IsMark[w.first.ob] AND FromPS[w.first] THEN IF ~w.first.selected THEN { w.first.selected _ TRUE; cnt _ cnt+1; CDOps.RedrawInstance[comm.design, w.first, FALSE] }; ENDLOOP; TerminalIO.WriteF["add-select curve control marks; %g more mark(s) selected\n ", [integer[cnt]]]; MarksStatistic[comm.design]; }; RemOwnerComm: PROC [comm: CDSequencer.Command] = { Write[" remove owner of marks\n"]; FOR w: CD.InstanceList _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO IF w.first.selected AND CDSymbolicObjects.IsMark[w.first.ob] THEN CDSymbolicObjects.SetOwner[w.first, NIL]; ENDLOOP; }; SetOwnerComm: PROC [comm: CDSequencer.Command] = { Write[" convert marks to curve control marks\n"]; FOR w: CD.InstanceList _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO IF w.first.selected AND CDSymbolicObjects.IsMark[w.first.ob] THEN IF ~FromPS[w.first] THEN SetOrder[w.first]; ENDLOOP; }; MarksStatisticComm: PROC [comm: CDSequencer.Command] = { Write["count marks: "]; MarksStatistic[comm.design]; }; MarksStatistic: PROC [design: CD.Design] = { oMcnt, pMcnt, oXcnt, notSelPMcnt: INT _ 0; FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF w.first.selected THEN { IF CDSymbolicObjects.IsMark[w.first.ob] THEN IF FromPS[w.first] THEN pMcnt _ pMcnt+1 ELSE oMcnt _ oMcnt +1 ELSE oXcnt _ oXcnt + 1 } ELSE IF CDSymbolicObjects.IsMark[w.first.ob] AND FromPS[w.first] THEN notSelPMcnt _ notSelPMcnt+1; ENDLOOP; TerminalIO.WriteF[" %g curve control marks", [integer[pMcnt]]]; IF oMcnt#0 THEN TerminalIO.WriteF[" %g other-marks", [integer[oMcnt]]]; IF oXcnt#0 THEN TerminalIO.WriteF[" %g other-objects", [integer[oXcnt]]]; Write[" selected"]; IF notSelPMcnt#0 THEN TerminalIO.WriteF[" %g curve control marks NOT selected", [integer[notSelPMcnt]]]; TerminalIO.WriteLn[]; }; ConvertPSToMarks: PROC [comm: CDSequencer.Command] = BEGIN i: CD.Instance _ CDCommandOps.TheInstance[comm, "split up curve object"]; IF i#NIL THEN { IF CDCurves.IsPolygon[i.ob] OR CDCurves.IsSpline[i.ob] OR CDCurves.IsFilledCurve[i.ob] OR CDCurves.IsLine[i.ob] THEN { cp: CDCurves.CurvePtr _ NARROW[i.ob.specificRef]; cnt: INT _ 0; oldPoints: LP _ OrientedPoints[i]; CDOps.RemoveInstance[comm.design, i]; FOR pl: LP _ oldPoints, pl.rest WHILE pl#NIL DO r: CD.Rect _ CDBasics.RectAt[[pl.first.x-cp.w/2, pl.first.y-cp.w/2], [0, 0]]; si: CD.Instance _ CDSymbolicObjects.CreateSymInst[denotes: r, layer: i.ob.layer]; SetOrder[si]; si.selected _ TRUE; CDOps.IncludeInstance[comm.design, si]; ENDLOOP; } ELSE Write["selected ob is neither polygon nor spline; not done\n"]; }; END; Selected: CDSymbolicObjects.InstEnumerator ={ RETURN [inst.selected] }; FromPS: CDSymbolicObjects.InstEnumerator ={ RETURN [CDSymbolicObjects.GetOwner[inst]=$CurveControl] }; SelectedOrFromPS: CDSymbolicObjects.InstEnumerator ={ RETURN [inst.selected OR CDSymbolicObjects.GetOwner[inst]=$CurveControl] }; SortPred: PriorityQueue.SortPred = { RETURN [ Rope.Compare[ CDSymbolicObjects.GetName[NARROW[x]], CDSymbolicObjects.GetName[NARROW[y] ], FALSE] < equal]; }; MarksToPSComm: PROC [comm: CDSequencer.Command] = BEGIN MarksToPS: PROC [design: CD.Design, pq: PriorityQueue.Ref, layer: CD.Layer, key: ATOM, w: CD.Number _ 0] = { ob: CD.Object; offset: CD.Position; pl: LIST OF CD.Position _ NIL; SELECT key FROM $s => {w _ (w+1)/2*2}; $p => {w _ 0}; $l => {w _ (w+1)/2*2}; $f => {w _ 0}; ENDCASE => ERROR; FOR c: INT IN [0..PriorityQueue.Size[pq]) DO i: CD.Instance _ NARROW[PriorityQueue.Remove[pq]]; pos: CD.Position _ CDBasics.BaseOfRect[CDSymbolicObjects.Denotes[i]]; pl _ CONS[[pos.x+w/2, pos.y+w/2], pl]; CDOps.RemoveInstance[design, i]; ENDLOOP; SELECT key FROM $s => [ob: ob, offset: offset] _ CDCurves.CreateSpline[pl, w, layer]; $p => [ob: ob, offset: offset] _ CDCurves.CreatePolygon[pl, layer]; $l => [ob: ob, offset: offset] _ CDCurves.CreateLine[pl, w, layer]; $f => [ob: ob, offset: offset] _ CDCurves.CreateFilledCurve[pl, layer]; ENDCASE => ERROR; IF ob=NIL THEN Write[" not done\n"] ELSE CDOps.IncludeObjectI[design, ob, offset]; }; key: ATOM; min: INT; predicate: CDSymbolicObjects.InstEnumerator; pq: PriorityQueue.Ref; Write[" convert marks to "]; IF comm.n<=1 THEN SELECT comm.key FROM $MakeSplineS => {Write["[0 size spline] "]; comm.key _ $MakeFilledCurveS}; $MakeLineS => {Write["[0 size line] "]; comm.key _ $MakePolygonS}; $MakeSplineB => {Write["[0 size spline] "]; comm.key _ $MakeFilledCurveB}; $MakeLineB => {Write["[0 size line] "]; comm.key _ $MakePolygonB}; ENDCASE => NULL; SELECT comm.key FROM $MakePolygonS => { Write["polygon (selected)"]; predicate _ Selected; key _ $p; min _ 3}; $MakeSplineS => {Write["spline (selected)"]; predicate _ Selected; key _ $s; min _ 4; min _ 4}; $MakeLineS => { Write["line (selected)"]; predicate _ Selected; key _ $l; min _ 2}; $MakeFilledCurveS => { Write["filled curve (selected)"]; predicate _ Selected; key _ $f; min _ 4}; $MakePolygonB => { Write["polygon (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $p; min _ 3}; $MakeSplineB => { Write["spline (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $s; min _ 4}; $MakeLineB => { Write["line (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $l; min _ 2}; $MakeFilledCurveB => { Write["filled curve (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $f; min _ 4}; ENDCASE => {Write["failed\n"]; RETURN}; pq _ FindMarks[comm.design, predicate]; IF pq.Size[] lr.number, ENDCASE => CDLayers.CurrentLayer[design]; new.layer _ CDLayers.AbstractToPaint[layer]; new.properties _ NIL; inst.ob _ new; repaintMe _ TRUE; END; CDSequencer.ImplementCommand[$DrawPolygonMark, DrawControlMarkComm]; CDSequencer.ImplementCommand[$PolygonRenumber, RenameMarkComm]; CDSequencer.ImplementCommand[$SplitPolygon, ConvertPSToMarks,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakePolygonS, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakePolygonB, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakeLineS, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakeLineB, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakeFilledCurveS, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakeFilledCurveB, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakeSplineS, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MakeSplineB, MarksToPSComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$RSelPMarks, SelectPMarksComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$SetOwnMarkP, SetOwnerComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$RemOwnMarkP, RemOwnerComm,, doQueueAndMark]; CDSequencer.ImplementCommand[$MStatC, MarksStatisticComm,, doQueue]; CDCallSpecific.Register[$ChangeLayer, CDCurves.splineClass, ChangeLayer]; CDCallSpecific.Register[$ChangeLayer, CDCurves.lineClass, ChangeLayer]; CDCallSpecific.Register[$ChangeLayer, CDCurves.polygonClass, ChangeLayer]; CDCallSpecific.Register[$ChangeLayer, CDCurves.filledCurveClass, ChangeLayer]; END. 4CDCurvesCommands.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, March 30, 1985 12:19:40 pm PST Last Edited by: Christian Jacobi, August 24, 1986 8:11:28 pm PDT OldDrawPolygonComm: PROC [comm: CDSequencer.Command] = BEGIN ob: CD.Object; offset: CD.Position; p1: CD.Position _ comm.sPos; --from p2: CD.Position _ comm.pos; --to points: LIST OF CD.Position; Write["Draw a polygon\n"]; IF ABS[p1.x-p2.x]<4 THEN p2.x _ p1.x+10; IF ABS[p1.y-p2.y]<4 THEN p2.y _ p1.y+10; points _ LIST[p1, p2, [p2.x, p1.y]]; [ob, offset] _ CDCurves.CreatePolygon[points, comm.l]; IF ob=NIL THEN Write[" not done\n"] ELSE CDOps.IncludeObjectI[comm.design, ob, offset] END; --returns th square of the distance --returns some bad hack representing distance --to is ignored --inst must be instance of a curve object StretchPolygonComm: PROC [comm: CDSequencer.Command] = BEGIN inst: CD.Instance; p: PROC [points: LP, from, to: CD.Position] RETURNS [LP]; r: Rope.ROPE; SELECT comm.key FROM $MovePolygonPoint => {p _ StretchPoints; r _ "stretch polygon"}; $AddPolygonPoint => {p _ IncludePoint; r _ "add point to polygon"}; $RemovePolygonPoint => {p _ RemovePoint; r _ "remove point from polygon"}; ENDCASE => {Write["unknown command\n"]; RETURN}; inst _ CDCommandOps.TheInstance[comm, r]; IF inst#NIL THEN { WITH inst.ob.specificRef SELECT FROM t: CDCurves.CurvePtr => { offset: CD.Position; ob: CD.Object; oldPoints: LP _ OrientedPoints[inst]; newPoints: LP _ p[oldPoints, comm.sPos, comm.pos]; [ob: ob, offset: offset] _ CDCurves.CreatePolygon[newPoints, inst.ob.layer]; IF ob=NIL THEN {Write[" not done\n"]; RETURN}; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[inst]]; inst.ob _ ob; inst.orientation _ CD.original; inst.location _ offset; CDOps.DelayedRedraw[comm.design, CDInstances.InstRectO[inst], FALSE]; } ENDCASE => Write["selected ob is not polygon; not done\n"]; }; END; --at this point we have to now the class implementation --to know that the specifiRref field is treated readonly... --old command set CDSequencer.ImplementCommand[$DrawPolygon, OldDrawPolygonComm]; CDSequencer.ImplementCommand[$MovePolygonPoint, StretchPolygonComm]; CDSequencer.ImplementCommand[$AddPolygonPoint, StretchPolygonComm]; CDSequencer.ImplementCommand[$RemovePolygonPoint, StretchPolygonComm]; --new command set Κ˜codešœ™Kšœ Οmœ7™BKšœ<™Kšžœ˜—K˜š   œžœžœ žœ žœ˜OKšž˜Kšœžœ˜ Kšœžœ˜ Kšœžœžœžœ˜šžœžœžœžœ˜*Kšœžœ˜$Kšœ ˜ Kšžœžœ˜!Kšžœ˜—šžœžœžœ ž˜Kšœžœ˜Kšœ˜Kšžœ˜—Kšœžœ ˜Kšœ˜šžœžœžœžœ˜*Kšœžœ˜Kšžœ˜—Kšžœ˜—K˜š   œžœžœ žœ žœ˜NKšž˜Kšœžœ˜Kšœžœ˜ Kšœžœžœžœ˜Kšœžœ ˜Kšœžœ˜š žœžœžœžœžœžœ˜9Kšœ/˜/Kšœ˜Kšœ ˜ Kšžœžœ˜#Kšžœ˜—Kšœ,˜,Kšžœžœ ˜šžœžœžœ ž˜Kšœžœ˜Kšœ˜Kšžœ˜—Kšœžœ ˜šžœžœžœžœ˜*Kšœžœ˜Kšžœ˜—Kšžœ˜—K˜š   œžœžœ žœ žœ˜MKšœ™Kšž˜Kšœžœ˜ Kšœžœ˜ Kšœžœžœžœ˜šžœžœžœžœ˜*Kšœžœ˜$Kšœ ˜ Kšžœžœ˜!Kšžœ˜—šžœžœžœ ž˜Kšœžœ˜Kšœ˜Kšžœ˜—Kšžœžœ˜#Kšžœ,˜0šžœžœžœžœ˜*Kšœžœ˜Kšžœ˜—Kšž˜—K˜š  œžœžœ ˜0šžœžœžœžœ˜&Kšœ(˜(Kšžœ˜—K˜—K˜š  œžœžœ žœ žœ˜AKšœ)™)Kšž˜Kšœ˜šžœžœž˜$Kšœ(˜(Kšžœžœ˜—šžœžœžœžœ˜&šœ žœ˜+Kšœ˜Kšœ˜Kšœ!˜!Kšœ)˜)—Kšœžœ˜Kšžœ˜—Kšžœ˜—K˜š   œžœ žœ5žœžœ˜xKšœ$˜$š žœžœ/žœžœž˜Fš žœ&žœ žœžœžœ˜XKšœ"˜"—Kšžœ˜—Kšœ˜—K˜š œžœ ˜6Kšœžœ˜ š žœžœ4žœžœž˜Kšžœ&žœžœ˜Bšžœžœ˜Kšœžœ˜%Kšœ+žœ˜1K˜——Kšžœ˜—Kšœb˜bKšœ˜K˜—K˜š  œžœ ˜2Kšœ"˜"š žœžœ4žœžœž˜Kšžœžœ&žœ˜CKšœ$žœ˜)—Kšžœ˜—K˜—K˜š  œžœ ˜2Kšœ1˜1š žœžœ4žœžœž˜Kšžœžœ&žœ˜CKšžœžœ˜+—Kšžœ˜—K˜—K˜š œžœ ˜8Kšœ˜Kšœ˜Kšœ˜—K˜š œžœ žœ ˜,Kšœ"žœ˜*š žœžœ/žœžœž˜Fšžœžœ˜šžœ&ž˜,Kšžœžœ˜'Kšžœ˜—Kšžœ˜Kšœ˜—šžœžœ&žœžœ˜FKšœ˜—Kšžœ˜—Kšœ?˜?Kšžœ žœ8˜GKšžœ žœ:˜IKšœ˜KšžœžœS˜hKšœ˜Kšœ˜—K˜š œžœ˜4Kšž˜KšœžœD˜Išžœžœžœ˜š žœžœžœžœžœ˜vKšœžœ˜1Kšœžœ(˜0Kšœ%˜%šžœžœžœž˜/KšœžœH˜MKšœžœK˜QKšœžœ˜!Kšœ'˜'Kšžœ˜—K˜—Kšžœ@˜DKšœ˜—Kšžœ˜—K˜š œ%˜-Kšžœ˜Kšœ˜—K˜š œ%˜+Kšžœ1˜7Kšœ˜—K˜š œ%˜5Kšžœžœ0˜HKšœ˜—K˜š œ˜$Kšžœ+žœ žœžœ ˜tK˜—K˜š  œžœ˜1Kšž˜K˜š   œžœ žœ'žœ žœžœ˜lKš œžœžœžœžœžœ žœ˜Bšžœž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜—šžœžœžœž˜,Kšœžœ žœ˜2Kšœžœ>˜EKšœžœ˜&Kšœ ˜ Kšžœ˜—šžœž˜KšœE˜EKšœC˜CKšœžœ=˜CKšœG˜GKšžœžœ˜—Kšžœžœžœ˜$Kšžœ*˜.Kšœ˜—K˜Kšœžœ ˜Kšœ,˜,Kšœ˜Kšœ˜šžœ ž˜šžœ ž˜KšœJ˜JKšœB˜BKšœJ˜JKšœB˜BKšžœžœ˜——šžœ ž˜šœ˜KšœF˜F—Kšœ_˜_šœ˜KšœC˜C—šœ˜KšœK˜K—šœ˜KšœU˜U—šœ˜KšœT˜T—šœ˜KšœR˜R—šœ˜KšœZ˜Z—Kšžœžœ˜'—Kšœ'˜'KšžœžœD˜YKšžœ1˜5Kšžœ˜—K˜š œžœ™6Kšž™Kšœžœ ™Kšœžœžœ žœ™9Kšœžœ™ šžœ ž™Kšœ@™@KšœC™CKšœJ™JKšžœ žœ™0—Kšœ)™)šžœžœžœ™šžœžœž™$šœ™Kšœžœ ™Kšœžœ™Kšœ%™%Kšœ2™2KšœL™LKšžœžœžœžœ™/Kšœ>™>Kšœ ™ Kšœžœ ™Kšœ™Kšœ>žœ™EK™—Kšžœ4™;—Kšœ™—Kšžœ™—K˜Kšœžœ˜ K˜š œžœžœ˜&Kšœ0˜0Kšœ žœ,˜NK˜—K˜š œžœ˜7Kšžœ˜Kšœžœ ˜Kšœžœ*˜/Kšœ%˜%Kšœ3˜3Kšœ˜Kšœ)˜)Kšžœ˜—K˜š œžœ˜2Kšžœ˜Kšœ/˜/š žœžœ4žœžœž˜Kšžœžœ˜Kšžœ&žœžœ ˜cKšžœ˜Kšœ˜—Kšžœ˜—Kšœ˜Kšžœ˜—K˜šΠbn œ˜&Kšž˜Kšœ7™7Kšœ;™;Kšœžœžœ˜,šœžœ žœžœž˜$Kšœ$˜$Kšžœ"˜)—Kšœ,˜,Kšœžœ˜Kšœ˜Kšœ žœ˜Kšžœ˜K˜—Kšœ™™Kšœ?™?KšœD™DKšœC™CšœF™FK™——Kšœ™K˜KšœD˜DKšœ?˜?KšœO˜OK˜KšœL˜LKšœL˜LKšœI˜IKšœI˜IKšœP˜PKšœP˜PKšœK˜KKšœK˜KK˜KšœM˜MKšœJ˜JKšœJ˜JKšœD˜DK˜KšœI˜IKšœG˜GKšœJ˜JKšœN˜NKšžœ˜K˜K˜—…—-ψG»