G3dTube.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Bloomenthal, July 15, 1992 4:06 pm PDT
Glassner, June 28, 1989 5:10:57 pm PDT
DIRECTORY Draw2d, G2dContour, G3dBasic, G3dCurve, G3dMatrix, G3dPlane, G3dShape, G3dSpline, G3dVector, Imager, ImagerInterpress, IO, Rope, ViewerClasses;
G3dTube: CEDAR DEFINITIONS
~ BEGIN
In General
A tube is a tree-like structure that may have an antecedent (tube.prev), a continuation (tube.next), and an arbitrary number of branches (tube.branches). A section is a tube considered by itself, without its continuation or branches. A branch is a tube and, recursively, its continuation. Generally, a tube means the sub-tree consisting of the current section and, recursively, its continuation and branches. The entire tree is the sub-tree that has no antecedent.
Tube Definitions
Contour:    TYPE ~ G2dContour.Contour;
ContourSequence: TYPE ~ G2dContour.ContourSequence; -- presumed ordered according to t
Frame:    TYPE ~ G3dBasic.Frame;
Hull:     TYPE ~ G3dBasic.Hull;
Pair:     TYPE ~ G3dBasic.Pair;
PairSequence:  TYPE ~ G3dBasic.PairSequence;
Ray:     TYPE ~ G3dBasic.Ray;
Triad:     TYPE ~ G3dBasic.Triad;
Triple:    TYPE ~ G3dBasic.Triple;
TripleSequence:  TYPE ~ G3dBasic.TripleSequence;
Curve:    TYPE ~ G3dCurve.Curve;
Matrix:    TYPE ~ G3dMatrix.Matrix;
Plane:     TYPE ~ G3dPlane.Plane;
Shape:     TYPE ~ G3dShape.Shape;
Bezier:    TYPE ~ G3dSpline.Bezier;
NearSpline:   TYPE ~ G3dSpline.NearSpline;
Spline:    TYPE ~ G3dSpline.Spline;
NearSegment:   TYPE ~ G3dVector.NearSegment;
Color:     TYPE ~ Imager.Color;
STREAM:    TYPE ~ IO.STREAM;
ROPE:     TYPE ~ Rope.ROPE;
origin:    Triple ~ [0.0, 0.0, 0.0];
RadiusMode:   TYPE ~ {linear, square};
XSection:    TYPE ~ REF XSectionRep;
XSectionRep:   TYPE ~ RECORD [
t:        REAL ¬ 0.0,     -- parametric position on curve
frame:       Frame ¬ [],     -- reference frame
length:      REAL ¬ 0.0,     -- distance from beginning of curve
scale:       REAL ¬ 1.0,     -- scale
twist:       REAL ¬ 0.0,     -- twist
matrix:      Matrix ¬ NIL,    -- matrix (right-handed) w/ scale,twist
contour:      Contour ¬ NIL,    -- normalized to unit square      
normals:      PairSequence ¬ NIL   -- normals of contour
];
XSectionSequence:  TYPE ~ REF XSectionSequenceRep;
XSectionSequenceRep: TYPE ~ RECORD [
length:      NAT ¬ 0,
element:      SEQUENCE maxLength: NAT OF XSection
];
Tube:     TYPE ~ REF TubeRep;
TubeRep:    TYPE ~ RECORD [
geometric givens:
p0, p1:      Triple ¬ origin,    -- Hermite endpoints of curve
v0, v1:      Triple ¬ origin,    -- Hermite tangents of curve
circleRes:     INTEGER ¬ 6,    -- # sides of circular contour
epsilon:     REAL ¬ 0.03,     -- criterion for spline flatness
tw0, tw1:     REAL ¬ 0.0,     -- twists
tens0, tens1:    REAL ¬ 1.0,     -- tensions
r0, r1:      REAL ¬ 0.05,     -- radii
scale:      REAL ¬ 1.0,     -- applied to radii
taper:      REAL ¬ 0.0,     -- applied to r1
contours:     ContourSequence ¬ NIL, -- optional contours
geometric derivations:
spline:      Spline ¬ NIL,    -- coefficients of curve
xSpline:      Spline ¬ NIL,    -- curve xformed to screen
bezier:     Bezier ¬ [],     -- useful in proximity testing
refVec:      Triple ¬ origin,    -- reference vector to make xSections
length:     REAL ¬ 0.0,     -- length of the tube
length0, length1:  REAL ¬ 0.0,     -- distances from root
plane:      Plane ¬ [],     -- plane at p1 perpendicular to curve
xSections:     XSectionSequence ¬ NIL, -- reference xSections, ordered by t
derivations status:
planeValid:    BOOL ¬ FALSE,    -- if plane ok
splineValid:    BOOL ¬ FALSE,    -- if tube.spline were set
lengthsValid:   BOOL ¬ FALSE,    -- if length, length0, and length1 ok
xSectionsValid:    BOOL ¬ FALSE,    -- if xSections ok
topology:
prev, next:     Tube ¬ NIL,     -- parent and continuing tubes
branches:     TubeSequence ¬ NIL,  -- branch (non-continuing) tubes
nearness:
nearSpline:    NearSpline ¬ [],    -- relative to a previous query
nearSegment:    NearSegment ¬ [],   -- relative to a previous query
miscellaneous:
name:      ROPE ¬ NIL,     -- optional name of tube
color:      Color ¬ NIL,     -- Imager color
refAny:     REF ANY ¬ NIL,    -- for client data
selected:     BOOL ¬ FALSE    -- selected for drawing?
];
TubeSequence:  TYPE ~ REF TubeSequenceRep;
TubeSequenceRep: TYPE ~ RECORD [
length:      NAT ¬ 0,
element:      SEQUENCE maxLength: NAT OF Tube
];
TubePlace:   TYPE ~ RECORD [tube: Tube, t: REAL];
DetailType:   TYPE ~ {
      autoSimplify, -- kill details if mouse held
      label,    -- label vectors
      skeleton,   -- draw straight line skeleton
      spline,   -- draw spline axis
      ends,    -- draw spline ends
      pick,    -- draw picked point
      enabled,   -- enable viewing of details
      xSections,   -- reference xSections
      lines,    -- longitudinal lines
      curvature,  -- curvature
      velocity,   -- velocity
      acceleration,  -- acceleration      
      contours,   -- true: contours, false: circles
      points,   -- points
      normals,   -- normals
      shape,    -- xSections or curvature or velocity or acceleration
      skin    -- contours or normals
      };
Details:    TYPE ~ REF DetailsRep;
DetailsRep:   TYPE ~ ARRAY DetailType OF BOOL ¬ [
      FALSE,   -- autoSimplify
      TRUE,    -- label
      FALSE,   -- skeleton
      TRUE,    -- spline
      TRUE,    -- ends
      TRUE,    -- pick
      TRUE,    -- enabled
      FALSE,   -- xSections
      FALSE,   -- lines
      FALSE,   -- curvature
      FALSE,   -- velocity
      FALSE,   -- acceleration
      FALSE,   -- contours
      FALSE,   -- points
      FALSE,   -- normals
      FALSE,   -- shape
      FALSE    -- skin
      ];
CallBack Definitions
TubeProc:   TYPE ~ PROC [tube: Tube] RETURNS [continue: BOOL ¬ TRUE];
        Procedure for operating on each tube section.
XSectionProc:   TYPE ~ PROC [position, velocity: Triple, t: REAL] RETURNS [XSection];
        Return a xSection given the position and velocity
        of the curve at parametric position t.
PointProc:   TYPE ~ PROC [id: INTEGER, position, normal: Triple, texture: Pair]
        RETURNS [continue: BOOL ¬ TRUE];
        Procedure for operating on the given point.
PolyProc:   TYPE ~ PROC [id, p0, p1, p2: INTEGER] RETURNS [continue: BOOL ¬ TRUE];
        Procedure for operating on the given triangle.
Geometric Operations
Evaluation
EvalPosition: PROC [tube: Tube, t: REAL] RETURNS [Triple];
Return the position of the tube at parametric position t.
For t=0, return tube.p0; for t=1, return tubeLast.p1 (tubeLast is the final section of tube).
EvalXSection: PROC [tube: Tube, t: REAL] RETURNS [XSection];
Return the xSection of the tube at parametric position t.
For t=0, return xSection at tube.p0;
for t=1, return xSection at tubeLast.p1 (tubeLast is the final section of tube).
Splines
SetSpline: PROC [tube: Tube];
Set the spline coefficients for tube and its descendents.
SetSectionSpline: PROC [tube: Tube];
Set the spline coefficients for tube only.
ExtractPartTube: PROC [in: Tube, t0, t1: REAL, out: Tube ¬ NIL] RETURNS [Tube];
Return a copy of that part of tube beginning at parameter t0 and ending at t1.
CurveFromTube: PROC [tube: Tube] RETURNS [Curve];
Return curve consisting of tube, tube.next, tube.next.next, and so on, ignoring branches.
Epsilon, Scale, Tension, Twist
SetTubeProperties: PROC [
tube: Tube, scale, taper, epsilon: REAL, recursively: BOOL ¬ TRUE];
Set the given properties of tube and (if recursively) to its descendants.
PropagateEpsilon: PROC [tube: Tube, epsilon: REAL];
Propagate the epsilon throughout the tube.
PropagateScale: PROC [tube: Tube, scale: REAL];
Propagate the scale throughout the tube.
Tension: PROC [tube: Tube, t: REAL] RETURNS [REAL];
Return the tension of the tube at parameter t.
Twist: PROC [tube: Tube, t: REAL] RETURNS [REAL];
Return the twist of the tube at parameter t.
Contour Procedures
AddContour: PROC [tube: Tube, contour: Contour];
Add the contour to the set of contours in the tube.
DivideContours: PROC [tube, tube0, tube1: Tube, t: REAL];
Divide the contours belonging to tube between tube0 and tube1 and the t dividing point.
TContour: PROC [contours: ContourSequence, circle: Contour, t: REAL] RETURNS [Contour];
Return the (possibly interpolated) contour t-way through the sequence;
If the sequence doesn't span t, then circle is returned.
Skin: PROC [tube: Tube];
Set the contour and normals fields of tube.xSections
GetContourPairs: PROC [xSection: XSection] RETURNS [PairSequence];
Return the sequence of pairs defining the tube hull at this xSection.
PropagateCircleRes: PROC [tube: Tube, circleRes: INTEGER];
Change circular resolution to circleRes for tube.
ScreenCircleRes: PROC [tube: Tube, view: Matrix] RETURNS [INTEGER];
Return the approximately appropriate circular resolution for display of the tube section.
tube.xSections is presumed defined.
Radius Procedures
Radius: PROC [tube: Tube, t: REAL, roundTip: BOOL ¬ FALSE] RETURNS [REAL];
Return the tube radius at parametric position t.
If roundTip and tube has no .next, then attenuate the radius to form a hemispherical tip.
SetRadii: PROC [tube: Tube, radius: REAL];
Set tube's and its descendents' radii to radius.
SetDescendantRadii: PROC [tube: Tube, mode: RadiusMode];
Set tube's descendents' radii such that, if radiusMode is linear, their sum equals tube.r1,
else, if square, the sum of their squares equals the square of tube.r1.
Length Procedures
Length: PROC [tube: Tube, t: REAL] RETURNS [REAL];
Return the length from the root of the tube to the t position on tube.
SetLengths: PROC [tube: Tube];
Set the length0 and length1 fields for tube and its descendents.
SetSectionLengths: PROC [tube: Tube];
Set the length0 and length1 fields for tube only.
AdjustXSectionLengths: PROC [tube: Tube];
Revise the xSection.length estimate based on the more accurate tube.length.
Plane Procedures
SetPlanes: PROC [tube: Tube];
Set the plane field for tube and its descendents.
SetPlane: PROC [tube: Tube];
Set the plane field for tube only.
Altering Tube XSections
ReScale: PROC [tube: Tube, scale: REAL ¬ 1.0, taper: REAL ¬ 0.0];
Resize tube.xSections to scale*tube.r.
SetCircles: PROC [tube: Tube, circleRes: NAT];
Set all tube xSections to be circular, with the given resolution.
Nearness Operations
NearestTube: PROC [q: Triple, tube: Tube, nearValid: BOOL ¬ TRUE] RETURNS [TubePlace];
Return tube and t nearest to q; iff nearValid, presumes nearSpline has been computed.
NearestTube2d: PROC [tube: Tube, screen: Pair, mouseDown: BOOL, view: Matrix]
RETURNS [TubePlace];
Return the tube and t nearest to q; iff mouse is down, recomputes tube screen projections.
Rotation Operations
Rotate: PROC [tube: Tube, line: Ray, angle: REAL, degrees, tubeAlso: BOOL ¬ TRUE];
Rotate tube (if tubeAlso) and its descendents about line by angle;
spline coefficients and tube xSections are not recomputed.
XSection Operations
Make: PROC [
tube: Tube,
skin: BOOL ¬ FALSE,
roundTip: BOOL ¬ FALSE,
view: Matrix ¬ NIL,
epsilon: REAL ¬ 0.03,
xSectionProc: XSectionProc ¬ NIL];
Create spline coefficients and reference xSections for the entire tube (its descendants and
antecedants). For each tube section, points, tangents, radii & twists are presumed defined.
The xSection matrix is scaled by tube.scale. This scale is changed according to distance from
the tube base and tube.taper; if tube.taper is 0, no tapering occurs; if tube.taper is 1, then
the scale of the matrix is reduced to zero after a distance of 1.
If skin TRUE then the curve subdivison considers the variation in any associated contours
and at each xSection the contour is computed.
If roundTip is TRUE then make the ends of those tubes without branches be hemispherical
by adding additional xSections.
tube.epsilon is set to epsilon. If view is NIL, the tube is considered only in object space
and epsilon is the same discriminator as in G3dSpline.FlatBezier; if view # NIL, epsilon is
the number of pixels the straight line approximation is permitted to deviate from the curve
as transformed to screen space.
If xSectionProc non-NIL, it is used to create the each xSection; otherwise a standard procedure,
return a xSection consisting of a circular cross-section.
MakeXSections: PROC [
tube: Tube,
skin: BOOL ¬ FALSE,
roundTip: BOOL ¬ FALSE,
view: Matrix ¬ NIL,
xSectionProc: XSectionProc ¬ NIL];
Make the xSections for the tube sub-tree (tube and its descendants only).
epsilon, scale, taper, skin, roundTip, view & xSectionProc have same meaning as in Make[].
MakeSectionXSections: PROC [
tube: Tube,
skin: BOOL ¬ FALSE,
roundTip: BOOL ¬ FALSE,
view: Matrix ¬ NIL,
xSectionProc: XSectionProc ¬ NIL];
Create a xSection sequence for the tube section only.
skin, roundTip, view, and xSectionProc have the same meaning as in Make[].
NXSections: PROC [tube: Tube] RETURNS [INTEGER];
Return the number of xSections in tube.
TotalNXSections: PROC [tube: Tube] RETURNS [nXSections: NAT ¬ 0];
Return the total number of xSections in tube and its descendents.
GetXSection: PROC [tube: Tube, t: REAL] RETURNS [XSection];
Return the xSection at parametric position t, t IN [0..1].
PutXSection: PROC [tube: Tube, xSection: XSection];
Insert the xSection in the tube.
CopyXSection: PROC [xSections: XSection] RETURNS [XSection];
Return a copy of the input xSection.
CopyXSections: PROC [xSections: XSectionSequence] RETURNS [XSectionSequence];
Return a copy of the input xSection sequence.
Basis: PROC [v, vv, rv: Triple] RETURNS [Triad];
Given tangent v along a curve, previous tangent vv, and reference vector rv, compute
vectors n and b; v, n, and b form a new set of axes; the transformation of the x, y, and z
axes to v, n, and b accomodates the twist in the curve; v, vv, and rv presumed unitized.
RefMatrix: PROC [position: Triple, triad: Triad, scale, twist: REAL, out: Matrix ¬ NIL]
RETURNS [Matrix];
Return matrix to transform origin to p, z-axis to triad.v, x-axis to triad.n and y-axis to triad.b;
twist around z by t degrees and scale by s.
XYFromXSection: PROC [point: Triple, tube: Tube, t: REAL] RETURNS [Pair];
Return the point as transformed to the x-y plane determined by tube.xSections at t.
Miscellany
ShapeFromTube: PROC [tube: Tube] RETURNS [Shape];
Create a polygonal shape given tube.
CopyTubeSection: PROC [tube: Tube, copy: Tube ¬ NIL] RETURNS [Tube];
Return a copy of the input tube.
CopyEntireTube: PROC [tube: Tube] RETURNS [copy: Tube];
Copy tube and all its descendents.
Find: PROC [searchee, search: Tube] RETURNS [BOOL];
Return true iff searchee is somewhere within search.
Where: PROC [searchee, search: Tube] RETURNS [ROPE];
Return the whereabouts of serachee within search; returns NIL if searchee no in search.
SetLastTubePicked: PROC [tube: Tube];
Set the most recently ScreenPicked tube to be tube.
LastTubePicked: PROC [copy: BOOL ¬ TRUE] RETURNS [Tube];
Return the tube most recently ScreenPicked; if copy then return copy.
First: PROC [tube: Tube] RETURNS [Tube];
Return the first antecedent of tube (that is, tube.prev.prev etc. such that tube.prev = NIL).
Last: PROC [tube: Tube] RETURNS [Tube];
Return the first last of tube (that is, tube.next.next etc. such that tube.next = NIL).
Divide: PROC [tube: Tube, t: REAL];
Divide tube into two parts, from 0 to t, and from t to 1.
Delete: PROC [tube: Tube];
Delete this tube and all its descendents.
SelectAll: PUBLIC PROC [tube: Tube];
Set select field TRUE for tube and its descendents.
UnSelectAll: PUBLIC PROC [tube: Tube];
Set select field FALSE for tube and its descendents.
ExtractTubeName: PROC [fileName: ROPE] RETURNS [ROPE];
Return the base name of the tube.
SetTubeColors: PROC [tube: Tube];
Set the tube colors according to their recursive depths.
Interpolation
Average: PROC [tube0, tube1: Tube] RETURNS [Tube];
Return the average of the two input tubes. next and branches fields are left NIL.
XSections and lengths are not computed. Spline are computed.
InterpTubes: PROC [tube1, tube2, interp: Tube, alpha: REAL];
Set the endpoints of interp according to an angular interpolation method.
This presumes tube1 and tube2 have identical topology!
interp should be initialized as a copy of either tube1 or tube2.
Creation
NewTube: PROC [
knots: TripleSequence,
tension: REAL ¬ 1.0,
tangent0, tangent1: Triple ¬ [],
cyclic: BOOL ¬ FALSE]
RETURNS [Tube];
Create a new tube based upon the input knot sequence.
If cyclic, tangent0 and tangent1 are ignored, and the last knot need not equal the first.
Branching
NewBranch: PROC [tube: Tube] RETURNS [Tube];
Fabricate a branch beginning at the end of tube.
AddBranch: PROC [tube, branch: Tube];
Add the branch to the end of tube.
GetBranch: PROC [tube: Tube, n: NAT] RETURNS [branch: Tube];
Return the n-th branch of tube; for n = 0, return tube.next, if it exist;
else return the appropriate branch. If n is out of range, NIL is returned.
Attributes
TubeHull: PROC [tube: Tube] RETURNS [Hull];
Return interesting attributes of the tube.
InvalidateTubeAttributes: PROC [tube: Tube];
Set splineValid, lengthsValid and xSectionsValid to false for tube and its descendents.
NTubes: PROC [tube: Tube] RETURNS [INTEGER];
Return the number of tubes (tube and its descendents).
NBranches: PROC [tube: Tube, nextAlso: BOOL ¬ FALSE] RETURNS [INTEGER];
Return the number of branches of tube. Iff nextAlso, add 1 if tube.next # NIL.
NSiblings: PROC [tube: Tube, tubeAlso: BOOL ¬ TRUE] RETURNS [INTEGER];
Return the number of siblings of tube, including, iff tubeAlso, tube.
NPoints: PROC [tube: Tube] RETURNS [INT];
Return the number of points in the tube.
NPolys: PROC [tube: Tube] RETURNS [INT];
Return the number of polygons in the tube.
NSplinesInBranch: PROC [tube: Tube] RETURNS [INT];
Return the number of splines in the branch.
Depth: PROC [tube: Tube] RETURNS [NAT];
Return the depth of recursion of tube; that is, its recursive distance from its first antecedent.
Info: PROC [tube: Tube] RETURNS [nPoints, nPolys, minCres, maxCres: INT];
Return the total number of points and polygons in a tube, and the extremes of circle res.
Call Backs
Points: PROC [tube: Tube, pointProc: PointProc, view: Matrix ¬ NIL] RETURNS [nPoints: INT];
Apply pointProc to the points in tube; first transform the points by view, if non-nil.
Polys: PROC [tube: Tube, polyProc: PolyProc] RETURNS [nPolys: INT];
Apply polyProc to the polygons in tube.
tubeProc is applied to a subset of tube; a tubeProc is called only if its argument is non-NIL.
ApplyToTube: PROC [tube: Tube, tubeProc: TubeProc];
Apply tubeProc recursively to tube and its descendant tubes (tube.next, and tube.branches).
ApplyToBranches: PROC [tube: Tube, tubeProc: TubeProc, nextAlso: BOOL ¬ TRUE];
Apply tubeProc to tube.branches and, iff nextAlso true, to tube.next.
ApplyToSiblings: PROC [tube: Tube, tubeProc: TubeProc, tubeAlso: BOOL ¬ TRUE];
Apply tubeProc to siblings of tube and, iff tubeAlso true, to tube.
IO
ReadTube: PROC [stream: STREAM] RETURNS [Tube];
Read from stream.
WriteTube: PROC [stream: STREAM, tube: Tube, m: Matrix ¬ NIL];
Write tube to stream, multiplying points and tangents by m if non-nil.
WritePointsPolys: PROC [tube: Tube, fileName: ROPE, m: Matrix ¬ NIL]
RETURNS [nPoints, nPolys: INT];
Write out the points and polygons to the given file;
points are indexed and contain xyz, normal, and uvw data.
WriteIP: PROC [ref: ImagerInterpress.Ref, tube: Tube, details: Details, m: Matrix];
Write the tube to ref; leaving the file open until ImagerInterpress.Close[ref].
TubeFromFile: PROC [fileName: ROPE] RETURNS [tube: Tube];
Return a tube given the file name.
TubeToFile: PROC [tube: Tube, fileName: ROPE, matrix: Matrix ¬ NIL];
Write tube to the given file name; transform the tube points according to matrix, if not NIL.
Drawing
DrawType: TYPE ~ Draw2d.DrawType;
MarkType: TYPE ~ Draw2d.MarkType;
Viewport:  TYPE ~ G3dMatrix.Viewport;
Context:  TYPE ~ Imager.Context;
DrawTube: PROC [
context: Context,
tube: Tube,
details: Details,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ solid];
Draw entire tube according to the details; splines as solid, if selected, or dotted, otherwise.
DrawSkeleton: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ solid];
Draw the entire tube with straight lines.
DrawSplines: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ solid];
Draw splines as drawType, if selected, or dotted, otherwise.
DrawSplineEnds: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
mark: MarkType ¬ dot];
Draw ends of splines with mark.
DrawPoints: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
markType: MarkType ¬ dot];
Draw the contour points.
DrawContours: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ solid];
Draw circles.
DrawLines: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
drawType: DrawType ¬ solid];
Draw lines.
DrawXSections: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
label: BOOL,
drawType: DrawType ¬ solid];
Draw xSections.
DrawNormals: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
label: BOOL,
drawType: DrawType ¬ solid];
Draw normals to the tube.
DrawCurvature: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
label: BOOL,
drawType: DrawType ¬ solid];
Draw curvature vectors.
DrawVelocity: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
label: BOOL,
drawType: DrawType ¬ solid];
Draw tangent vectors.
DrawAcceleration: PROC [
context: Context,
tube: Tube,
view: Matrix,
viewport: Viewport ¬ [],
label: BOOL,
drawType: DrawType ¬ solid];
Draw acceleration vectors.
NVectors: PROC [tube: Tube, details: Details] RETURNS [INTEGER];
Count number of vectors to draw.
END.