DIRECTORY Commander, CommanderOps, Controls, Convert, G2dBasic, G3dBasic, G3dSpline, G3dTool, G3dTube, G3dVector, IO, Menus, Rope;
G3dTubeCmdsImpl: CEDAR PROGRAM
IMPORTS CommanderOps, Controls, Convert, G3dSpline, G3dTool, G3dTube, G3dVector, IO, Rope
~ BEGIN
Control: TYPE ~ Controls.Control;
Triple: TYPE ~ G3dBasic.Triple;
Tool: TYPE ~ G3dTool.Tool;
ROPE: TYPE ~ Rope.ROPE;
Tube: TYPE ~ G3dTube.Tube;
TubeProc: TYPE ~ G3dTube.TubeProc;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD [
tool: Tool ฌ NIL,
alpha: Control ฌ NIL,
tube1, tube2: Tube ฌ NIL,
interp: Tube ฌ NIL
];
TubeInterpCmd: Commander.CommandProc ~ {
argv: CommanderOps.ArgumentVector ฌ CommanderOps.Parse[cmd];
IF argv.argc # 3
THEN RETURN[$Failure, interpUsage]
ELSE {
Prepare: PROC [tube: Tube] ~ {
tube.epsilon ฌ 1.0;
G3dTube.Make[tube];
};
d: Data ฌ NEW[DataRep];
d.tube1 ฌ G3dTube.TubeFromFile[argv[1]];
d.tube2 ฌ G3dTube.TubeFromFile[argv[2]];
IF d.tube1 = NIL OR d.tube2 = NIL
THEN RETURN[$Failure, "Can't read tube(s)"]
ELSE {
Prepare[d.tube1];
Prepare[d.tube2];
d.interp ฌ G3dTube.CopyEntireTube[d.tube1];
G3dTube.SelectAll[d.interp];
d.tool ฌ G3dTool.MakeTool[
name: "TubeInterp",
extraControls: LIST[Controls.NewControl["alpha",, d, 0, 1, 0, Alpha,,,,,,, 136]],
extraButtons: LIST[Controls.ClickButton["Write Tube", WriteTube, d]],
client: [draw: Draw, data: d]
];
};
};
};
Alpha: Controls.ControlProc ~ {
d: Data ฌ NARROW[clientData];
IF control.mouse.button # right THEN RETURN;
G3dTube.InterpTubes[d.tube1, d.tube2, d.interp, control.value];
G3dTool.Repaint[d.tool];
};
Draw: G3dTool.DrawProc ~ {
G3dTube.DrawSkeleton[context, NARROW[clientData, Data].interp, view, vp];
};
WriteTube: Controls.ClickProc ~ {
d: Data ฌ NARROW[clientData];
fileName: ROPE ฌ Controls.TypescriptReadFileName[d.tool.typescript];
IF fileName # NIL THEN G3dTube.TubeToFile[d.interp, fileName];
};
TubeOpsCmd: Commander.CommandProc ~ {
tube: Tube;
argv: CommanderOps.ArgumentVector ฌ CommanderOps.Parse[cmd];
IF argv.argc < 4 THEN RETURN[$Failure, opsUsage];
IF (tube ฌ G3dTube.TubeFromFile[argv[1]]) = NIL
THEN RETURN[$Failure, "Can't read tube"]
ELSE {
n: NAT ฌ 3;
WHILE n < argv.argc DO
Eq: PROC [r: ROPE] RETURNS [b: BOOL] ~ {b ฌ Rope.Equal[argv[n], r, FALSE]};
GetReal: PROC [n: NAT] RETURNS[r: REAL] ~ {r ฌ Convert.RealFromRope[argv[n]]};
SELECT TRUE FROM
Eq["-fixUp"] => {
Op: TubeProc ~ {IF tube.prev # NIL THEN tube.p0 ฌ tube.prev.p1};
G3dTube.ApplyToTube[tube, Op];
};
Eq["-normalize"] => {
Op: TubeProc ~ {
tube.p0 ฌ G3dVector.Mul[G3dVector.Sub[tube.p0, hull.center], scale];
tube.p1 ฌ G3dVector.Mul[G3dVector.Sub[tube.p1, hull.center], scale];
tube.v0 ฌ G3dVector.Mul[tube.v0, scale];
tube.v1 ฌ G3dVector.Mul[tube.v1, scale];
tube.r0 ฌ scale*tube.r0;
tube.r1 ฌ scale*tube.r1;
};
hull: G3dBasic.Hull ฌ G3dTube.TubeHull[tube];
size: Triple ฌ G3dVector.Sub[hull.pMax, hull.pMin];
scale: REAL ฌ 1.0/MAX[size.x, size.y, size.z];
G3dTube.ApplyToTube[tube, Op];
};
Eq["-scale"] => {
Op: TubeProc ~ {
tube.p0 ฌ G3dVector.Mul[tube.p0, scale];
tube.p1 ฌ G3dVector.Mul[tube.p1, scale];
};
scale: REAL ฌ GetReal[n+1];
n ฌ n+1;
G3dTube.ApplyToTube[tube, Op];
};
Eq["-offset"] => {
Op: TubeProc ~ {
tube.p0 ฌ G3dVector.Add[tube.p0, offset];
tube.p1 ฌ G3dVector.Add[tube.p1, offset];
};
offset: Triple ฌ [GetReal[n+1], GetReal[n+2], GetReal[n+3]];
n ฌ n+3;
G3dTube.ApplyToTube[tube, Op];
};
Eq["-invertZ"] => {
Op: TubeProc ~ {
tube.p0.z ฌ 1.0-tube.p0.z;
tube.p1.z ฌ 1.0-tube.p1.z;
};
G3dTube.ApplyToTube[tube, Op];
};
Eq["-interpolate"] => {
Interpolate: TubeProc ~ {
AddPt: PROC [p: Triple] ~ {pts[pts.length] ฌ p; pts.length ฌ pts.length+1};
temp: Tube ฌ tube;
last: Tube ฌ G3dTube.Last[tube];
splines: G3dSpline.SplineSequence;
tan0: Triple ฌ IF tube.prev # NIL
THEN tube.prev.v1
ELSE G3dVector.Mul[G3dVector.Sub[tube.p1, tube.p0], (1.0/3.0)];
tan1: Triple ฌ G3dVector.Mul[G3dVector.Sub[last.p1, last.p0], (1.0/3.0)];
pts.length ฌ 0;
AddPt[tube.p0];
FOR t: Tube ฌ tube, t.next WHILE t # NIL DO AddPt[t.p1]; ENDLOOP;
splines ฌ G3dSpline.Interpolate[pts, tan0, tan1];
FOR n: NAT IN [0..splines.length) DO
temp.spline ฌ splines[n];
temp.v0 ฌ G3dSpline.Velocity[temp.spline, 0.0];
temp.v1 ฌ G3dSpline.Velocity[temp.spline, 1.0];
temp ฌ temp.next;
ENDLOOP;
FOR t: Tube ฌ tube, t.next WHILE t # NIL DO
G3dTube.ApplyToBranches[t, Interpolate, FALSE];
ENDLOOP;
};
pts: G3dBasic.TripleSequence ฌ NEW[G3dBasic.TripleSequenceRep[100]];
[] ฌ Interpolate[tube];
};
ENDCASE => IO.PutF1[cmd.err, "Bad option: %g\n", IO.rope[argv[n]]];
n ฌ n+1;
ENDLOOP;
G3dTube.TubeToFile[tube, argv[2]];
};
};
opsUsage: ROPE ฌ "
3dTubeOps