DIRECTORY Commander, Controls, Draw2d, FileNames, G3dDraw, G3dMatrix, G3dTool, G3dTube, ImplicitDefs, ImplicitSlice, ImplicitTube, IO, Menus, Rope; ImplicitSliceCmdsImpl: CEDAR PROGRAM IMPORTS Controls, FileNames, ImplicitSlice, ImplicitTube, IO, G3dDraw, G3dTool, G3dTube, Rope ~ BEGIN Button: TYPE ~ Controls.Button; DrawProc: TYPE ~ Draw2d.DrawProc; ClickProc: TYPE ~ Menus.ClickProc; DiagramProc: TYPE ~ ImplicitDefs.DiagramProc; ValueProc: TYPE ~ ImplicitDefs.ValueProc; Tool: TYPE ~ ImplicitSlice.Tool; Function: TYPE ~ ImplicitSlice.Function; Tube: TYPE ~ G3dTube.Tube; ROPE: TYPE ~ Rope.ROPE; TubeData: TYPE ~ REF TubeDataRep; TubeDataRep: TYPE ~ RECORD [ tool: Tool ¬ NIL, tube: Tube ¬ NIL, drawLines: BOOL ¬ FALSE ]; TubeSlice: Commander.CommandProc ~ { t: TubeData ¬ NEW[TubeDataRep]; f: LIST OF Function ¬ LIST[["segment", ValueSegment, DrawSegment]]; b: LIST OF Button ¬ LIST[ Controls.ClickButton["GetTube", GetTube, t], Controls.ClickButton["Lines: Off", ToggleDrawLines, t]]; t.tool ¬ ImplicitSlice.MakeTool["ImplicitSlice Tube", f, DrawTube, t,, b]; }; DrawTube: DrawProc ~ { t: TubeData ¬ NARROW[data]; v: G3dMTool.View ¬ G3dTool.GetView[viewer, t.tool.renderTool]; G3dTube.DrawSplines[context, t.tube, xform]; IF t.drawLines THEN { G3dTube.DrawContours[context, t.tube, v.camera.matrix, v.viewport]; G3dTube.DrawLines[context, t.tube, v.camera.matrix, v.viewport]; }; }; DrawSegment: DiagramProc ~ { t: TubeData ¬ NARROW[clientData]; xform: Matrix ¬ G3dTool.GetView[viewer, t.tool.renderTool].camera.matrix; vp: G3dMatrix.Viewport ¬ G3dView.GetViewport[viewer]; ImplicitTube.DiagramTube[context, xform, vp, point, t.tube, $Segment, inverseSqrd, 0.0, 0.75]; G3dDraw.Mark[context, t.tool.point, xform, vp, IO.PutFR[" %6.3f", IO.real[t.tool.value]]]; }; ValueSegment: ValueProc ~ { t: TubeData ¬ NARROW[clientData]; value ¬ ImplicitTube.SampleTube[point, t.tube, $Segment, inverseSqrd, 0.0, 0.75].value; }; ToggleDrawLines: ClickProc ~ { t: TubeData ¬ NARROW[clientData]; t.drawLines ¬ NOT t.drawLines; Controls.ButtonToggle[t.tool.renderTool.outerData, t.drawLines, "Lines: On", "Lines: Off"]; ImplicitSlice.Repaint[t.tool]; }; GetTube: ClickProc ~ { t: TubeData ¬ NARROW[clientData]; t.tube ¬ G3dTube.LastTubePicked[TRUE]; IF t.tube = NIL THEN { r: ROPE ¬FileNames.ResolveRelativePath[Controls.TypescriptReadFileName[t.tool.typescript]]; IF (t.tube ¬ G3dTube.TubeFromFile[r]) = NIL THEN { Controls.TypescriptWrite[t.tool.typescript, Rope.Cat["Bad file: ", r, "\n"]]; RETURN; }; }; G3dTube.SelectAll[t.tube]; IF t.tube.xSections = NIL THEN G3dTube.MakeXSections[t.tube, TRUE, TRUE]; ImplicitSlice.Repaint[t.tool]; }; ImplicitSlice.Register["Tube", TubeSlice, "Explore various tube designs."]; END. .. SqDistToSegment: PROC [a, b, q: Pair] RETURNS [REAL] ~ { n: Pair ~ [b.x-a.x, b.y-a.y]; nSq: REAL ~ n.x*n.x+n.y*n.y; qSq: REAL ~ SqDist[q, a]; IF nSq < 0.1*qSq THEN RETURN[qSq] ELSE { ua: Pair ~ [q.x-a.x, q.y-a.y]; alpha: REAL ~ (ua.x*n.x+ua.y*n.y)/nSq; RETURN[SqDist[q, SELECT alpha FROM <= 0.0 => a, >= 1.0 => b, ENDCASE => [a.x+alpha*n.x, a.y+alpha*n.y]]]; }; }; SqDist: PROC [p0, p1: Pair] RETURNS [REAL] ~ { d: Pair ¬ [p1.x-p0.x, p1.y-p0.y]; RETURN[d.x*d.x+d.y*d.y]; }; SqDistToContour: PROC [contour: Contour, q: Pair] RETURNS [min: REAL ¬ 10000.0] ~ { pairs: PairSequence ~ contour.pairs; n, n0, n1: NAT; FOR i: NAT IN [0..pairs.length) DO d: REAL ~ SqDist[q, pairs[i]]; IF d < min THEN {min ¬ d; n ¬ i}; ENDLOOP; n0 ¬ IF n > 0 THEN n-1 ELSE IF contour.closed THEN pairs.length-1 ELSE n; n1 ¬ IF n < pairs.length-1 THEN n+1 ELSE IF contour.closed THEN 0 ELSE n; RETURN[MIN[ SqDistToSegment[pairs[n0], pairs[n], q], SqDistToSegment[pairs[n], pairs[n1], q]]]; }; SqDistToArc: PROC [q: Pair, arc: REAL] RETURNS [REAL] ~ { IF q.y > arc THEN RETURN[ MIN[SqDist[q, [arc, arc]], SqDist[q, [-arc, arc]]]] ELSE { yDif: REAL ~ q.y-arc; d: REAL ~ arc-RealFns.SqRt[q.x*q.x+yDif*yDif]; RETURN[d*d]; }; }; FOR s: NAT IN [pm.sMin..pm.sMin+pm.sSize) DO IF p.abort THEN RETURN; FOR f: NAT IN [pm.fMin..pm.fMin+pm.fSize) DO q: Pair ~ PairCoords[[f, s]]; potential: REAL ¬ 0.0; IF p.options[radius] AND p.rad.value # 0.0 THEN { d: REAL ~ q.x*q.x+q.y*q.y; potential ¬ IF d # 0.0 THEN 10.0*p.rad.value/d ELSE 255.0; }; IF p.options[arc] THEN { d: REAL ~ SqDistToArc[q, p.arc.value]; potential ¬ IF d # 0.0 THEN potential+1.0/d ELSE 255.0; }; IF p.options[line] AND ABS[q.x] < p.line.value THEN { potential ¬ IF q.y = 0.0 THEN 255.0 ELSE potential+10.0*(p.line.value-ABS[q.x])*(p.line.value-ABS[q.x])/ABS[q.y]; }; IF p.options[contour] THEN { d: REAL ~ SqDistToContour[c, q]; potential ¬ IF d # 0.0 THEN potential+1.0/d ELSE 255.0; }; CtBasic.PutPixel[pm, f, s, Real.RoundI[MIN[255.0, MAX[0.0, potential]]]]; ENDLOOP; ENDLOOP; ψ ImplicitSliceCmdsImpl.mesa Copyright Σ 1985, 1990 by Xerox Corporation. All rights reserved. Bloomenthal, August 11, 1992 4:06 pm PDT Types Tube Testing Start Code Fancy Tube Display DrawTube: PROC [context: Context, tube: Tube] ~ { tubeProc: G3dTube.TubeProc ~ { i: G3dSpline.SplinePlaneIntersect ¬ G3dSpline.IntersectSplineAndPlane[tube.coeffs, t.slice.plane]; FOR n: NAT IN [0..i.nRoots) DO Draw3d.Mark[context, G3dSpline.Position[s.tube.coeffs, i.roots[n]], t.view, , x]; ENDLOOP; DrawSpline[context, tube.coeffs]; }; Imager.SetColor[context, Imager.black]; Imager.SetStrokeWidth[context, 2.0]; G3dTube.ApplyToTube[tube, tubeProc]; Imager.SetStrokeWidth[context, 4.0]; }; DrawSpline: PROC [context: Context, coeffs: Coeffs] ~ { PatternProc: PROC [i: NAT] RETURNS [REAL] ~ {RETURN[2]}; behind: BOOL ¬ Plane3d.DistanceToPt[Spline3d.Position[coeffs, 0.0], s.slice.plane] < 0; was: BOOL ¬ NOT behind; solid, dash: Imager.Trajectory ¬ NIL; FOR t: REAL ¬ 0.0, t+0.005 WHILE t <= 1.004 DO q: Triple ¬ G3dSpline.Position[coeffs, t]; v: Pair ¬ G3dMatrix.TransformD[q, s.view]; behind ¬ G3dPlane.DistanceToPoint[q, s.slice.plane] < 0; SELECT TRUE FROM was AND NOT behind => solid ¬ ImagerPath.MoveTo[v]; NOT was AND behind => dash ¬ ImagerPath.MoveTo[v]; behind => dash ¬ ImagerPath.LineTo[dash, v]; ENDCASE => solid ¬ ImagerPath.LineTo[solid, v]; was ¬ behind; ENDLOOP; IF dash # NIL THEN Imager.MaskDashedStrokeTrajectory[context, dash, 2, PatternProc, 0, 20]; IF solid # NIL THEN Imager.MaskStrokeTrajectory[context, solid]; }; Discarded Value Procs Line: InfoProc ~ { FOR n: NAT IN [0..info.length) DO i: Info ¬ info[n]; FOR nn: NAT IN (n..info.length) DO ii: Info ¬ info[nn]; IF i.point # ii.point THEN { near: NearSegment3d ¬ G3dVector.NearestTo3dSegment[i.point, ii.point, point]; distance: REAL ¬ SELECT near.w0 FROM 0.0 => ii.distance, 1.0 => i.distance, ENDCASE => G3dVector.Distance[near.point, point]; aveRadius: REAL ¬ 0.5*(i.radius+ii.radius); value ¬ value+Strength[Ratio[distance, aveRadius, spread]]; } ELSE value ¬ value+i.strength; ENDLOOP; ENDLOOP; IF info.length > 2 THEN value ¬ 2.0*value/(info.length*(info.length-1)); }; MaxInfo: PROC [info: REF Infos] RETURNS [max: NAT ¬ 0] ~ { strength: REAL ¬ 0.0; FOR n: NAT IN [0..info.length) DO IF info[n].strength > strength THEN {strength ¬ info[n].strength; max ¬ n}; ENDLOOP; }; TotalValue: PROC [info: REF Infos, proc: PROC [i, ii: Info] RETURNS [REAL]] RETURNS [REAL] ~ { max: NAT ¬ MaxInfo[info]; i: Info ¬ info[max]; value: REAL ¬ i.strength; FOR n: NAT IN [0..info.length) DO IF n # max THEN value ¬ value+proc[i, info[n]]; ENDLOOP; RETURN[value]; }; CosineAndSynergy: InfoProc ~ { Proc: PROC [i, ii: Info] RETURNS [REAL] ~ { tot: REAL ¬ i.strength+ii.strength; acos: REAL ¬ G3dVector.Dot[i.vector, ii.vector]; RETURN[(1.0-acos)* (IF tot > 1.0 THEN tot*tot*ii.strength ELSE ii.strength)]; }; RETURN[TotalValue[info, Proc]]; }; CosineAndClose: InfoProc ~ { Proc: PROC [i, ii: Info] RETURNS [REAL] ~ { totalStrength: REAL ¬ i.strength+ii.strength; IF totalStrength # 0.0 THEN { acos: REAL ¬ G3dVector.Dot[i.vector, ii.vector]; closeness: REAL ¬ 1.0-ABS[i.strength-ii.strength]/totalStrength; RETURN[closeness*(1.0-acos)*ii.strength]; }; RETURN[0.0]; }; RETURN[TotalValue[info, Proc]]; }; Summation: InfoProc ~ { FOR n: NAT IN [0..info.length) DO value ¬ value+info[n].strength; ENDLOOP; }; Strength: PROC [distance, radius, spread: REAL] RETURNS [REAL] ~ { Attempt 2: dOverR: REAL ¬ distance/radius; IF dOverR > 4.0 THEN RETURN[0.0] ELSE { dif: REAL ¬ dOverR-4.0; RETURN[4.0-Real.SqRt[16.0-dif*dif]]; }; }; Strength: PROC [distance, radius, spread: REAL] RETURNS [REAL] ~ { Attempt 1: dOverR: REAL ¬ distance/radius; RETURN[SELECT dOverR FROM IN[0.00..0.25) => 4.0-4.00*dOverR, IN[0.25..0.50) => 4.0-4.00*dOverR, IN[0.50..0.75) => 3.0-2.00*dOverR, IN[0.75..1.00) => 3.0-2.00*dOverR, IN[1.00..1.50) => 1.5-0.50*dOverR, IN[1.50..2.00) => 1.5-0.50*dOverR, IN[2.00..3.00) => 1.0-0.25*dOverR, IN[3.00..4.00) => 1.0-0.25*dOverR, ENDCASE => 0.0]; }; ValueOfTube: PROC [tube: Tube, point: Triple, spread: REAL] RETURNS [value: REAL ¬ 0.]~ { max, nBranches: NAT ¬ G3dTube.NBranches[tube]+1; FOR n: NAT IN [0..nBranches) DO branch: Tube ¬ IF n = 0 THEN tube.next ELSE tube.branches[n-1]; nearest: NearSpline3d ¬ G3dSpline.PreciseNearestPoint[point, branch.xCoeffs]; vector: Triple ¬ G3dVector.Normalize[G3dVector.Sub[nearest.point, point]]; radius: REAL ¬ G3dTube.Radius[branch, nearest.t]; strength: REAL ¬ Strength[nearest.distance, radius, spread]; IF strength > value THEN {value ¬ strength; max ¬ n}; info[n] ¬ [nearest.point, vector, nearest.distance, radius, strength]; ENDLOOP; FOR n: NAT IN [0..nBranches) DO IF n # max THEN { acos: REAL ¬ G3dVector.Dot[info[max].vec, info[n].vec]; value ¬ value+0.5*(1.0-acos)*info[n].strength; }; ENDLOOP; value ¬ (4.0/3.0)*value; }; ELSE potential+(p.line.value-ABS[q.x])/(q.y*q.y); d: REAL ~ SELECT q.x FROM < -p.line.value => SqDist[q, [-p.line.value, 0.0]], > p.line.value => SqDist[q, [p.line.value, 0.0]], ENDCASE => q.y*q.y; potential ¬ IF d # 0.0 THEN potential+1.0/d ELSE 255.0; Κ ¦•NewlineDelimiter ™™JšœB™BJ™(J˜JšΟk œŠ˜“J˜—šΠblœœ˜$J˜JšœV˜]J˜—Jšœ˜headšΟl™Jšœ œ˜"Jšœ œ˜#Jšœ œ˜$Jšœœ˜/Jšœ œ˜+Jšœ œ˜$Jšœ œ˜+Jšœœ˜Jšœœœ˜—šŸ ™ Jšœ œœ ˜#šœ œœ˜Jšœœ˜Jšœœ˜Jšœœ˜J˜J˜—šΠbn œ˜$Jšœœ˜Jšœœœ œ)˜Cšœœœ œ˜J˜,J˜8—J˜JJ˜J˜—šΟnœ˜Jšœœ˜J˜>J˜,šœ œ˜J˜CJ˜@J˜—J˜J˜—š‘ œ˜Jšœœ ˜!J˜IJ˜5J˜^Jšœ/œœ˜[J˜J˜—š‘ œ˜Jšœœ ˜!J˜WJ˜J˜—šΟbœ˜Jšœœ ˜!Jšœœ ˜J˜[J˜J˜J˜—š’œ˜Jšœœ ˜!Jšœ œ˜&šœ œœ˜JšœΟs£œS˜[šœ&œœ˜2JšœM˜MJšœ˜J˜—J˜—J˜Jš œœœœœ˜IJ˜J˜——šŸ ™ J˜K—J˜šœ˜J˜—šŸ™š‘œœ#™1š‘œ™code™#L™>—šœœœ™L™QLšœ™—J™!J™—J™'J™$J™$J™$J™J™—š‘ œœ'™7Jš ‘ œœœœœœ™8JšœœH™WJšœœœ™Jšœ!œ™%šœœœ ™.L™*L™*L™8šœœ™Jšœœœ(™3Jšœœ'™2J™,Jšœ(™/—J™ Lšœ™—šœœ™L™H—Lšœ œœ-™@J™——šŸ™š‘œ™šœœœ™!J™šœœœ™"J™šœœ™J™Mšœ œœ ™$J™J™Jšœ*™1—Jšœ œ™+J™;J™—Jšœ™Jšœ™—Jšœ™—Jšœœ1™HJ™J™—š ‘œœœœœ ™:Jšœ œ™šœœœ™!Jšœœ(™KJšœ™—J™J™—š‘ œœœœœœœœ™ZJ™Jšœœ™J™Jšœœ™šœœœ™!Jšœ œ ™/Jšœ™—Jšœ™J™J™—š‘œ™š‘œœœœ™+Jšœœ™#Jšœœ&™0Jšœœ œœ™MJ™—Jšœ™J™J™—š‘œ™š‘œœœœ™+Jšœœ™-šœœ™Jšœœ&™0Jšœ œœ'™@Jšœ#™)J™—Jšœ™ J™—Jšœ™J™J™—š‘ œ™Jš œœœœ œ™JJ™J™—š ‘œœœœœ™BJ™ Jšœ£œ™šœ ™Jšœœ™šœ™Jšœœ™Jšœ™$J™——™J™——š ‘œœœœœ™BJ™ Jšœ£œ™šœœ™Jšœ ™"Jšœ ™"Jšœ ™"Jšœ ™"Jšœ ™"Jšœ ™"Jšœ ™"Jšœ ™"Jšœ ™—J™J˜—š ‘ œœ%œœ œ ™YJšœœ™0šœœœ™Jšœœœ œ™?J™MJ™JJšœœ%™1Jšœ œ.™