<> <> <> <> <<>> DIRECTORY CD, CDInstances, CDBasics, CDCurves, CDOps, CDPrivate, CDSequencer, CDSymbolicObjects, IO, PriorityQueue, Real, Rope, TerminalIO; CDCurvesCommands: CEDAR PROGRAM IMPORTS CDBasics, CDCurves, CDOps, CDSequencer, CDSymbolicObjects, IO, PriorityQueue, Real, Rope, TerminalIO SHARES CDCurves = BEGIN LP: TYPE = LIST OF CD.Position; DistanceSq: PROC[p1, p2: CD.Position] RETURNS [REAL] = { <<--returns th square of the distance>> 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] }; Distance: PROC [p1, p2: CD.Position] RETURNS [REAL] = { RETURN [Real.SqRt[DistanceSq[p1, p2]]] }; DistancePairP: PROC[p1, p2, p: CD.Position] RETURNS [REAL] = { <<--returns some bad hack representing distance>> RETURN [ABS[Distance[p1, p]+Distance[p2, p]-Distance[p2, p1]]] }; StretchPoints: PROC [points: LP, from, to: CD.Position] RETURNS [new: LP_NIL] = { 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 d> 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 TerminalIO.PutRope["degenerated polygon not created\n"]; FOR p: LP _ points, p.rest WHILE p#NIL DO new _ CONS[p.first, new]; ENDLOOP; }; 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] = { <<--inst must be instance of a curve object>> pl: LP; WITH inst.ob.specific SELECT FROM cp: CDCurves.CurveSpecific => pl _ cp.points; ENDCASE => ERROR; FOR p: LP _ pl, p.rest WHILE p#NIL DO orientedP: CD.Position = CDBasics.MapPoint[p.first, inst.trans].pointInWorld; copy _ CONS[orientedP, copy]; ENDLOOP; }; 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.PutF["add-select curve control marks; %g more mark(s) selected\n ", [integer[cnt]]]; MarksStatistic[comm.design]; }; RemOwnerComm: PROC [comm: CDSequencer.Command] = { TerminalIO.PutRope[" 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] = { TerminalIO.PutRope[" 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] = { TerminalIO.PutRope["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.PutF[" %g curve control marks", [integer[pMcnt]]]; IF oMcnt#0 THEN TerminalIO.PutF[" %g other-marks", [integer[oMcnt]]]; IF oXcnt#0 THEN TerminalIO.PutF[" %g other-objects", [integer[oXcnt]]]; TerminalIO.PutRope[" selected"]; IF notSelPMcnt#0 THEN TerminalIO.PutF[" %g curve control marks NOT selected", [integer[notSelPMcnt]]]; TerminalIO.PutRope["\n"]; }; ConvertPSToMarks: PROC [comm: CDSequencer.Command] = { i: CD.Instance _ CDOps.TheInstance[comm.design, "split up curve object\n"]; 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.CurveSpecific _ NARROW[i.ob.specific]; 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 TerminalIO.PutRope["selected ob is neither polygon nor spline; not done\n"]; }; }; 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 TerminalIO.PutRope[" not done\n"] ELSE CDOps.IncludeObjectI[design, ob, offset]; }; key: ATOM; min: INT; predicate: CDSymbolicObjects.InstEnumerator; pq: PriorityQueue.Ref; TerminalIO.PutRope[" convert marks to "]; IF comm.n<=1 THEN SELECT comm.key FROM $MakeSplineS => { TerminalIO.PutRope["[0 size spline] "]; comm.key _ $MakeFilledCurveS}; $MakeLineS => { TerminalIO.PutRope["[0 size line] "]; comm.key _ $MakePolygonS}; $MakeSplineB => { TerminalIO.PutRope["[0 size spline] "]; comm.key _ $MakeFilledCurveB}; $MakeLineB => { TerminalIO.PutRope["[0 size line] "]; comm.key _ $MakePolygonB}; ENDCASE => NULL; SELECT comm.key FROM $MakePolygonS => { TerminalIO.PutRope["polygon (selected)"]; predicate _ Selected; key _ $p; min _ 3}; $MakeSplineS => { TerminalIO.PutRope["spline (selected)"]; predicate _ Selected; key _ $s; min _ 4; min _ 4}; $MakeLineS => { TerminalIO.PutRope["line (selected)"]; predicate _ Selected; key _ $l; min _ 2}; $MakeFilledCurveS => { TerminalIO.PutRope["filled curve (selected)"]; predicate _ Selected; key _ $f; min _ 4}; $MakePolygonB => { TerminalIO.PutRope["polygon (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $p; min _ 3}; $MakeSplineB => { TerminalIO.PutRope["spline (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $s; min _ 4}; $MakeLineB => { TerminalIO.PutRope["line (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $l; min _ 2}; $MakeFilledCurveB => { TerminalIO.PutRope["filled curve (selected+origin)"]; predicate _ SelectedOrFromPS; key _ $f; min _ 4}; ENDCASE => {TerminalIO.PutRope["failed\n"]; RETURN}; pq _ FindMarks[comm.design, predicate]; IF pq.Size[]