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"];