ContoursSimilarImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, September 19, 1986 4:01:41 pm PDT
DIRECTORY Commander, Controls, Contours, Draw2d, Imager, ImagerBackdoor, IO, TIPUser, Vector2, ViewerClasses, ViewerOps;
ContoursSimilarImpl: CEDAR PROGRAM
IMPORTS Commander, Controls, Contours, Draw2d, ImagerBackdoor, IO, TIPUser, Vector2, ViewerOps
~ BEGIN
OPEN Contours;
Commands
ProgramData:  TYPE ~ REF ProgramDataRec;
ProgramDataRec: TYPE ~ RECORD [
outer:      Viewer ← NIL,   -- the outer (parent, top level) viewer
alpha:      Control ← NIL,   -- interpolation value
box0:      Control ← NIL,   -- control for contour0
box1:      Control ← NIL,   -- control for contour1
boxI0:      Control ← NIL,   -- control for misc. display
boxI1:      Control ← NIL,   -- control for misc. display
contour:     Contour ← NIL,   -- interpolated contour
contour0:     Contour ← NIL,   -- contour0
contour1:     Contour ← NIL,   -- contour1
save0:      Contour ← NIL,   -- to undo contour0
save1:      Contour ← NIL   -- to undo contour1
];
ContoursSimilar: Commander.CommandProc ~ {
NewControl: PROC [name: ROPE, row: NAT, proc: Controls.ControlProc, flavor: ATOM]
RETURNS [Control] ~ {
RETURN[Controls.NewControl[
name: name, type: contour, w: 150, proc: proc, data: p, row: row, flavor: flavor]];
};
p: ProgramData ← NEW[ProgramDataRec];
p.alpha ← Controls.NewControl["Alpha", vSlider, p, 0.0, 1.0, 0.5, Alpha, , , , , , , 120];
p.boxI0 ← NewControl["Interp Vs. Contour0", 0, NIL, $Similar];
p.boxI1 ← NewControl["Interp Vs. Contour1", 0, NIL, $Similar];
p.box0 ← NewControl["Contour0", 1, Contour0Changed, $Nil];
p.box1 ← NewControl["Contour1", 1, Contour1Changed, $Nil];
p.outer ← Controls.OuterViewer[
name: "Contours Similar",
controls: LIST[p.boxI0, p.boxI1, p.box0, p.box1, p.alpha],
buttons: LIST[
["Undo", Undo],
["Clear", Clear],
["Circles", Circles],
["Smooth", Smooth],
["Thin", Thin]],
data: p];
};
PrepContour: PROC [contour: Contour] RETURNS [Contour] ~ {
IF contour = NIL THEN RETURN[NIL];
contour ← Contours.Orient[contour];
contour.normals ← Contours.Normals[contour];
contour.percents ← Contours.Percents[contour];
RETURN[contour];
};
Contour0Changed: Controls.ControlProc ~ {
p: ProgramData ← NARROW[control.data];
p.contour0 ← PrepContour[Contours.FromControl[p.box0]];
Similar[p];
};
Contour1Changed: Controls.ControlProc ~ {
p: ProgramData ← NARROW[control.data];
p.contour1 ← PrepContour[Contours.FromControl[p.box1]];
Similar[p];
};
Alpha: Controls.ControlProc ~ {
IF control.mouse.state # up THEN Similar[NARROW[control.data, ProgramData]];
};
Similar: PROC [p: ProgramData] ~ {
IF Contours.ContourOK[p.contour0] AND Contours.ContourOK[p.contour1] THEN {
p.contour ← Contours.Interpolate[p.contour0, p.contour1, p.alpha.value];
p.contour.normals ← Contours.Normals[p.contour];
}
ELSE p.contour ← NIL;
ViewerOps.PaintViewer[p.boxI0.viewer, client, FALSE, NIL];
ViewerOps.PaintViewer[p.boxI1.viewer, client, FALSE, NIL];
};
PaintSimilar: ViewerClasses.PaintProc ~ {
ShowNormalsRange: PROC [c, cc: Contour] ~ {
Label: PROC [y: NAT, rope: ROPE] ~ {Draw2d.Label[context, [5, y], rope]};
Xform: PROC [p: Pair] RETURNS [Pair] ~ {RETURN[[wScale*(p.x+1), hScale*(p.y+1)]]};
DrawNormal: PROC [base, normal: Pair, scale: REAL] ~ {
Draw2d.Arrow[context, base, Vector2.Add[base, Vector2.Mul[normal, scale]]];
};
IF Contours.ContourOK[c] AND Contours.ContourOK[cc] THEN {
min: REAL ← 10000.0;
p0: Pair ← Xform[c.pairs[c.pairs.length-1]];
FOR i: NAT IN [0..c.pairs.length) DO
p1: Pair ← Xform[c.pairs[i]];
n: Pair ← c.normals[i];
nn: Pair ← Contours.PercentNormal[cc, c.percents[i]];
min ← MIN[min, Vector2.Dot[n, nn]];
DrawNormal[p1, n, 20.0];
DrawNormal[p1, nn, 30.0];
Draw2d.Line[context, p0, p1, dotted];
p0 ← p1;
ENDLOOP;
Label[135, IO.PutFR["min = %6.3f", IO.real[min]]];
Label[125, IO.PutFR["%g vs %g points", IO.int[c.pairs.length], IO.int[cc.pairs.length]]];
};
};
p: ProgramData ← NARROW[NARROW[self.data, Control].data];
bounds: Imager.Rectangle ← ImagerBackdoor.GetBounds[context];
wScale: REAL ← 0.5*(bounds.w-1.0);
hScale: REAL ← 0.5*(bounds.h-1.0);
Draw2d.Clear[context];
SELECT self FROM
p.boxI0.viewer => ShowNormalsRange[p.contour, p.contour0];
p.boxI1.viewer => ShowNormalsRange[p.contour, p.contour1];
ENDCASE;
};
ActionProc: TYPE ~ PROC [contour: Contour] RETURNS [Contour];
DoToContours: PROC [p: ProgramData, action: ActionProc] ~ {
p.save0 ← Contours.Copy[p.contour0];
p.save1 ← Contours.Copy[p.contour1];
p.contour0 ← PrepContour[action[p.contour0]];
p.contour1 ← PrepContour[action[p.contour1]];
Contours.ToControl[p.box0, p.contour0];
Contours.ToControl[p.box1, p.contour1];
Similar[p];
};
Undo: Controls.ClickProc ~ {
p: ProgramData ← NARROW[NARROW[clientData, Controls.OuterData].data];
Contours.ToControl[p.box0, p.contour0 ← p.save0];
Contours.ToControl[p.box1, p.contour1 ← p.save1];
Similar[p];
};
Clear: Controls.ClickProc ~ {
action: ActionProc ~ {RETURN[NIL]};
DoToContours[NARROW[NARROW[clientData, Controls.OuterData].data], action];
};
Circles: Controls.ClickProc ~ {
action: ActionProc ~ {
return: Contour ← Contours.Scale[Contours.Circle[4], 0.5];
return.circle ← FALSE;
RETURN[return];
};
DoToContours[NARROW[NARROW[clientData, Controls.OuterData].data], action];
};
Thin: Controls.ClickProc ~ {
action: ActionProc ~ {RETURN[Contours.Thin[contour]]};
DoToContours[NARROW[NARROW[clientData, Controls.OuterData].data], action];
};
Smooth: Controls.ClickProc ~ {
action: ActionProc ~ {RETURN[Contours.Smooth[contour]]};
DoToContours[NARROW[NARROW[clientData, Controls.OuterData].data], action];
};
ViewerOps.RegisterViewerClass[$Similar, NEW[ViewerClasses.ViewerClassRec ← [
notify: Controls.NotifyControl,
paint: PaintSimilar,
tipTable: TIPUser.InstantiateNewTIPTable["Controls.TIP"]]]];
Commander.Register["///Commands/ContoursSimilar", ContoursSimilar, "Test Similar[].\n"];
END.