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 ำ 1985, 1992 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 ]; ส =•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ฯeœ6™BKšœ.™.K™,K™K™(—K˜šฯk ˜ Kšœžœ ˜Kšœžœžœ˜(KšœžœG˜PKšœ ˜ K˜Kšœ ˜ —K˜šะbl œžœž˜Kšžœ˜Kšžœ ˜—Kšž˜K˜šœžœ˜šœžœžœžœ™K™K™Kšœžœ™Kšœ žœฯcD™SKšœžœžœ™K™K™——Kšœžœ˜+Kšœ žœ˜)Kšœ žœ˜'Kšœ žœ˜'Kšœ žœ˜!Kšœ žœ˜#Kšžœžœ žœ˜K™K˜šฯnœžœžœžœ˜0šœ žœ˜Kšœžœ˜Kšœžœ˜(Kšœžœ˜K˜ Kšœžœ˜Kšœž˜ K˜—K˜K˜—šกœžœžœ˜.Kšœ žœ˜ K˜˜>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˜3Kšœ6˜6Kšžœžœžœ/˜MKšžœžœ.˜˜qKšœžœ˜ Kšœ#žœžœ˜Cšœ"˜"šžœžœ˜K˜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˜š ก œžœžœžœžœ˜