RenderWithStreamImpl.mesa
Last Edited by: Crow, February 20, 1987 5:58:01 pm PST
DIRECTORY
Atom     USING [ GetPropFromList, PutPropOnList ],
Rope     USING [ Cat, ROPE ],
Convert    USING [ RealFromRope, RopeFromReal ],
BasicTime   USING [ GetClockPulses, PulsesToSeconds ],
IO      USING [ PutRope, RopeFromROS, ROS, STREAM, UnsafePutBlock ],
Real     USING [ Fix, RoundI, Float ],
Commander   USING [ CommandProc ],
ComputeServerServer USING [ Register ],
Pixels     USING [ GetScanSeg, SampleSetSequence ],
SampleMapOps  USING [ GetPointer ],
SceneUtilities  USING [ ReadScene ],
ThreeDBasics  USING [ Context, ContextClass, Create, GetDisplayType, RegisterDisplayType ];
RenderWithStreamImpl: CEDAR PROGRAM
IMPORTS Atom, BasicTime, ComputeServerServer, Convert, IO, Pixels, Real, Rope, SampleMapOps, SceneUtilities, ThreeDBasics
~ BEGIN
Context: TYPE ~ ThreeDBasics.Context;
ContextClass: TYPE ~ ThreeDBasics.ContextClass;
Ceiling: PROC[ in: REAL ] RETURNS[ out: INTEGER ] ~ {
out ← Real.RoundI[in];
IF Real.Float[out] < in THEN out ← out + 1;
};
ElapsedTime: PROC[startTime: REAL] RETURNS[Rope.ROPE] ~ {
timeX100: REAL ← 100.0 * (CurrentTime[] - startTime);
RETURN[ Rope.Cat[ Convert.RopeFromReal[ Real.Fix[timeX100] / 100.0 ], "s," ] ];
};
CurrentTime: PROC[] RETURNS[REAL] ~ {
RETURN[ BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[]] ];
};
renderFullClrProc: PROC[context: REF Context];
renderPseudoClrProc: PROC[context: REF Context];
renderGreyProc: PROC[context: REF Context];
MakeFrame: PROC[context: REF Context] ~ {
Makes image, sends pixels and log back on output stream.
lastTime: REAL ← CurrentTime[];
scanSeg: REF Pixels.SampleSetSequence;
startTime: REALNARROW[Atom.GetPropFromList[context.props, $StartTime], REF REAL]^;
log: IO.STREAMNARROW[Atom.GetPropFromList[context.props, $Log]];
output: IO.STREAMNARROW[ Atom.GetPropFromList[context.props, $Output] ];
SELECT context.class.displayType FROM
$FullColor, $Dorado24 => renderFullClrProc[context];
$PseudoColor => renderPseudoClrProc[context];
$Grey => renderGreyProc[context];
ENDCASE => log.PutRope[ " \n No frame: unknown displayType \n " ];
Write pixels back on output stream
lastTime ← CurrentTime[];
FOR y: NAT IN [0 .. Ceiling[context.viewPort.h] ) DO
scanSeg ← Pixels.GetScanSeg[context.display, 0, y, Ceiling[context.viewPort.w], scanSeg];
FOR i: NAT IN [0.. context.display.samplesPerPixel) DO
TRUSTED {
IO.UnsafePutBlock[ -- uses 16 bits per byte (wasting net bandwidth)
self: output,
block: [ base: LOOPHOLE[SampleMapOps.GetPointer[scanSeg[i], 0, scanSeg[i].length]],
  count: 2*scanSeg[i].length ]
];
};
ENDLOOP;
ENDLOOP;
log.PutRope[ Rope.Cat[
" output: ", ElapsedTime[lastTime], " total: ", ElapsedTime[startTime]
] ];
};
RenderWithStreamProc: Commander.CommandProc ~ {
CommandProc: TYPE = PROC [cmd: Handle] RETURNS [result: REF ← NIL, msg: ROPE ← NIL];
Reads scene described on input stream, passes pixels back on output stream
startTime: REAL ← Convert.RealFromRope[cmd.commandLine];
context: REF ThreeDBasics.Context ← ThreeDBasics.Create[];
log: IO.STREAM ← IO.ROS[]; -- use Rope Output Stream
log.PutRope[ Rope.Cat[" delay: ", ElapsedTime[startTime] ] ];
context.props ← Atom.PutPropOnList[context.props, $StartTime, NEW[REAL ← CurrentTime[]] ];
context.props ← Atom.PutPropOnList[context.props, $Log, log ];
context.props ← Atom.PutPropOnList[context.props, $Output, cmd.out]; -- output pixel stream
SceneUtilities.ReadScene[context, cmd.in]; -- read from stream until termination
msg ← Rope.Cat[ msg, IO.RopeFromROS[log] ]; -- add log to end of stream for feedback
msg ← Rope.Cat[ msg, " remote end at: ", ElapsedTime[startTime] ];
context ← NIL;      -- kill off everything, no state saved  
};
Init: PROC ~ {
Get previously registered classes and modify them to call MakeFrame for rendering
contextClass: ContextClass ← ThreeDBasics.GetDisplayType[$FullColor];
renderFullClrProc ← contextClass.render;  -- ambush render procedure
contextClass.render ← MakeFrame;   -- and insert local proc before call
ThreeDBasics.RegisterDisplayType[contextClass];
contextClass.displayType ← $Dorado24;    -- catch $Dorado24 and treat as $FullColor
ThreeDBasics.RegisterDisplayType[contextClass];
contextClass ← ThreeDBasics.GetDisplayType[$PseudoColor];
renderPseudoClrProc ← contextClass.render;  -- ambush render procedure
contextClass.render ← MakeFrame;    -- and insert local proc before call
ThreeDBasics.RegisterDisplayType[contextClass];
contextClass ← ThreeDBasics.GetDisplayType[$Grey];
renderGreyProc ← contextClass.render;   -- ambush render procedure
contextClass.render ← MakeFrame;    -- and insert local proc before call
ThreeDBasics.RegisterDisplayType[contextClass];
ComputeServerServer.Register[     -- register control procedure with compute server
key: "3dRenderWithStream",
proc: RenderWithStreamProc
];
};
Init[];
END.