DIRECTORY Cubic USING [Bezier], Complex USING [VEC, Sub, Abs, Mul, Add], Seq USING [ComplexSequence, ComplexSequenceRec,JointSequence, JointSequenceRec], FitBasic, FitStateUtils, FitState; FitStateImpl: CEDAR PROGRAM IMPORTS Complex, FitStateUtils EXPORTS FitState = BEGIN Handle: TYPE = FitBasic.Handle; SampleHandle: TYPE = FitBasic.SampleHandle; SListHandle: TYPE = FitBasic.SListHandle; LinkHandle: TYPE = FitBasic.LinkHandle; TrajHandle: TYPE = FitBasic.TrajHandle; Contour: TYPE = FitBasic.Contour; DataType: TYPE = FitState.DataType; VEC: TYPE = Complex.VEC; Create: PUBLIC PROC RETURNS [handle: Handle] = { handle _ NEW[FitBasic.Rec _ [ traj: NEW[FitBasic.Traj], slist: NEW[FitBasic.SList _ NewSList[]], closed: FALSE, minDist: 0, otherContours: NIL, undo: NIL ]]; }; NewSList: PROC RETURNS [s: FitBasic.SList] = { s.header _ NEW[FitBasic.Sample]; s.selectedSample _ s.header.next _ s.header.prev _ s.header; s.first _ NIL; s.last _ NIL; }; UnlinkSamples: PROC[slist: SListHandle] = { IF slist#NIL AND slist.header#NIL THEN { s,t: SampleHandle; s _ slist.header.next; UNTIL s = slist.header DO t _ s.next; s.next _ s.prev _ NIL; s _ t; ENDLOOP; slist.header.next _ slist.header.prev _ NIL; }; }; UnlinkLinks: PROC[traj: TrajHandle] = { IF traj #NIL THEN { l,t: LinkHandle; l _ traj.links; UNTIL l=NIL DO t _ l.next; l.next _l.prev _ NIL; l _ t; ENDLOOP; }; }; ResetData: PUBLIC PROC[handle: Handle, type: DataType, all: BOOLEAN _ FALSE] = { SELECT type FROM samples => { reset: FitStateUtils.SListProc = { UnlinkSamples[slist]; slist^ _ NewSList[]; }; [] _ reset[handle.slist]; IF all THEN FitStateUtils.ForAllOtherSLists[handle,reset]; }; links => { reset: FitStateUtils.TrajProc = { UnlinkLinks[traj]; traj.links _ NIL; traj.lastLink _ NIL; }; [] _ reset[handle.traj]; IF all THEN FitStateUtils.ForAllOtherTrajs[handle,reset]; }; joints => { reset: FitStateUtils.SListProc = {FitStateUtils.ForAllSamples[handle.slist, ResetJoint]}; [] _ reset[handle.slist]; IF all THEN FitStateUtils.ForAllOtherSLists[handle,reset]; }; contours => { ResetData[handle, samples, all]; ResetData[handle, links, all]; IF all THEN handle.otherContours _ NIL; }; ENDCASE => ERROR; }; ScaleData: PUBLIC PROC[handle: Handle, scale: REAL, type: DataType, all: BOOLEAN _ FALSE] = { XFormData[handle: handle, scale: [scale,scale], type: type, all: all]; }; TranslateData: PUBLIC PROC[handle: Handle, trans: VEC, type: DataType, all: BOOLEAN _ FALSE] = { XFormData[handle: handle, trans: trans, type: type, all: all]; }; XFormData: PROC[handle: Handle, scale: VEC _ [1,1], trans: VEC _ [0,0], type: DataType, all: BOOLEAN _ FALSE] = { xformSample: FitStateUtils.SampleProc = { p: VEC _ s.xy; s.xy _ Complex.Mul[p,scale]; p _ s.tanIn; s.tanIn _ Complex.Mul[p,scale]; p _ s.tanOut; s.tanOut _ Complex.Mul[p,scale]; }; SELECT type FROM samples => { xform: FitStateUtils.SListProc = {FitStateUtils.ForAllSamples[handle.slist,xformSample]}; [] _ xform[handle.slist]; IF all THEN FitStateUtils.ForAllOtherSLists[handle,xform]; }; links => { xform: FitStateUtils.LinkProc = { cubic: Cubic.Bezier _ l.cubic; l.cubic.b0 _ Complex.Add[Complex.Mul[scale,cubic.b0], trans]; l.cubic.b1 _ Complex.Add[Complex.Mul[scale,cubic.b1], trans]; l.cubic.b2 _ Complex.Add[Complex.Mul[scale,cubic.b2], trans]; l.cubic.b3 _ Complex.Add[Complex.Mul[scale,cubic.b3], trans]; }; do: FitStateUtils.TrajProc = {FitStateUtils.ForAllLinks[handle.traj,xform]}; [] _ do[handle.traj]; IF all THEN FitStateUtils.ForAllOtherTrajs[handle,do]; }; joints => { xform: FitStateUtils.SampleProc = {IF s.jointType#none THEN [] _ xformSample[s]}; do: FitStateUtils.SListProc = {FitStateUtils.ForAllSamples[handle.slist,xform]}; [] _ do[handle.slist]; IF all THEN FitStateUtils.ForAllOtherSLists[handle,do]; }; contours => { XFormData[handle, scale, trans, samples, all]; XFormData[handle, scale, trans, links, all]; }; ENDCASE => ERROR; }; AddSample: PUBLIC PROC[handle: Handle, x,y: REAL, joint: FitBasic.JointType _ none, tanIn,tanOut: Complex.VEC _ [0,0]] = { IF Complex.Abs[Complex.Sub[[x,y],handle.slist.header.prev.xy]]>handle.minDist THEN { update: BOOLEAN _ handle.slist.last=handle.slist.header.prev OR handle.slist.last=NIL; handle.slist.selectedSample _ handle.slist.header; InsertBeforeSample[handle, x,y, joint, tanIn, tanOut]; IF handle.slist.first=NIL THEN handle.slist.first _ handle.slist.header.next; IF update THEN handle.slist.last _ handle.slist.header.prev; }; }; RemoveSample: PUBLIC PROC[handle: Handle] = { IF handle.slist#NIL AND handle.slist.selectedSample # handle.slist.header THEN { sample: SampleHandle _ handle.slist.selectedSample; handle.slist.selectedSample _ sample.next; IF handle.slist.first=sample THEN handle.slist.first _ sample.next; IF handle.slist.last=sample THEN handle.slist.last _ sample.next; sample.prev.next _ sample.next; sample.next.prev _ sample.prev; sample.next _ sample.prev _ NIL; }; }; InsertBeforeSample: PUBLIC PROC[handle: Handle, x,y: REAL, joint: FitBasic.JointType _ none, tanIn,tanOut: Complex.VEC _ [0,0]] = { IF handle.slist#NIL THEN { s: SampleHandle _ handle.slist.selectedSample; new: SampleHandle _ NEW[FitBasic.Sample _ [ next: s, prev: s.prev, xy: [x,y], jointType: joint, tanIn: tanIn, tanOut: tanOut]]; s.prev _ new; new.prev.next _ new; handle.slist.selectedSample _ new; }; }; AddLink: PUBLIC PROC[handle: Handle, b: Cubic.Bezier] = { new: LinkHandle _ NEW[FitBasic.Link]; new.cubic _ b; IF handle.traj.links=NIL THEN { handle.traj.links _ new; handle.traj.lastLink _ new; } ELSE { handle.traj.lastLink.next _ new; new.prev _ handle.traj.lastLink; handle.traj.lastLink _ new; }; }; SetJoint: PUBLIC PROC[handle: Handle, index: NAT, joint: FitBasic.JointType _ potential, tanIn,tanOut: Complex.VEC _ [0,0]] = { i:NAT _ 0; FOR s: SampleHandle _ handle.slist.header.next, s.next UNTIL s=handle.slist.header DO IF i=index THEN {s.jointType _ joint; s.tanIn _ tanIn; s.tanOut _ tanOut; EXIT}; i_i+1; ENDLOOP; }; ResetJoint: FitStateUtils.SampleProc = { s.jointType _ none; s.tanIn _ s.tanOut _ [0,0]; }; NewContour: PUBLIC PROC[handle: Handle] = { IF handle.otherContours = NIL THEN handle.otherContours _ LIST[[handle.traj, handle.slist]] ELSE { p: LIST OF Contour _ handle.otherContours; UNTIL p.rest = NIL DO p _ p.rest ENDLOOP; p.rest _ LIST[[handle.traj, handle.slist]]; }; handle.slist _ NEW[FitBasic.SList _ NewSList[]]; handle.traj _ NEW[FitBasic.Traj]; }; NextContour: PUBLIC PROC[handle: Handle] = { IF handle.otherContours # NIL THEN { p: LIST OF Contour _ handle.otherContours; ts: Contour _ handle.otherContours.first; handle.otherContours.first _ [handle.traj, handle.slist]; [handle.traj, handle.slist] _ ts; UNTIL p.rest = NIL DO p _ p.rest ENDLOOP; p.rest _ handle.otherContours; -- make it circular for a few microseconds p _ p.rest; handle.otherContours _ p.rest; p.rest _ NIL; } }; CurrentJoints: PUBLIC PROC [handle: Handle] RETURNS[joints: Seq.JointSequence, tangents: Seq.ComplexSequence] = { i,n:NAT _ 0; count: FitStateUtils.SampleProc = {IF s.jointType#none THEN n_n+1}; copy: FitStateUtils.SampleProc = { IF s.jointType#none THEN { joints[n] _[index: i, forced: s.jointType=forced]; tangents[2*n] _ s.tanIn; tangents[2*n+1] _ s.tanOut; n_n+1; }; i_i+1; }; FitStateUtils.ForAllSamples[handle.slist,count]; joints _ IF n>0 THEN NEW[Seq.JointSequenceRec[n]] ELSE NIL; tangents _ IF n>0 THEN NEW[Seq.ComplexSequenceRec[2*n]] ELSE NIL; i _ n _ 0; FitStateUtils.ForAllSamples[handle.slist,copy]; }; CurrentSamples: PUBLIC PROC[handle: Handle] RETURNS [z: Seq.ComplexSequence] = { i,n:NAT _ 0; count: FitStateUtils.SampleProc = {n_n+1}; copy: FitStateUtils.SampleProc = { z[i] _ s.xy; i_i+1; }; FitStateUtils.ForAllSamples[handle.slist,count]; z _ NEW[Seq.ComplexSequenceRec[n]]; i _ 0; FitStateUtils.ForAllSamples[handle.slist,copy]; }; EnumerateLinks: PUBLIC PROC[handle: Handle, newContour: PROC[x,y: REAL], newCubic: PROC[c: Cubic.Bezier]] = { trajProc: FitStateUtils.TrajProc = { newContour[traj.links.cubic.b0.x, traj.links.cubic.b0.y]; FitStateUtils.ForAllLinks[traj,callCubic]; }; callCubic: FitStateUtils.LinkProc = {newCubic[l.cubic]}; --there's a defaulted return[false] FitStateUtils.ForAllTrajs[handle, trajProc]; }; EnumerateSamples: PUBLIC PROC[handle: Handle, newContour: PROC[x,y: REAL], newSample: PROC[x,y: REAL]] = { first: BOOLEAN _ TRUE; slistProc: FitStateUtils.SListProc = { first _ TRUE; FitStateUtils.ForAllSamples[slist,callNewSample]; }; callNewSample: FitStateUtils.SampleProc = { IF first THEN {newContour[s.xy.x, s.xy.y]; first _ FALSE} ELSE newSample[s.xy.x, s.xy.y]; }; FitStateUtils.ForAllSLists[handle, slistProc]; }; CountContours: PUBLIC PROC[handle: Handle] RETURNS [INT] = { i: INT _ 1; FOR p: LIST OF Contour _ handle.otherContours, p.rest UNTIL p=NIL DO i_i+1 ENDLOOP; RETURN[i] }; END. ¦FitStateImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Maureen Stone February 14, 1985 5:18:35 pm PST Doug Wyatt, September 5, 1985 1:58:49 pm PDT Changes the state of the FitState.Handle Rec: PUBLIC TYPE = RECORD [ traj: TrajHandle, slist: SListHandle, closed: BOOLEAN, minDist: REAL, --affects AddSample. Won't add a new sample inside of this distance otherContours: LIST OF Contour ]; Κ u˜codešœ™Kšœ Οmœ1™˜>K˜—š ‘ œžœžœžœžœžœ˜qšœ)˜)Kšœžœ˜K˜K˜ K˜K˜ K˜ K˜K˜—šžœž˜˜ KšœY˜YKšœ˜Kšžœžœ/˜:K˜—šœ ˜ šœ!˜!K˜Kšœ=˜=Kšœ=˜=Kšœ=˜=Kšœ=˜=Kšœ˜—KšœL˜LK˜Kšžœžœ+˜6K˜—šœ ˜ Kšœ#žœžœ˜QKšœP˜PK˜Kšžœžœ,˜7K˜—šœ ˜ K˜.K˜,K˜—Kšžœžœ˜—K˜K˜—š ‘ œžœžœžœ:žœ ˜zšžœLž˜TKšœžœ.žœžœ˜VKšœ3˜3Kšœ6˜6Kšžœžœžœ/˜MKšžœžœ.˜˜qKšœžœ˜ Kšœ#žœžœ˜Cšœ"˜"šžœžœ˜Kšœ2˜2Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜Kšœ˜—K˜0Kš œ žœžœžœžœžœ˜;Kš œ žœžœžœžœžœ˜AK˜ K˜/K˜K˜—K˜š‘œžœžœžœ˜PKšœžœ˜ Kšœ*˜*šœ"˜"K˜ K˜Kšœ˜—K˜0Kšœžœ˜#K˜K˜/K˜K˜—K˜š ‘œžœžœžœžœ žœ˜m˜$K˜9K˜*K˜—Kšœ9 #˜\K˜,K˜K˜—š ‘œž œžœžœžœžœ˜jKšœžœžœ˜˜&Kšœžœ˜ Kšœ1˜1K˜—šœ+˜+Kšžœžœ&žœ˜9Kšžœ˜Kšœ˜—K˜.K˜—K˜š ‘ œžœžœžœžœ˜