<> <> <> <<>> DIRECTORY Atom USING [PutPropOnList], CADTypes USING [VertexSequence, TriangleSequence], FS USING [StreamOpen], Imager USING [black, Context, MaskFill, MaskStroke, PathProc, SetColor, SetStrokeEnd, SetStrokeJoint, SetStrokeWidth, StrokeEnd, StrokeJoint], ImagerColor USING [RGB], IO USING [Close, int, PutF, real, STREAM, RopeFromROS, ROS], <> RealFns USING [SqRt], Rope USING [ROPE], SceneUtilities USING [NewShape, ReadShape], ShapeUtilities USING [XfmPtToDisplay, XfmPtToEyeSpace], ThreeDBasics USING [Context, GetSurfaceType, ImagerProc, ImagerProcRec, NatSequence, PatchProc, PtrPatch, PtrPatchSequence, PutShading, RegisterSurfaceType, ShadingValue, ShadingSequence, ShapeClass, ShapeInstance, ShapeProc, Vertex, VertexSequence], ThreeDHacks USING [], ThreeDViewer USING [DrawInViewer], Geometry3dVector USING [Triple, TripleSequence]; ThreeDHacksImpl: CEDAR PROGRAM IMPORTS Atom, FS, Imager, IO, RealFns, SceneUtilities, ShapeUtilities, ThreeDBasics, ThreeDViewer EXPORTS ThreeDHacks ~ BEGIN RegisterNewClasses: PUBLIC PROC [context3d: REF ThreeDBasics.Context] ~ BEGIN <> <> <<>> standardClass: ThreeDBasics.ShapeClass _ ThreeDBasics.GetSurfaceType[$Bezier]; standardClass.type _ $FatPoint; <> standardClass.display _ NIL; standardClass.displayPatch _ FatPointPatchDisplayProc; ThreeDBasics.RegisterSurfaceType[standardClass, $FatPoint]; standardClass.type _ $FatSeg; <> standardClass.displayPatch _ FatSegPatchDisplayProc; ThreeDBasics.RegisterSurfaceType[standardClass, $FatSeg]; END; FatPointPatchDisplayProc: ThreeDBasics.PatchProc ~ BEGIN <> <> dataList: LIST OF REAL; coordinates, eyespaceCoordinates, screenCoordinates: Geometry3dVector.Triple; <> coordinates _ [ x: patch.vtx[0].coord.x, y: patch.vtx[0].coord.y, z: patch.vtx[0].coord.z]; [eyespaceCoordinates] _ ShapeUtilities.XfmPtToEyeSpace[context, coordinates]; screenCoordinates _ ShapeUtilities.XfmPtToDisplay[context, eyespaceCoordinates]; dataList _ LIST[screenCoordinates.x, screenCoordinates.y]; <<>> <> ThreeDViewer.DrawInViewer[context, NEW[ThreeDBasics.ImagerProcRec _ [proc: FatPointImagerProc, data: dataList]]]; RETURN[NIL]; END; FatPointImagerProc: ThreeDBasics.ImagerProc _ BEGIN <> dataList: LIST OF REAL _ NARROW[data]; screenX: REAL _ dataList.first; screenY: REAL _ dataList.rest.first; Path: Imager.PathProc ~ BEGIN moveTo[[screenX+10, screenY]]; arcTo[[screenX-10, screenY], [screenX+10, screenY]]; END; Imager.SetColor[imagerCtx, Imager.black]; --Fill in the outline, colored black Imager.MaskFill[imagerCtx, Path]; END; FatSegPatchDisplayProc: ThreeDBasics.PatchProc ~ BEGIN <> <> dataList: LIST OF REAL; p0Coordinates, p0EyespaceCoordinates, p0ScreenCoordinates, p1Coordinates, p1EyespaceCoordinates, p1ScreenCoordinates: Geometry3dVector.Triple; <> p0Coordinates _ [ x: patch.vtx[0].coord.x, y: patch.vtx[0].coord.y, z: patch.vtx[0].coord.z]; [p0EyespaceCoordinates] _ ShapeUtilities.XfmPtToEyeSpace[context, p0Coordinates]; p0ScreenCoordinates _ ShapeUtilities.XfmPtToDisplay[context, p0EyespaceCoordinates]; p1Coordinates _ [ x: patch.vtx[1].coord.x, y: patch.vtx[1].coord.y, z: patch.vtx[1].coord.z]; [p1EyespaceCoordinates] _ ShapeUtilities.XfmPtToEyeSpace[context, p1Coordinates]; p1ScreenCoordinates _ ShapeUtilities.XfmPtToDisplay[context, p1EyespaceCoordinates]; dataList _ LIST[p0ScreenCoordinates.x, p0ScreenCoordinates.y, p1ScreenCoordinates.x, p1ScreenCoordinates.y]; <> ThreeDViewer.DrawInViewer[context, NEW[ThreeDBasics.ImagerProcRec _ [proc: FatSegImagerProc, data: dataList]]]; <<>> <> IF patch.clipState = clipped THEN RETURN[NIL]; RETURN[NIL]; END; FatSegImagerProc: ThreeDBasics.ImagerProc _ BEGIN dataList: LIST OF REAL _ NARROW[data]; firstScreenX: REAL _ dataList.first; firstScreenY: REAL _ dataList.rest.first; secondScreenX: REAL _ dataList.rest.rest.first; secondScreenY: REAL _ dataList.rest.rest.rest.first; Path: Imager.PathProc ~ BEGIN moveTo[[firstScreenX, firstScreenY]]; lineTo[[secondScreenX, secondScreenY]]; END; Imager.SetColor[imagerCtx, Imager.black]; Imager.SetStrokeWidth[imagerCtx, 5]; Imager.SetStrokeEnd[imagerCtx, round]; Imager.SetStrokeJoint[imagerCtx, round]; Imager.MaskStroke[imagerCtx, Path]; END; MakeFatPoint: PUBLIC PROC [name: Rope.ROPE, position: Geometry3dVector.Triple] RETURNS [newFatPoint: REF ThreeDBasics.ShapeInstance] ~ BEGIN <> <<>> <> nullVertex: ThreeDBasics.Vertex; nullShade: ThreeDBasics.ShadingValue; surface: REF ThreeDBasics.PtrPatchSequence; <> newFatPoint _ SceneUtilities.NewShape[name]; newFatPoint.fileName _ ""; newFatPoint.numSurfaces _ 1; newFatPoint.class^ _ ThreeDBasics.GetSurfaceType[$FatPoint]; newFatPoint.insideVisible _ TRUE; <> newFatPoint.vertex _ NEW[ThreeDBasics.VertexSequence[3]]; newFatPoint.vertex.length _ 3; newFatPoint.shade _ NEW[ThreeDBasics.ShadingSequence[3]]; newFatPoint.shade.length _ 3; FOR i: NAT IN [0..3) DO newFatPoint.vertex[i] _ NEW[ThreeDBasics.Vertex _ nullVertex]; newFatPoint.shade[i] _ NEW[ThreeDBasics.ShadingValue _ nullShade]; ENDLOOP; ThreeDBasics.PutShading[newFatPoint, $Color, NEW[ImagerColor.RGB _ [0.7, 0.7, 0.7]]]; <> newFatPoint.vertex[0].x _ position.x; newFatPoint.vertex[0].y _ position.y; newFatPoint.vertex[0].z _ position.z; newFatPoint.vertex[1].x _ position.x + 0.10; newFatPoint.vertex[1].y _ position.y; newFatPoint.vertex[1].z _ position.z; newFatPoint.vertex[2].x _ position.x; newFatPoint.vertex[2].y _ position.y + 0.01; newFatPoint.vertex[2].z _ position.z; <> newFatPoint.surface _ NEW[ThreeDBasics.PtrPatchSequence[1]]; surface _ NARROW[newFatPoint.surface, REF ThreeDBasics.PtrPatchSequence]; surface[0] _ NEW[ThreeDBasics.PtrPatch]; surface[0].vtxPtr _ NEW[ThreeDBasics.NatSequence[3]]; surface[0].vtxPtr.length _ 3; surface[0].nVtces _ 3; surface[0].type _ $FatPoint; surface[0].oneSided _ FALSE; surface[0].vtxPtr[0] _ 0; surface[0].vtxPtr[1] _ 1; surface[0].vtxPtr[2] _ 2; surface[0].props _ Atom.PutPropOnList[NIL, $ShapeName, name]; <> newFatPoint.centroid.x _ position.x; newFatPoint.centroid.y _ position.y; newFatPoint.centroid.z _ position.z; newFatPoint.boundingRadius _ 0.1; END; MakeFatSeg: PUBLIC PROC [name: Rope.ROPE, points: Geometry3dVector.TripleSequence] RETURNS [newFatSeg: REF ThreeDBasics.ShapeInstance] ~ BEGIN <> nullVertex: ThreeDBasics.Vertex; nullShade: ThreeDBasics.ShadingValue; surface: REF ThreeDBasics.PtrPatchSequence; radius: REAL; <> newFatSeg _ SceneUtilities.NewShape[name]; <> IF points.length < 2 THEN RETURN; <> <> <> <> <> <<>> newFatSeg.fileName _ ""; newFatSeg.numSurfaces _ points.length - 1; newFatSeg.class^ _ ThreeDBasics.GetSurfaceType[$FatSeg]; newFatSeg.insideVisible _ TRUE; <> newFatSeg.vertex _ NEW[ThreeDBasics.VertexSequence[points.length]]; newFatSeg.shade _ NEW[ThreeDBasics.ShadingSequence[points.length]]; FOR i: NAT IN [0..points.length) DO newFatSeg.vertex[i] _ NEW[ThreeDBasics.Vertex _ nullVertex]; newFatSeg.shade[i] _ NEW[ ThreeDBasics.ShadingValue _ nullShade]; ENDLOOP; ThreeDBasics.PutShading[newFatSeg, $Color, NEW[ImagerColor.RGB _ [0.7, 0.7, 0.7]]]; <> FOR i: NAT IN [0..points.length) DO newFatSeg.vertex[i].x _ points[i].x; newFatSeg.vertex[i].y _ points[i].y; newFatSeg.vertex[i].z _ points[i].z; ENDLOOP; <> newFatSeg.surface _ NEW[ThreeDBasics.PtrPatchSequence[points.length - 1]]; surface _ NARROW[newFatSeg.surface, REF ThreeDBasics.PtrPatchSequence]; FOR i: NAT IN [0..points.length - 1) DO surface[i] _ NEW[ThreeDBasics.PtrPatch]; surface[i].vtxPtr _ NEW[ThreeDBasics.NatSequence[3]]; surface[i].vtxPtr.length _ 3; surface[i].nVtces _ 3; surface[i].type _ $FatSeg; surface[i].oneSided _ FALSE; surface[i].vtxPtr[0] _ i; surface[i].vtxPtr[1] _ i + 1; surface[i].vtxPtr[2] _ i; ENDLOOP; <> newFatSeg.centroid.x _ newFatSeg.vertex[0].x; newFatSeg.centroid.y _ newFatSeg.vertex[0].y; newFatSeg.centroid.z _ newFatSeg.vertex[0].z; newFatSeg.boundingRadius _ 0; FOR i: NAT IN [0..points.length) DO radius _ RealFns.SqRt[ Sqr[newFatSeg.vertex[i].x - newFatSeg.centroid.x] + Sqr[newFatSeg.vertex[i].y - newFatSeg.centroid.y] + Sqr[newFatSeg.vertex[i].z - newFatSeg.centroid.z]]; IF radius > newFatSeg.boundingRadius THEN newFatSeg.boundingRadius _ radius; ENDLOOP; END; MakeTwoCell: PUBLIC PROC [name: Rope.ROPE, vertices: REF CADTypes.VertexSequence, triangles: REF CADTypes.TriangleSequence] RETURNS [newTwoCell: REF ThreeDBasics.ShapeInstance] ~ BEGIN <> shapeOutStream: IO.STREAM; shapeFileRope: Rope.ROPE; tempFileName: Rope.ROPE ~ "[]<>Foo>TemporaryTwoCellFile"; tempFileOutStream: IO.STREAM; <> shapeOutStream _ IO.ROS[]; <> IO.PutF[shapeOutStream, "TemporaryTwoCellFile\n"]; IO.PutF[shapeOutStream, "\nSurfaceType ~ ConvexPolygon, InsideVisible, CountFromOne\n"]; IO.PutF[shapeOutStream, "\nVertices ~ xyzCoords: triple\n\n"]; <> FOR i: NAT IN [0..vertices.nVertices) DO IO.PutF[ shapeOutStream, "\t%g\t%g\t%g\n", IO.real[vertices[i].x], IO.real[vertices[i].y], IO.real[vertices[i].z]]; ENDLOOP; <> IO.PutF[shapeOutStream, "\nPolygons ~ index: integer vertices: nats\n\n"]; FOR i: NAT IN [0..triangles.nTriangles) DO IO.PutF[ shapeOutStream, "\t%g\t%g\t%g\t%g\n", IO.int[3], IO.int[triangles[i].firstVertex], IO.int[triangles[i].secondVertex], IO.int[triangles[i].thirdVertex]]; ENDLOOP; <> shapeFileRope _ IO.RopeFromROS[shapeOutStream]; tempFileOutStream _ FS.StreamOpen[tempFileName, $create]; IO.PutF[tempFileOutStream, shapeFileRope]; IO.Close[tempFileOutStream]; <> newTwoCell _ SceneUtilities.NewShape[name]; <> IF triangles.nTriangles > 0 THEN SceneUtilities.ReadShape[newTwoCell, tempFileName]; -- 9/22/86 - test put in for empty shapes <> END; Foo: SIGNAL = CODE; AnotherMakeTwoCell: PROC [name: Rope.ROPE, vertices: REF CADTypes.VertexSequence, triangles: REF CADTypes.TriangleSequence] RETURNS [newTwoCell: REF ThreeDBasics.ShapeInstance] ~ BEGIN <> min, max: Geometry3dVector.Triple; nullVertex: ThreeDBasics.Vertex; nullShade: ThreeDBasics.ShadingValue; surface: REF ThreeDBasics.PtrPatchSequence; <<>> <> newTwoCell _ SceneUtilities.NewShape[name]; newTwoCell.fileName _ ""; newTwoCell.numSurfaces _ triangles.nTriangles; <> <> newTwoCell.insideVisible _ TRUE; <> newTwoCell.vertex _ NEW[ThreeDBasics.VertexSequence[vertices.nVertices]]; newTwoCell.shade _ NEW[ThreeDBasics.ShadingSequence[vertices.nVertices]]; FOR i: NAT IN [0..vertices.nVertices) DO newTwoCell.vertex[i] _ NEW[ThreeDBasics.Vertex _ nullVertex]; newTwoCell.shade[i] _ NEW[ ThreeDBasics.ShadingValue _ nullShade]; ENDLOOP; ThreeDBasics.PutShading[newTwoCell, $Color, NEW[ImagerColor.RGB _ [0.2, 0.8, 0.8]]]; <> FOR i: NAT IN [0..vertices.nVertices) DO newTwoCell.vertex[i].x _ vertices[i].x; newTwoCell.vertex[i].y _ vertices[i].y; newTwoCell.vertex[i].z _ vertices[i].z; ENDLOOP; <> newTwoCell.surface _ NEW[ThreeDBasics.PtrPatchSequence[triangles.nTriangles]]; surface _ NARROW[newTwoCell.surface, REF ThreeDBasics.PtrPatchSequence]; FOR i: NAT IN [0..triangles.nTriangles) DO surface[i] _ NEW[ThreeDBasics.PtrPatch]; surface[i].vtxPtr _ NEW[ThreeDBasics.NatSequence[3]]; surface[i].vtxPtr.length _ 3; surface[i].nVtces _ 3; surface[i].type _ $ConvexPolygon; surface[i].oneSided _ FALSE; surface[i].vtxPtr[0] _ triangles[i].firstVertex; surface[i].vtxPtr[1] _ triangles[i].secondVertex; surface[i].vtxPtr[2] _ triangles[i].thirdVertex; ENDLOOP; <> min _ max _ [newTwoCell.vertex[0].x, newTwoCell.vertex[0].y, newTwoCell.vertex[0].z]; FOR i: NAT IN (0..newTwoCell.vertex.length) DO IF newTwoCell.vertex[i] # NIL THEN BEGIN IF newTwoCell.vertex[i].x < min.x THEN min.x _ newTwoCell.vertex[i].x ELSE IF newTwoCell.vertex[i].x > max.x THEN max.x _ newTwoCell.vertex[i].x; IF newTwoCell.vertex[i].y < min.y THEN min.y _ newTwoCell.vertex[i].y ELSE IF newTwoCell.vertex[i].y > max.y THEN max.y _ newTwoCell.vertex[i].y; IF newTwoCell.vertex[i].z < min.z THEN min.z _ newTwoCell.vertex[i].z ELSE IF newTwoCell.vertex[i].x > max.z THEN max.z _ newTwoCell.vertex[i].z; END; ENDLOOP; newTwoCell.centroid.x _ (min.x + max.x) / 2; newTwoCell.centroid.y _ (min.y + max.y) / 2; newTwoCell.centroid.z _ (min.z + max.z) / 2; newTwoCell.boundingRadius _ 0.; FOR i: NAT IN [0..newTwoCell.vertex.length) DO radius: REAL _ RealFns.SqRt[ Sqr[newTwoCell.vertex[i].x - newTwoCell.centroid.x] + Sqr[newTwoCell.vertex[i].y - newTwoCell.centroid.y] + Sqr[newTwoCell.vertex[i].z - newTwoCell.centroid.z] ]; IF radius > newTwoCell.boundingRadius THEN newTwoCell.boundingRadius _ radius; ENDLOOP; newTwoCell _ SceneUtilities.NewShape[name]; SceneUtilities.ReadShape[newTwoCell, "[]<>Users>Rauen.pa>AlgebraicSurfaces>ChampagneGlass.shape"]; END; Sqr: PROC [number: REAL] RETURNS [result: REAL] ~ BEGIN result _ number * number; END; END.