DIRECTORY Basics, Commander, Controls, G3dDraw, G3dPolygon, G3dTool, G3dVector, Imager, ImagerColor, ImagerFont, IO, Rope; ImplicitTestTetEdgesImpl: CEDAR PROGRAM IMPORTS Basics, Commander, Controls, G3dDraw, G3dPolygon, G3dTool, G3dVector, Imager, ImagerColor, ImagerFont, IO, Rope ~ BEGIN Triple: TYPE ~ G3dTool.Triple; Corner: TYPE ~ RECORD [positive: BOOL, point: Triple]; Direction: TYPE ~ {lbn, lbf, ltn, ltf, rbn, rbf, rtn, rtf}; Triangle: TYPE ~ RECORD [p1, p2, p3, center, normal: Triple]; Tetrahedron: TYPE ~ RECORD [p1, p2, p3, p4: Triple]; Cube: TYPE ~ RECORD [ lbn, lbf, ltn, ltf: Corner, rbn, rbf, rtn, rtf: Corner, triangles: LIST OF Triangle ¬ NIL, tetrahedra: LIST OF Tetrahedron ¬ NIL]; Data: TYPE ~ RECORD [ tool: G3dTool.Tool ¬ NIL, select: INTEGER ¬ 0, nrms, text, tets, lab: BOOL ¬ TRUE, cubes1, cubes2: ARRAY [0..256) OF REF Cube ¬ ALL[NIL]]; TestTetEdgesCmd: Commander.CommandProc ~ { d: REF Data ¬ NEW[Data]; buttons: Controls.ButtonList ¬ LIST[ Controls.ClickButton["STEP", But, d], Controls.ClickButton["SET", But, d], Controls.ClickButton["Text: On", But, d], Controls.ClickButton["Tets: On", But, d], Controls.ClickButton["Labs: On", But, d], Controls.ClickButton["Nrms: On", But, d]]; FOR i: INTEGER IN [0..256) DO d.cubes1[i] ¬ MakeCube[i, 1]; ENDLOOP; FOR i: INTEGER IN [0..256) DO d.cubes2[i] ¬ MakeCube[i, 2]; ENDLOOP; d.tool ¬ G3dTool.MakeTool["TetEdges", buttons,,, [io: TRUE], [draw: Draw, data: d],,,,, 275]; }; Poly: PROC [cube: REF Cube, type: NAT] ~ { VertexID: PROC [c1, c2: Corner] RETURNS [Triple] ~ { IF c1.positive = c2.positive THEN ERROR; RETURN[G3dVector.Midpoint[c1.point, c2.point]]; }; TriangulateTetrahedron: PROC [a, b, c, d: Corner] ~ { Output: PROC [a, b, c: Triple] ~ INLINE { t: Triangle ¬ [a, b, c, G3dPolygon.TriangleCenter[a,b,c], G3dPolygon.TriangleNormal[a,b,c,TRUE]]; cube.triangles ¬ IF cube.triangles = NIL THEN LIST[t] ELSE CONS[t, cube.triangles]; }; index: INT ¬ 0; aPos, bPos, cPos, dPos: BOOL; e1, e2, e3, e4, e5, e6: Triple; tet: Tetrahedron ¬ [a.point, b.point, c.point, d.point]; IF (aPos ¬ a.positive) THEN index ¬ index+8; IF (bPos ¬ b.positive) THEN index ¬ index+4; IF (cPos ¬ c.positive) THEN index ¬ index+2; IF (dPos ¬ d.positive) THEN index ¬ index+1; IF index IN [1..14] THEN cube.tetrahedra ¬ IF cube.tetrahedra = NIL THEN LIST[tet] ELSE CONS[tet, cube.tetrahedra]; IF aPos # bPos THEN e1 ¬ VertexID[a, b]; IF aPos # cPos THEN e2 ¬ VertexID[a, c]; IF aPos # dPos THEN e3 ¬ VertexID[a, d]; IF bPos # cPos THEN e4 ¬ VertexID[b, c]; IF bPos # dPos THEN e5 ¬ VertexID[b, d]; IF cPos # dPos THEN e6 ¬ VertexID[c, d]; SELECT index FROM 1 => Output[e5, e6, e3]; 2 => Output[e2, e6, e4]; 3 => {Output[e3, e5, e4]; Output[e3, e4, e2]}; 4 => Output[e1, e4, e5]; 5 => {Output[e3, e1, e4]; Output[e3, e4, e6]}; 6 => {Output[e1, e2, e6]; Output[e1, e6, e5]}; 7 => Output[e1, e2, e3]; 8 => Output[e1, e3, e2]; 9 => {Output[e1, e5, e6]; Output[e1, e6, e2]}; 10 => {Output[e1, e3, e6]; Output[e1, e6, e4]}; 11 => Output[e1, e5, e4]; 12 => {Output[e3, e2, e4]; Output[e3, e4, e5]}; 13 => Output[e6, e2, e4]; 14 => Output[e5, e3, e6]; ENDCASE; -- 0, 15 }; IF type = 1 THEN { TriangulateTetrahedron[cube.lbn, cube.lbf, cube.ltn, cube.rbn]; TriangulateTetrahedron[cube.ltf, cube.ltn, cube.lbf, cube.rtf]; TriangulateTetrahedron[cube.rbf, cube.rbn, cube.rtf, cube.lbf]; TriangulateTetrahedron[cube.rtn, cube.rtf, cube.rbn, cube.ltn]; TriangulateTetrahedron[cube.lbf, cube.ltn, cube.rbn, cube.rtf]; } ELSE { TriangulateTetrahedron[cube.lbf, cube.rbf, cube.ltf, cube.lbn]; TriangulateTetrahedron[cube.ltn, cube.ltf, cube.rtn, cube.lbn]; TriangulateTetrahedron[cube.rbn, cube.rbf, cube.lbn, cube.rtn]; TriangulateTetrahedron[cube.rtf, cube.rtn, cube.ltf, cube.rbf]; TriangulateTetrahedron[cube.lbn, cube.ltf, cube.rtn, cube.rbf]; }; }; MakeCube: PROC [i: INTEGER, type: NAT] RETURNS [c: REF Cube] ~ { Bit: PROC [i: WORD, c: Direction] RETURNS [BOOL] ~ { exp: NAT ¬ SELECT c FROM lbn=>0,lbf=>1,ltn=>2,ltf=>3,rbn=>4,rbf=>5,rtn=>6,ENDCASE=>7; RETURN[IF Basics.BITAND[i, Basics.BITSHIFT[1, exp]] # 0 THEN TRUE ELSE FALSE]; }; Point: PROC [c: Direction] RETURNS [t: Triple] ~ { t ¬ SELECT c FROM lbn => [-.4,-.4,-.4], lbf => [-.4,-.4,.4], ltn => [-.4,.4,-.4], ltf => [-.4,.4,.4], rbn => [.4,-.4,-.4], rbf => [.4,-.4,.4], rtn => [.4,.4,-.4], ENDCASE => [.4,.4,.4]; }; c ¬ NEW[Cube]; c.lbn ¬ [Bit[i, lbn], Point[lbn]]; c.lbf ¬ [Bit[i, lbf], Point[lbf]]; c.ltn ¬ [Bit[i, ltn], Point[ltn]]; c.ltf ¬ [Bit[i, ltf], Point[ltf]]; c.rbn ¬ [Bit[i, rbn], Point[rbn]]; c.rbf ¬ [Bit[i, rbf], Point[rbf]]; c.rtn ¬ [Bit[i, rtn], Point[rtn]]; c.rtf ¬ [Bit[i, rtf], Point[rtf]]; Poly[c, type]; }; Draw: G3dTool.DrawProc ~ { NTetrahedra: PROC [c: REF Cube] RETURNS [n: INTEGER ¬ 0] ~ { FOR l: LIST OF Tetrahedron ¬ c.tetrahedra, l.rest WHILE l # NIL DO n ¬ n+1; ENDLOOP; }; NTriangles: PROC [c: REF Cube] RETURNS [n: INTEGER ¬ 0] ~ { FOR l: LIST OF Triangle ¬ c.triangles, l.rest WHILE l # NIL DO n ¬ n+1; ENDLOOP; }; ShowRope: PROC [x, y: REAL, r: Rope.ROPE] ~ { Imager.SetXY[context, [x, y]]; Imager.ShowRope[context, r]; }; SetColor: PROC [rgb: Triple] ~ { IF color#rgb THEN Imager.SetColor[context,ImagerColor.ColorFromRGB[[rgb.x,rgb.y,rgb.z]]]; color ¬ rgb; }; DrawAll: PROC [c: REF Cube, type: NAT] ~ { DrawBox: PROC [p: Triple] ~ {G3dDraw.Box[context, p, view, vp, 6, 6]}; DrawSeg: PROC [a, b: Triple] ~{G3dDraw.DrawSegment[context, a, b, view, vp]}; DrawEdge: PROC [c1, c2: Corner] ~ {DrawSeg[c1.point, c2.point]}; Label: PROC [p: Triple, r: Rope.ROPE] ~ {G3dDraw.Mark[context, p, view, vp, r, none]}; DrawTriangle: PROC [t: Triangle, color: Triple, showNormal: BOOL] ~ { SetColor[color]; DrawSeg[t.p1, t.p2]; DrawSeg[t.p2, t.p3]; DrawSeg[t.p3, t.p1]; IF showNormal THEN { label: Rope.ROPE ¬ NIL; -- IF fwd THEN "forward" ELSE "backward"; SetColor[[0.0, 0.0, 1.0]]; G3dDraw.DrawVector[context, t.center, t.normal, view, vp, label]; }; }; DrawTetrahedron: PROC [t: Tetrahedron] ~ { DrawTriangle[[t.p1, t.p2, t.p3], [0.0, 1.0, 1.0], FALSE]; DrawTriangle[[t.p1, t.p2, t.p4], [0.0, 1.0, 1.0], FALSE]; DrawTriangle[[t.p1, t.p3, t.p4], [0.0, 1.0, 1.0], FALSE]; DrawTriangle[[t.p2, t.p3, t.p4], [0.0, 1.0, 1.0], FALSE]; }; DrawCube: PROC [c: REF Cube] ~ { SetColor[[0.0, 0.0, 0.0]]; DrawEdge[c.lbn, c.ltn]; DrawEdge[c.ltn, c.rtn]; DrawEdge[c.rtn, c.rbn]; DrawEdge[c.rbn, c.lbn]; DrawEdge[c.lbf, c.ltf]; DrawEdge[c.ltf, c.rtf]; DrawEdge[c.rtf, c.rbf]; DrawEdge[c.rbf, c.lbf]; DrawEdge[c.lbn, c.lbf]; DrawEdge[c.ltn, c.ltf]; DrawEdge[c.rtn, c.rtf]; DrawEdge[c.rbn, c.rbf]; }; vp: G3dTool.Viewport ¬ v.viewport; vp.translate.x ¬ vp.translate.x+(IF type = 1 THEN -150 ELSE 150); IF d.text THEN { SetColor[[0.0, 0.0, 0.0]]; ShowRope[vp.translate.x-75, 35, IO.PutFR["#%g (type %g)", IO.int[d.select], IO.int[type]]]; ShowRope[vp.translate.x-75, 20, IO.PutFR["%g triangles, %g tetrahedra", IO.int[NTriangles[c]], IO.int[NTetrahedra[c]]]]; }; DrawCube[c]; IF d.tets THEN FOR l: LIST OF Tetrahedron ¬ c.tetrahedra, l.rest WHILE l # NIL DO DrawTetrahedron[l.first]; ENDLOOP; FOR l: LIST OF Triangle ¬ c.triangles, l.rest WHILE l # NIL DO DrawTriangle[l.first, [0.0, 1.0, 0.0], d.nrms]; ENDLOOP; SetColor[[1.0, 0.0, 0.0]]; FOR l: LIST OF Corner¬LIST[c.lbn,c.lbf,c.ltn,c.ltf,c.rbn,c.rbf,c.rtn,c.rtf], l.rest WHILE l#NIL DO IF l.first.positive THEN DrawBox[l.first.point]; ENDLOOP; }; d: REF Data ¬ NARROW[clientData]; color: Triple ¬ [1.0, 1.0, 1.0]; v: G3dTool.View ¬ G3dTool.GetView[viewer, d.tool]; view: G3dTool.Matrix ¬ v.camera.matrix; Imager.SetFont[context, font]; DrawAll[d.cubes1[d.select], 1]; DrawAll[d.cubes2[d.select], 2]; }; But: Controls.ClickProc ~ { d: REF Data ¬ NARROW[clientData]; SELECT TRUE FROM Rope.Equal[parent.name, "STEP"] => d.select ¬ MIN[255, MAX[0, d.select+(IF mouseButton = red THEN 1 ELSE -1)]]; Rope.Equal[parent.name, "SET"] => d.select ¬ MIN[255, MAX[0, Controls.GetNat[d.tool.typescript, "select: ", d.select]]]; Rope.Find[parent.name, "Nrms"] # -1 => Controls.ButtonToggle[d.tool.outerData, d.nrms ¬ NOT d.nrms, "Nrms: On", "Nrms: Off"]; Rope.Find[parent.name, "Text"] # -1 => Controls.ButtonToggle[d.tool.outerData, d.text ¬ NOT d.text, "Text: On", "Text: Off"]; Rope.Find[parent.name, "Tets"] # -1 => Controls.ButtonToggle[d.tool.outerData, d.tets ¬ NOT d.tets, "Tets: On", "Tets: Off"]; Rope.Find[parent.name, "Labs"] # -1 => Controls.ButtonToggle[d.tool.outerData, d.lab ¬ NOT d.lab, "Labs: On", "Labs: Off"]; ENDCASE; G3dTool.Repaint[d.tool]; }; font: ImagerFont.Font ¬ ImagerFont.Find["xerox/tiogafonts/helvetica10"]; Commander.Register["TestTetEdges", TestTetEdgesCmd]; END. \ ImplicitTestTetEdgesImpl.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Bloomenthal, August 11, 1992 4:07 pm PDT corners presumed oriented such that b, c, d appear clockwise when viewed from a IF showNormal AND d.lab THEN { Label[t.p1, "1"]; Label[t.p2, "2"]; Label[t.p3, "3"]; }; fwd: BOOL ¬ G3dVector.FrontFacing[t.normal, t.center, view]; IF d.lab THEN { Label[c.lbn.point, "lbn"]; Label[c.lbf.point, "lbf"]; Label[c.ltn.point, "ltn"]; Label[c.ltf.point, "ltf"]; Label[c.rbn.point, "rbn"]; Label[c.rbf.point, "rbf"]; Label[c.rtn.point, "rtn"]; Label[c.rtf.point, "rtf"]; }; Κ œ•NewlineDelimiter ™™Jšœ<™šœ œœ˜4J˜—šœœœ˜Jšœ˜JšœŸœŸœŸœ ˜Jšœœœ œ˜%Jšœœœœ˜)J˜—šœœœ˜Jšœœ˜Jšœ  œ˜Jšœœœ˜#Jš œœ œœœœ˜8J˜—šΟnœ˜*Jšœœœ˜šœœ˜$J˜%J˜$J˜)J˜)J˜)J˜*—Jš œœœ œœ˜DJš œœœ œœ˜DJšœŸœŸœŸœ ŸœœŸœŸœŸœŸœ ˜]J˜J˜—š œœœ œ˜*š œœœ ˜4Jšœœœ˜(Jšœ)˜/J˜—š œœ˜5J™Oš œœœ˜)˜ Jš œŸœŸœŸœ!Ÿœ œ˜S—Jš œœ œœœ˜SJ˜—Jšœœ˜Jšœœ˜Jšœ˜J˜8Jšœœ˜,Jšœœ˜,Jšœœ˜,Jšœœ˜,šœœ œ˜*Jš œœœœœœ˜H—Jšœ œ˜(Jšœ œ˜(Jšœ œ˜(Jšœ œ˜(Jšœ œ˜(Jšœ œ˜(šœ˜Jšœ˜Jšœ˜Jšœ/˜/Jšœ˜Jšœ/˜/Jšœ/˜/Jšœ˜Jšœ˜Jšœ/˜/Jšœ/˜/Jšœ˜Jšœ/˜/Jšœ˜Jšœ˜JšœΟc˜—Jšœ˜—šœ ˜ šœ˜Jšœ?˜?Jšœ?˜?Jšœ?˜?Jšœ?˜?Jšœ?˜?Jšœ˜—šœ˜Jšœ?˜?Jšœ?˜?Jšœ?˜?Jšœ?˜?Jšœ?˜?Jšœ˜——J˜J˜—š  œœœœœœ ˜@š  œœœœœ˜4JšœŸœŸŸœŸŸœ1œ˜UJšœœœ œœœœœ˜NJ˜—š œœœ˜2šœŸœŸ˜JšœS˜SJšœ< œ˜S—J˜—Jšœœ˜JšœΟfœ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"Jšœ’œ ’œ ’œ˜"J˜J˜J˜—š œ˜š   œœœœœ ˜Jšœ/˜/Jšœ˜—J˜šŸœŸŸŸœœ2Ÿœ£ŸœŸ˜bJšœœ˜0Jšœ˜—J˜—Jšœœœ ˜!J˜ J˜2J˜'Jšœ˜Jšœ˜Jšœ˜J˜J˜—š œ˜Jšœœœ ˜!šœœ˜šœ"˜"Jš œ œœœœœ˜L—šœŸœ˜!Jš œŸœŸœŸœŸœ+Ÿœ˜V—šœ&˜&Jšœ1œ"˜V—šœ&˜&Jšœ1œ"˜V—šœ&˜&Jšœ1œ"˜V—šœ&˜&Jšœ0œ!˜T—Jšœ˜—J˜J˜J˜—J˜Hšœ4˜4J˜——Jš˜—…—!’.Š