DIRECTORY CADIO, CADTypes USING [CellRec, CellSequence, CompoundOperator, QuantifierFreeFormula, QuantifierFreeFormulaSequence, Scad, SimpleOperator, TriangleSequence, VariableRec, VertexSequence, VisibleMask], Convert, FormulaOperators, Formulas, FS USING [StreamOpen], Interminal USING [MousePosition], IO USING [BreakProc, Close, CR, GetTokenRope, IDProc, int, NUL, PutF, PutFR, real, rope, SP, STREAM], MultiPolynomial USING [EvaluationBindings, RefFromRope, RopeFromRef, TotallyEvaluate], AlgebraClasses, Ints, Polynomials, Points, Sequences, CoveringSets, Triangles, Cells, Cads, Reals, Rope USING [Compare, Concat, ROPE], Geometry3dVector USING [Triple]; CADIOImpl: CEDAR PROGRAM IMPORTS Convert, FS, IO, MultiPolynomial, Polynomials, PopUpMenu, Triangles, Cads, Rope EXPORTS CADIO ~ BEGIN Error: PUBLIC ERROR[why: ATOM] = CODE; ReadVAXCadFiles: PUBLIC PROC [cadFile, csFile: Rope.ROPE] RETURNS [info: CADTypes.Scad] ~ BEGIN cadStream, csStream: IO.STREAM; qeCad: Cads.Cad; qeCadData: Cads.CadData; oldCellsData: Sequences.SequenceData; polySeqData: Sequences.SequenceData; cellData: Cells.CellData; pointData: Points.PointData; inputPoly: Polynomials.Polynomial; cadStructure: AlgebraClasses.Structure _ Cads.MakeCadStructure[]; surfaceRope: Rope.ROPE; oldCells: Sequences.Sequence; numberOfOldCells: NAT; newCells: REF CADTypes.CellSequence; newCellIndex: NAT; compressedNewCells: REF CADTypes.CellSequence; TranslateQFF: PROC [old: Formulas.Formula] RETURNS [new: CADTypes.QuantifierFreeFormula] ~ BEGIN oldData: Formulas.FormulaData _ NARROW[old.data]; mainOp: FormulaOperators.Op _ NARROW[oldData.mainOperator.data, FormulaOperators.OperatorData]^; IF oldData.atomicMatrix THEN BEGIN newOperator: CADTypes.SimpleOperator; SELECT mainOp FROM lt => newOperator _ isNegative; gt => newOperator _ isPositive; eq => newOperator _ isZero; le, ge, ne => ERROR Error[$UnimplementedOperator]; ENDCASE => ERROR Error[$BadOperator]; RETURN [[ isCompound: FALSE, compoundOperator: none, compoundArguments: NIL, simpleOperator: newOperator, simpleArgument: MultiPolynomial.RefFromRope[Polynomials.ToRope[oldData.polynomial]] ]]; END ELSE BEGIN newOperator: CADTypes.CompoundOperator; newOperands: REF CADTypes.QuantifierFreeFormulaSequence; oldOperands: LIST OF Formulas.Formula; nOperands: NAT; SELECT mainOp FROM and => newOperator _ and; or => newOperator _ or; not => ERROR Error[$UnimplementedOperator]; ENDCASE => ERROR Error[$BadOperator]; nOperands _ 0; oldOperands _ oldData.operands; UNTIL oldOperands = NIL DO nOperands _ nOperands + 1; oldOperands _ oldOperands.rest; ENDLOOP; newOperands _ NEW[CADTypes.QuantifierFreeFormulaSequence[nOperands]]; oldOperands _ oldData.operands; FOR i: NAT IN [0..nOperands) DO newOperands[i] _ TranslateQFF[oldOperands.first]; oldOperands _ oldOperands.rest; ENDLOOP; RETURN [[ isCompound: TRUE, compoundOperator: newOperator, compoundArguments: newOperands, simpleOperator: none, simpleArgument: NIL ]]; END; END; cadStream _ FS.StreamOpen[cadFile]; qeCad _ cadStructure.class.read[cadStream, cadStructure]; csStream _ FS.StreamOpen[csFile]; Cads.ReadCSets[csStream, qeCad]; qeCadData _ NARROW[qeCad.data]; polySeqData _ NARROW[qeCadData.inputPolynomials.data]; inputPoly _ polySeqData[1]; surfaceRope _ inputPoly.structure.class.toRope[inputPoly]; oldCells _ qeCadData.cells; oldCellsData _ NARROW[oldCells.data]; numberOfOldCells _ oldCellsData.lengthPlus1 - 1; newCells _ NEW[CADTypes.CellSequence[numberOfOldCells]]; newCellIndex _ 0; FOR oldCellIndex: NAT IN [1..numberOfOldCells] DO cellData _ NARROW[oldCellsData[oldCellIndex].data]; pointData _ NARROW[cellData.index.data]; IF NARROW[pointData[3].data, Ints.IntData]^ MOD 2 = 0 THEN BEGIN newCells[newCellIndex].indexX _ NARROW[pointData[1].data, Ints.IntData]^; newCells[newCellIndex].indexY _ NARROW[pointData[2].data, Ints.IntData]^; newCells[newCellIndex].indexZ _ NARROW[pointData[3].data, Ints.IntData]^; newCells[newCellIndex].dimension _ cellData.dimension; newCells[newCellIndex].definingFormula _ TranslateQFF[cellData.definingFormula]; SELECT newCells[newCellIndex].dimension FROM 0 => BEGIN xReal, yReal, zReal: REAL; coveringSetData: CoveringSets.CoveringSetData _ NARROW[cellData.coveringSet.data]; setData: Sequences.SequenceData _ NARROW[coveringSetData.dataPoints.data]; columnData: Sequences.SequenceData _ NARROW[setData[1].data]; pointData: Points.PointData _ NARROW[columnData[1].data ]; newCells[newCellIndex].vertices _ NEW[CADTypes.VertexSequence[1]]; xReal _ NARROW[pointData[1].data, Reals.RealData]^; yReal _ NARROW[pointData[2].data, Reals.RealData]^; zReal _ NARROW[pointData[3].data, Reals.RealData]^; newCells[newCellIndex].vertices[0] _ [ x: xReal, y: yReal, z: zReal ]; newCells[newCellIndex].polygons _ NEW[CADTypes.TriangleSequence[0]]; END; 1 => BEGIN coveringSetData: CoveringSets.CoveringSetData _ NARROW[cellData.coveringSet.data]; setData: Sequences.SequenceData _ NARROW[coveringSetData.dataPoints.data]; columnData: Sequences.SequenceData _ NARROW[setData[1].data]; numberOfPoints: NAT _ columnData.lengthPlus1 - 1; newCells[newCellIndex].vertices _ NEW[CADTypes.VertexSequence[numberOfPoints]]; FOR j: NAT IN [0..numberOfPoints) DO xReal, yReal, zReal: REAL; pointData: Points.PointData _ NARROW[columnData[j + 1].data ]; xReal _ NARROW[pointData[1].data, Reals.RealData]^; yReal _ NARROW[pointData[2].data, Reals.RealData]^; zReal _ NARROW[pointData[3].data, Reals.RealData]^; newCells[newCellIndex].vertices[j] _ [ x: xReal, y: yReal, z: zReal ]; ENDLOOP; newCells[newCellIndex].polygons _ NEW[CADTypes.TriangleSequence[0]]; END; 2 => BEGIN numberOfPoints, pointIndex: NAT; triangulation: Triangles.TriangleSeq; coveringSetData: CoveringSets.CoveringSetData _ NARROW[cellData.coveringSet.data]; setData: Sequences.SequenceData _ NARROW[coveringSetData.dataPoints.data]; numberOfPoints _ 0; FOR i: NAT IN [1..setData.lengthPlus1) DO columnData: Sequences.SequenceData _ NARROW[setData[i].data]; numberOfPoints _ numberOfPoints + columnData.lengthPlus1 - 1; ENDLOOP; newCells[newCellIndex].vertices _ NEW[CADTypes.VertexSequence[numberOfPoints]]; pointIndex _ 0; FOR i: NAT IN [1..setData.lengthPlus1) DO columnData: Sequences.SequenceData _ NARROW[setData[i].data]; FOR j: NAT IN [1..columnData.lengthPlus1) DO xReal, yReal, zReal: REAL; pointData: Points.PointData _ NARROW[columnData[j].data ]; xReal _ NARROW[pointData[1].data, Reals.RealData]^; yReal _ NARROW[pointData[2].data, Reals.RealData]^; zReal _ NARROW[pointData[3].data, Reals.RealData]^; newCells[newCellIndex].vertices[pointIndex] _ [ x: xReal, y: yReal, z: zReal ]; pointIndex _ pointIndex + 1; ENDLOOP; ENDLOOP; triangulation _ Triangles.GenerateTriangles[cellData.coveringSet]; IF triangulation = NIL THEN newCells[newCellIndex].polygons _ NEW[CADTypes.TriangleSequence[0]] ELSE { newCells[newCellIndex].polygons _ NEW[CADTypes.TriangleSequence [triangulation.trianglesPlusOne - 1]]; FOR i: NAT IN [1..triangulation.trianglesPlusOne) DO newCells[newCellIndex].polygons[i - 1] _ [ firstVertex: triangulation[i].firstVertex, secondVertex: triangulation[i].secondVertex, thirdVertex: triangulation[i].thirdVertex ]; ENDLOOP; }; END; ENDCASE => BEGIN ERROR Error[$DegreeOutOfRange]; END; newCellIndex _ newCellIndex + 1; END; ENDLOOP; compressedNewCells _ NEW[CADTypes.CellSequence[newCellIndex]]; FOR i: NAT IN [0..newCellIndex) DO compressedNewCells[i] _ newCells[i]; ENDLOOP; info _ [ surface: MultiPolynomial.RefFromRope[surfaceRope], named: FALSE, name: "(none)", color: [1, 1, 1], cells: compressedNewCells]; END; ReadInfoFile: PUBLIC PROC [filename: Rope.ROPE] RETURNS [info: CADTypes.Scad] ~ BEGIN infoStream: IO.STREAM _ FS.StreamOpen[filename]; token: Rope.ROPE _ ""; InfoFileError: ERROR = CODE; TestError: ERROR = CODE; Break: SIGNAL = CODE; BreakProc: IO.BreakProc ~ IO.IDProc; numberOfCells: NAT; TokenBreakProc: IO.BreakProc ~ BEGIN RETURN [SELECT char FROM IN [IO.NUL .. IO.SP], '$ => sepr, ENDCASE => other ]; END; PolynomialBreakProc: IO.BreakProc ~ BEGIN RETURN [SELECT char FROM '$, IO.CR => break, ENDCASE => other ]; END; NextToken: PROC [proc: IO.BreakProc _ TokenBreakProc] RETURNS [Rope.ROPE] ~ BEGIN token: Rope.ROPE; [token: token] _ IO.GetTokenRope[infoStream, proc]; RETURN [token]; END; GetDefiningFormula: PROC RETURNS [CADTypes.QuantifierFreeFormula] ~ BEGIN operatorRope: Rope.ROPE; simpleOperator: CADTypes.SimpleOperator; compoundOperator: CADTypes.CompoundOperator; isCompound: BOOLEAN; operatorRope _ NextToken[]; IF Rope.Compare[operatorRope, "IsPositive"] = equal THEN {simpleOperator _ isPositive; isCompound _ FALSE} ELSE IF Rope.Compare[operatorRope, "IsZero"] = equal THEN {simpleOperator _ isZero; isCompound _ FALSE} ELSE IF Rope.Compare[operatorRope, "IsNegative"] = equal THEN {simpleOperator _ isNegative; isCompound _ FALSE} ELSE IF Rope.Compare[operatorRope, "And"] = equal THEN {compoundOperator _ and; isCompound _ TRUE} ELSE IF Rope.Compare[operatorRope, "Or"] = equal THEN {compoundOperator _ or; isCompound _ TRUE} ELSE ERROR InfoFileError; IF ~isCompound THEN BEGIN polyRope: Rope.ROPE _ NextToken[PolynomialBreakProc]; RETURN [[ isCompound: FALSE, compoundOperator: none, compoundArguments: NIL, simpleOperator: simpleOperator, simpleArgument: MultiPolynomial.RefFromRope[polyRope] ]]; END ELSE BEGIN numberOfArguments: NAT _ Convert.IntFromRope[NextToken[]]; qff: CADTypes.QuantifierFreeFormula _ [ isCompound: TRUE, compoundOperator: compoundOperator, compoundArguments: NEW[CADTypes.QuantifierFreeFormulaSequence[numberOfArguments]], simpleOperator: none, simpleArgument: NIL]; FOR argument: NAT IN [0..numberOfArguments) DO qff.compoundArguments[argument] _ GetDefiningFormula[]; ENDLOOP; RETURN [qff]; END; END; UNTIL Rope.Compare[token, "BEGIN"] = equal DO token _ NextToken[]; ENDLOOP; IF Rope.Compare[NextToken[], "CAD"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "DESCRIPTION"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "Surface"] # equal THEN ERROR InfoFileError; token _ NextToken[PolynomialBreakProc]; info.surface _ MultiPolynomial.RefFromRope[token]; IF Rope.Compare[NextToken[], "Name"] # equal THEN ERROR InfoFileError; token _ NextToken[]; IF Rope.Compare[token, "UNNAMED"] = equal THEN BEGIN info.named _ FALSE; info.name _ "(unnamed)"; END ELSE BEGIN info.named _ TRUE; info.name _ token; END; IF Rope.Compare[NextToken[], "Color"] # equal THEN ERROR InfoFileError; info.color.R _ Convert.RealFromRope[NextToken[]]; info.color.G _ Convert.RealFromRope[NextToken[]]; info.color.B _ Convert.RealFromRope[NextToken[]]; IF Rope.Compare[NextToken[], "Cells"] # equal THEN ERROR InfoFileError; numberOfCells _ Convert.IntFromRope[NextToken[]]; info.cells _ NEW[CADTypes.CellSequence[numberOfCells]]; IF Rope.Compare[NextToken[], "BEGIN"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "CELL"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "DEFINITIONS"] # equal THEN ERROR InfoFileError; FOR cell: NAT IN [0..numberOfCells) DO dimension: CARDINAL; IF Rope.Compare[NextToken[], "CellIndices"] # equal THEN ERROR InfoFileError; info.cells[cell].indexX _ Convert.IntFromRope[NextToken[]]; info.cells[cell].indexY _ Convert.IntFromRope[NextToken[]]; info.cells[cell].indexZ _ Convert.IntFromRope[NextToken[]]; IF Rope.Compare[NextToken[], "CellDegree"] # equal THEN ERROR InfoFileError; dimension _ Convert.CardFromRope[NextToken[]]; IF dimension > 2 THEN ERROR InfoFileError; info.cells[cell].dimension _ dimension; IF Rope.Compare[NextToken[], "DefiningFormula"] # equal THEN ERROR InfoFileError; info.cells[cell].definingFormula _ GetDefiningFormula[]; ENDLOOP; IF Rope.Compare[NextToken[], "END"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "CELL"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "DEFINITIONS"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "BEGIN"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "CELL"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "DISPLAY"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "INFORMATION"] # equal THEN ERROR InfoFileError; FOR cell: NAT IN [0..numberOfCells) DO dimension: CARDINAL; nVertices, nTriangles: NAT; IF Rope.Compare[NextToken[], "Indices"] # equal THEN ERROR InfoFileError; IF Convert.IntFromRope[NextToken[]] # info.cells[cell].indexX THEN ERROR InfoFileError; IF Convert.IntFromRope[NextToken[]] # info.cells[cell].indexY THEN ERROR InfoFileError; IF Convert.IntFromRope[NextToken[]] # info.cells[cell].indexZ THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "Degree"] # equal THEN ERROR InfoFileError; dimension _ Convert.CardFromRope[NextToken[]]; IF dimension # info.cells[cell].dimension THEN ERROR InfoFileError; IF dimension = 0 THEN BEGIN IF Rope.Compare[NextToken[], "Position"] # equal THEN ERROR InfoFileError; info.cells[cell].vertices _ NEW[CADTypes.VertexSequence[1]]; info.cells[cell].vertices[0].x _ Convert.RealFromRope[NextToken[]]; info.cells[cell].vertices[0].y _ Convert.RealFromRope[NextToken[]]; info.cells[cell].vertices[0].z _ Convert.RealFromRope[NextToken[]]; END ELSE IF dimension = 1 OR dimension = 2 THEN BEGIN IF Rope.Compare[NextToken[], "Vertices"] # equal THEN ERROR InfoFileError; nVertices _ Convert.IntFromRope[NextToken[]]; info.cells[cell].vertices _ NEW[CADTypes.VertexSequence[nVertices]]; FOR i: NAT IN [0..nVertices) DO info.cells[cell].vertices[i].x _ Convert.RealFromRope[NextToken[]]; info.cells[cell].vertices[i].y _ Convert.RealFromRope[NextToken[]]; info.cells[cell].vertices[i].z _ Convert.RealFromRope[NextToken[]]; ENDLOOP; END ELSE ERROR InfoFileError; IF dimension = 2 THEN BEGIN IF Rope.Compare[NextToken[], "Triangles"] # equal THEN ERROR InfoFileError; nTriangles _ Convert.IntFromRope[NextToken[]]; info.cells[cell].polygons _ NEW[CADTypes.TriangleSequence[nTriangles]]; FOR i: NAT IN [0..nTriangles) DO info.cells[cell].polygons[i].firstVertex _ Convert.IntFromRope[NextToken[]]; info.cells[cell].polygons[i].secondVertex _ Convert.IntFromRope[NextToken[]]; info.cells[cell].polygons[i].thirdVertex _ Convert.IntFromRope[NextToken[]]; ENDLOOP; END ELSE BEGIN info.cells[cell].polygons _ NEW[CADTypes.TriangleSequence[0]]; END; ENDLOOP; IF Rope.Compare[NextToken[], "END"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "CELL"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "DISPLAY"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "INFORMATION"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "END"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "CAD"] # equal THEN ERROR InfoFileError; IF Rope.Compare[NextToken[], "DESCRIPTION"] # equal THEN ERROR InfoFileError; END; WriteInfoFile: PUBLIC PROC [filename: Rope.ROPE, info: CADTypes.Scad] ~ BEGIN infoStream: IO.STREAM _ FS.StreamOpen[filename, $create]; InternalError: ERROR = CODE; WriteDefiningFormula: PROC[df: CADTypes.QuantifierFreeFormula, nesting: NAT _ 2] ~ BEGIN operatorRope: Rope.ROPE _ IF df.isCompound THEN SELECT df.compoundOperator FROM and => "And", or => "Or", ENDCASE => ERROR InternalError ELSE SELECT df.simpleOperator FROM isPositive => "IsPositive", isZero => "IsZero", isNegative => "IsNegative" ENDCASE => ERROR InternalError; IF nesting # 2 THEN FOR i: NAT IN [1..nesting] DO IO.PutF[infoStream, "\t"]; ENDLOOP; IF df.isCompound THEN BEGIN IO.PutF[ infoStream, "%g %g\n", IO.rope[operatorRope], IO.int[df.compoundArguments.length]]; FOR formula: NAT IN [0..df.compoundArguments.length) DO WriteDefiningFormula[df.compoundArguments[formula], nesting + 1]; ENDLOOP; END ELSE BEGIN IO.PutF[ infoStream, "%g %g\n", IO.rope[operatorRope], IO.rope[MultiPolynomial.RopeFromRef[df.simpleArgument]]]; END; END; IO.PutF[infoStream, "BEGIN CAD DESCRIPTION\n\n"]; IO.PutF[ infoStream, "\tSurface %g\n", IO.rope[MultiPolynomial.RopeFromRef[info.surface]]]; IF info.named THEN IO.PutF[infoStream, "\tName %g\n", IO.rope[info.name]] ELSE IO.PutF[infoStream, "\tName UNNAMED\n"]; IO.PutF[ infoStream, "\tColor %g %g %g\n", IO.real[info.color.R], IO.real[info.color.G], IO.real[info.color.B]]; IO.PutF[infoStream, "\tCells %g\n", IO.int[info.cells.nCells]]; IO.PutF[infoStream, "\n\tBEGIN CELL DEFINITIONS\n"]; FOR cell: NAT IN [0..info.cells.nCells) DO IO.PutF[ infoStream, "\n\t\tCellIndices %g %g %g\n", IO.int[info.cells[cell].indexX], IO.int[info.cells[cell].indexY], IO.int[info.cells[cell].indexZ]]; IO.PutF[infoStream, "\t\tCellDegree %g\n", IO.int[info.cells[cell].dimension]]; IO.PutF[infoStream, "\t\tDefiningFormula "]; WriteDefiningFormula[info.cells[cell].definingFormula, 2]; ENDLOOP; IO.PutF[infoStream, "\n\tEND CELL DEFINITIONS\n"]; IO.PutF[infoStream, "\n\tBEGIN CELL DISPLAY INFORMATION\n"]; FOR cell: NAT IN [0..info.cells.nCells) DO dimension: CARDINAL _ info.cells[cell].dimension; nVertices: NAT _ info.cells[cell].vertices.nVertices; nTriangles: NAT _ info.cells[cell].polygons.nTriangles; IO.PutF[ infoStream, "\n\t\tIndices %g %g %g\n", IO.int[info.cells[cell].indexX], IO.int[info.cells[cell].indexY], IO.int[info.cells[cell].indexZ]]; IO.PutF[infoStream, "\t\tDegree %g\n", IO.int[dimension]]; IF dimension = 0 THEN IO.PutF[ infoStream, "\t\tPosition %g %g %g\n", IO.real[info.cells[cell].vertices[0].x], IO.real[info.cells[cell].vertices[0].y], IO.real[info.cells[cell].vertices[0].z]] ELSE BEGIN IO.PutF[infoStream, "\t\tVertices %g\n", IO.int[nVertices]]; FOR i: NAT IN [0..nVertices) DO IO.PutF[ infoStream, "\t\t\t%g %g %g\n", IO.real[info.cells[cell].vertices[i].x], IO.real[info.cells[cell].vertices[i].y], IO.real[info.cells[cell].vertices[i].z]]; ENDLOOP; END; IF dimension = 2 THEN BEGIN IO.PutF[infoStream, "\t\tTriangles %g\n", IO.int[nTriangles]]; FOR i: NAT IN [0..nTriangles) DO IO.PutF[ infoStream, "\t\t\t%g %g %g\n", IO.int[info.cells[cell].polygons[i].firstVertex], IO.int[info.cells[cell].polygons[i].secondVertex], IO.int[info.cells[cell].polygons[i].thirdVertex]]; ENDLOOP; END; ENDLOOP; IO.PutF[infoStream, "\n\tEND CELL DISPLAY INFORMATION\n"]; IO.PutF[infoStream, "\nEND CAD DESCRIPTION\n"]; IO.Close[infoStream]; END; SelectCell: PUBLIC PROC [scad: CADTypes.Scad, mask: REF CADTypes.VisibleMask, title: Rope.ROPE] RETURNS [index: INT] ~ BEGIN menuRopes: LIST OF Rope.ROPE _ NIL; mousePosition: REF Interminal.MousePosition; selection: INT; IF scad.cells.nCells # mask.length THEN ERROR Error[$WrongNumberOfCells]; FOR i: INT IN [0..scad.cells.nCells) DO j: NAT _ scad.cells.nCells - i - 1; cell: CADTypes.CellRec _ scad.cells[j]; cellRope: Rope.ROPE _ IO.PutFR["(%g, %g, %g)", IO.int[cell.indexX], IO.int[cell.indexY], IO.int[cell.indexZ]]; IF mask[j] THEN cellRope _ Rope.Concat[cellRope, " V"]; menuRopes _ CONS[cellRope, menuRopes]; ENDLOOP; mousePosition _ NEW[Interminal.MousePosition _ [mouseX: 0, color: FALSE, mouseY: 0]]; selection _ 0; IF (selection = 0) OR (selection = -1) THEN RETURN[-1] ELSE RETURN[selection - 1]; END; WhatCellIsItOn: PUBLIC PROC[point: Geometry3dVector.Triple, variables: CADTypes.VariableRec, scad: CADTypes.Scad] RETURNS [cell: NAT] ~ BEGIN FOR i: NAT IN [0..scad.cells.nCells) DO IF SatisfiesQFF[point, variables, scad.cells[i].definingFormula] THEN RETURN[i]; ENDLOOP; ERROR Error[$NotOnAnyCell]; END; SatisfiesQFF: PROC[point: Geometry3dVector.Triple, variables: CADTypes.VariableRec, qff: CADTypes.QuantifierFreeFormula] RETURNS [satisfiesQFF: BOOLEAN] ~ BEGIN whoops: ERROR = CODE; epsilon: REAL ~ 0.0001; IF qff.isCompound THEN SELECT qff.compoundOperator FROM and => BEGIN FOR i: NAT IN [0..qff.compoundArguments.length) DO IF ~SatisfiesQFF[point, variables, qff.compoundArguments[i]] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; END; or => BEGIN FOR i: NAT IN [0..qff.compoundArguments.length) DO IF SatisfiesQFF[point, variables, qff.compoundArguments[i]] THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; ENDCASE => ERROR whoops ELSE BEGIN bindings: MultiPolynomial.EvaluationBindings _ LIST [ [variable: variables.x, value: point.x], [variable: variables.y, value: point.y], [variable: variables.z, value: point.z] ]; evaluatedPol: REAL _ MultiPolynomial.TotallyEvaluate[qff.simpleArgument, bindings]; SELECT qff.simpleOperator FROM isPositive => RETURN[evaluatedPol > 0]; isZero => RETURN[ABS[evaluatedPol] < epsilon]; isNegative => RETURN[evaluatedPol < 0]; ENDCASE => ERROR whoops; END; END; END. `CADIOImpl.mesa James Rauen, August 21, 1986 6:18:48 pm PDT Last edited by: James Rauen January 13, 1988 7:59:58 pm PST POP-UP-MENU must be replaced! Declarations Here is a procedure that translates quantifier-free-formulas between representations. Translate an atomic formula. Or translate a compound formula. Read the CAD and covering set files. Get the surface equation. Get the old cells and instantiate the new ones. Iterate over the old cells. Only do the cell if it is part of the surface. IF QEIO.CellDimension[oldCells[oldCellIndex].index ] < 3 THEN BEGIN 9/11/86 Do the cell if it has dimension less than 3; clearly wrong; the intent here was just to pick up nasty vertical lines. Translate its indices and dimension. pointData: Points.PointData _ NARROW[oldCells[oldCellIndex].index.data]; Interim calculation of dimension; replace when ReadCad computes it. newCells[newCellIndex].dimension _ (NARROW[oldCells[oldCellIndex].index.data, Points.PointData][1] MOD 2) + (NARROW[oldCells[oldCellIndex].index.data, Points.PointData][2] MOD 2) + (NARROW[oldCells[oldCellIndex].index.data, Points.PointData][3] MOD 2); Translate its defining formula. Translate the vertex and polygon sequences. Count the number of points. numberOfPoints _ 1; newCells[newCellIndex].vertices[0] _ [6, 1, 70]; Translate the points. Generate a triangulation of the points. Translate the triangles. Note! These "triangulations" number the vertices from 1, 2, ..., while the vertices are indexed from 0, 1, .... For example, triangle [firstVertex: 2, secondVertex: 3, thirdVertex: 4] refers to vertices[1], vertices[2], and vertices[3]. The discrepancy is remedied when the 2-cells are written to a temporary file by ThreeDHacks. Increment the index into the new cells. Do the next cell. Compress the new cells. Construct and return the Scad. No guarantees for incorrectly formatted files. Will raise syntax errors. It won't make some checks, such as if vertices listed in the Triangles section actually exist. Declarations Define a break procedure that gets a token. Define a break procedure that gets a polynomial. Define a procedure to get the next token or polynomial. Recursive procedure to get a defining formula. Get the BEGIN token Get the CAD DESCRIPTION tokens. Get the surface polynomial. Get the name of the surface. Get the color of the surface. Get the number of cells and create the cell sequence in the Scad. Get the BEGIN CELL DEFINITIONS tokens. Iterate over the cells. Declarations Get the indices. Get the dimension. Get the defining formula. Do the next cell. Get the END CELL DEFINITIONS tokens. Get the BEGIN CELL DISPLAY INFORMATION tokens. Iterate over the cells. Declarations Get the indices for comparison. Get the dimension for comparison. Get the vertex sequence. For zero-cells, there is only one vertex, the Position; for one- and two-cells, the number of vertices is specified in the file. Get the triangle sequence. For two-cells, the number of vertices is specified in the file; for zero- and one-cells, there are none. Do the next cell. Get the END CELL DISPLAY INFORMATION tokens. Get the END CAD DESCRIPTION tokens. Declarations Procedure to write a defining formula. Get the operator Indent unless the nesting level is 2. Write the defining formula. Write the header. Iterate over the cells, writing the indices, dimension, and defining formula. Write the end of the cell definitions block and the start of the display information block. Iterate over the cells, writing the display information. Extract some useful quantities. Write the indices and dimension. Write the vertex sequence. Write the triangle sequence if the cell has dimension 2. Do the next cell. Write the "END"s and close the file. Declarations. Ensure that the scad and mask have the same number of elements. Build the list of ropes, backwards (of course), for the menu. Get a selection from the pop-up menu. selection _ PopUpMenu.RequestSelection[ label: title, choice: menuRopes, timeOut: 0, mouse: mousePosition]; Return the selection (minus 1 so the counts start at zero), or return -1 on timeout/abort. Returns a boolean value indicating if point satisfies the qff. ΚŸ˜™J™+Icode™;KšΟb™J™—šΟk ˜ Kšžœ˜Kšœ žœ³˜ΑKšœ˜Kšœ˜Kšœ ˜ Kšžœžœ˜Kšœ žœ˜!Kš žœžœžœžœžœžœ˜eKšœžœA˜VK˜K˜Kšœ ˜ K˜K˜ K˜ Kšž œ˜ Kšœ˜Kšœ˜Kšœ˜Kšœžœžœ˜#Kšœžœ ˜ K˜—K˜šΠln œžœž˜Kšžœ žœžœ@˜WKšžœž˜ Kšœž˜K˜Kš Οnœžœžœžœžœ˜&K˜š  œžœžœžœžœž˜_K˜™ Kšœžœžœ˜Kšœ˜Kšœ˜Kšœ%˜%Kšœ$˜$K˜Kšœ˜Kšœ"˜"KšœA˜AKšœžœ˜K˜Kšœžœ˜Kšœ žœ˜$Kšœžœ˜Kšœžœ˜.K˜K˜—™Uš  œžœžœ)ž˜`K˜Kšœ žœ ˜1Kšœžœ<˜`K˜™šžœžœž˜"Kšœ%˜%šžœž˜Kšœ˜Kšœ ˜ Kšœ˜Kšœžœ˜2Kšžœžœ˜%—šžœ˜ Kšœ žœ˜K˜Kšœžœ˜Kšœ˜KšœS˜SK˜—Kšž˜K˜——™ šžœž˜ Kšœ'˜'Kšœ žœ(˜8Kšœ žœžœ˜&Kšœ žœ˜šžœž˜Kšœ˜Kšœ˜Kšœžœ˜+Kšžœžœ˜%—K˜Kšœ ˜ šžœžœž˜K˜Kšœ˜Kšžœ˜—Kšœžœ4˜EKšœ˜šžœžœžœž˜Kšœ1˜1Kšœ˜Kšžœ˜—šžœ˜ Kšœ žœ˜Kšœ˜Kšœ˜Kšœ˜Kšœž˜K˜—Kšžœ˜K˜—šžœ˜K˜————™$Kšœ žœ˜#Kšœ9˜9Kšœ žœ˜!Kšœ ˜ K™—™Kšœ žœ ˜Kšœžœ"˜6Kšœ˜Kšœ:˜:K˜—™/Kšœ˜Kšœžœ˜%Kšœ0˜0Kšœ žœ*˜8Kšœ˜K˜—™šžœžœžœž˜1K˜™.Kšœ žœ"˜3Kšœ žœ˜(Kš žœžœ#žœžœž˜@K™šžœžœ2žœž™CK™~—K™K˜™$Kšœžœ$™HKšœ žœ#˜IKšœ žœ#˜IKšœ žœ#˜IKšœ6˜6K˜—™Cšœ"™"KšœH™HKšœI™IKšœG™G—K™—™KšœP˜PK˜—™+šžœ"ž˜,K˜šœž˜ Kšœžœ˜Kšœ0žœ˜RKšœ"žœ"˜JKšœ%žœ˜=Kšœžœ˜:Kšœ"žœ˜BKšœ3˜3Kšœ3˜3Kšœ3˜3šœ&˜&Kšœ ˜ Kšœ ˜ Kšœ˜K˜—Kšœ"žœ˜DKšžœ˜K˜—šœž˜ Kšœ0žœ˜RKšœ"žœ"˜JKšœ%žœ˜=Kšœžœ˜1Kšœ"žœ*˜Ošžœžœžœž˜$Kšœžœ˜Kšœžœ˜>Kšœ3˜3Kšœ3˜3Kšœ3˜3šœ&˜&Kšœ ˜ Kšœ ˜ Kšœ˜K˜—Kšžœ˜—Kšœ"žœ˜DKšžœ˜K˜—šœž˜ Kšœžœ˜ K˜%Kšœ0žœ˜RKšœ"žœ"˜JK˜™Kšœ˜Kšœ™šžœžœžœž˜)Kšœ%žœ˜=Kšœ=˜=Kšžœ˜—Kšœ"žœ*˜OKšœ0™0K˜—™K˜šžœžœžœž˜)Kšœ%žœ˜=šžœžœžœž˜,Kšœžœ˜Kšœžœ˜:Kšœ3˜3Kšœ3˜3Kšœ3˜3šœ/˜/Kšœ ˜ Kšœ ˜ Kšœ˜K˜—K˜Kšžœ˜—Kšžœ˜K˜——™'JšœB˜BJ˜—™šžœžœž˜Jšœ"žœ˜C—šžœ˜Kšœ"žœA˜fšžœžœžœ%ž˜4šœ*˜*Kšœ*˜*Kšœ,˜,Kšœ)˜)K˜—Kšžœ˜—K˜K˜——K™ΜKšžœ˜K˜—šžœž˜Kšžœ˜Kšžœ˜K˜———™'Kšœ ˜ šžœ˜K˜———™Kšžœ˜K˜———™Kšœžœ&˜>šžœžœžœž˜"Kšœ$˜$Kšžœ˜—K˜—™˜Kšœ2˜2Kšœžœ˜ K˜K˜Kšœ˜—K˜—Kšžœ˜—K˜š   œžœžœžœžœž˜UK˜K™©K˜™ Kšœ žœžœžœ˜0Kšœ žœ˜Kš  œžœžœ˜Kš  œžœžœ˜Kš œžœžœ˜Kš  œžœ žœ˜$Kšœžœ˜K˜—™+š œžœ ž˜$šžœžœž˜Kš žœžœžœžœžœ˜!Kšžœ ˜K˜—šžœ˜K˜———™0š œžœ ž˜)šžœžœž˜Kšœžœžœ ˜Kšžœ ˜K˜—Kšžœ˜—K˜—™7š   œžœžœžœžœž˜QKšœ žœ˜Kšœžœ ˜3Kšžœ ˜Kšžœ˜K˜——™.š œžœžœ$ž˜IKšœžœ˜Kšœ(˜(Kšœ,˜,Kšœ žœ˜Kšœ˜šžœ2ž˜8Kšœ+žœ˜1—šžœžœ.ž˜9Kšœ'žœ˜-—šžœžœ2ž˜=Kšœ+žœ˜1—šžœžœ+ž˜6Kšœ&žœ˜+—šžœžœ*ž˜5Kšœ%žœ˜*—Kšžœžœ˜šžœ žœž˜Kšœžœ"˜5šžœ˜ Kšœ žœ˜K˜Kšœžœ˜Kšœ˜K˜5K˜—Kšž˜—šžœž˜ Kšœžœ$˜:šœ'˜'Kšœ žœ˜K˜#Kšœžœ<˜RK˜Kšœžœ˜—šžœ žœžœž˜.Kšœ7˜7Kšžœ˜—Kšžœ˜ Kšžœ˜—Kšžœ˜K˜K˜——™šžœ&ž˜-Kšœ˜Kšžœ˜K˜——™Kšžœ*žœžœ˜EKšžœ2žœžœ˜MK˜—™Kšžœ.žœžœ˜IJšœ'˜'Jšœ2˜2J˜—™Kšžœ+žœžœ˜FJšœ˜šžœ(žœž˜4Jšœ žœ˜J˜Jšž˜—šžœž˜ Jšœ žœ˜Jšœ˜Jšžœ˜—J™—™Kšžœ,žœžœ˜GK˜1K˜1K˜1J™—™AKšžœ,žœžœ˜GKšœ1˜1Kšœ žœ'˜7K˜—šœ&™&Kšžœ,žœžœ˜GKšžœ+žœžœ˜FKšžœ2žœžœ˜MK™—™šžœžœžœž˜&K˜—™ Kšœ žœ˜—K˜™Kšžœ2žœžœ˜MKšœ;˜;Kšœ;˜;Kšœ;˜;K™—™Kšžœ1žœžœ˜LKšœ  œ˜.Kšžœžœžœ˜*K˜'K˜—™Kšžœ6žœžœ˜QKšœ8˜8K˜—™Kšžœ˜K˜——™$Kšžœ*žœžœ˜EKšžœ+žœžœ˜FKšžœ2žœžœ˜MK˜—šœ.™.Kšžœ,žœžœ˜GKšžœ+žœžœ˜FKšžœ.žœžœ˜IKšžœ2žœžœ˜MK˜—™šžœžœžœž˜&K˜—™ Kšœ žœ˜K˜—K˜™Kšžœ.žœžœ˜IKšžœ<žœžœ˜WKšžœ<žœžœ˜WKšžœ<žœžœ˜WK™—™!Kšžœ-žœžœ˜HKšœ  œ˜.Kšžœ(žœžœ˜CK˜—™ššžœžœž˜Kšžœ/žœžœ˜JKšœžœ˜Kšžœ˜K˜——™Kšžœ˜K˜——šœ,™,Kšžœ*žœžœ˜EKšžœ+žœžœ˜FKšžœ.žœžœ˜IKšžœ2žœžœ˜MK˜—™#Kšžœ*žœžœ˜EKšžœ*žœžœ˜EKšžœ2žœžœ˜MK˜—Kšžœ˜K˜—š   œžœžœžœž˜MK˜™ Kšœ žœžœžœ˜9Kš  œžœžœ˜K˜—™&š œžœ.žœž˜X™šœžœ˜šžœžœžœž˜5K˜K˜ Kšžœžœ˜—šžœžœž˜"Kšœ˜Kšœ˜Kšœ˜Kšžœžœ˜K˜———™%š žœ žœžœžœžœž˜1Kšžœ˜Kšžœ˜K˜——™šžœžœž˜šžœ˜K˜ K˜ Kšžœ˜Kšžœ#˜%—šžœ žœžœ"ž˜7KšœA˜AKšžœ˜—Kšž˜—šžœž˜ šžœ˜K˜ K˜ Kšžœ˜Kšžœ7˜9—šžœ˜K˜———Kšžœ˜—K˜—™Kšžœ/˜1šžœ˜Kšœ ˜ Kšœ˜Kšžœ2˜4—šžœ žœžœ!žœ˜IKšžœžœ&˜-—šžœ˜K˜ K˜Kšžœ˜Kšžœ˜Kšžœ˜—Kšžœ"žœ˜?K˜4K˜—™Mšžœžœžœž˜*šžœ˜˜ K˜Kšžœ˜ Kšžœ˜ Kšžœ˜!——Kšžœ)žœ"˜OKšžœ*˜,K˜:Kšžœ˜—K™—™[Kšžœ0˜2Kšžœ:˜šžœžœžœž˜ šžœ˜Kšœ ˜ Kšœ˜Kšžœ/˜1Kšžœ0˜2Kšžœ0˜2—Kšžœ˜—Kšžœ˜K˜——™Kšžœ˜———K™™$Kšžœ8˜:Kšžœ-˜/Kšžœ˜K˜—Kšžœ˜K˜—š  œžœžœžœ#žœžœ žœž˜|K˜™ Kš œ žœžœžœžœ˜#KšœžœΟtœ˜,Kšœ žœ˜K˜—™?Kšžœ!žœžœ˜IK˜—™=šžœžœžœž˜'Kšœ#˜#Kšœ'˜'Kš œžœžœžœžœžœ˜nKšžœ žœ(˜7Kšœ žœ˜&Kšžœ˜K˜——™%Kšœžœ‘œžœ˜Ušœ'™'Kšœ ™ Kšœ™K™ Kšœ™—˜K™——™ZKšžœžœžœžœ˜6Kšžœžœ˜Kšžœ˜K˜——š  œžœžœWžœžœž˜šžœžœžœž˜'Kšžœ?žœžœ˜PKšžœ˜—Kšžœ˜Kšžœ˜K™—š   œžœgžœžœž˜ K˜K™>K™Kšœžœžœ˜Kšœ žœ ˜K™šžœž˜šžœž˜ šœž˜ šžœžœžœ#ž˜2Kšžœ;žœžœžœ˜PKšžœ˜—Kšžœžœ˜ Kšžœ˜—šœž˜ šžœžœžœ#ž˜2Kšžœ:žœžœžœ˜NKšžœ˜—Kšžœžœ˜Kšžœ˜—Kšžœžœ˜K˜——šžœž˜ šœ/žœ˜5Kšœ(˜(Kšœ(˜(Kšœ'˜'K˜—KšœžœA˜Sšžœž˜Kšœžœ˜'Kšœ žœžœ˜.Kšœžœ˜'Kšžœžœ˜—Kšžœ˜—šžœ˜K˜—K˜K˜—˜K˜——Kšžœ˜—…—OΔyΓ