INTERFACE Triang; IMPORT Oct, Color, Wr, Random; IMPORT R3; TYPE Arc = Oct.Arc; Edge <: PublicEdge; PublicEdge = Oct.Edge OBJECT METHODS init(no: Oct.EdgeNo := 0): Edge; (* Initializes "self" with the given edge number. *) END; Node <: PublicNode; PublicNode = OBJECT END; Vertex <: PublicVertex; PublicVertex = Node OBJECT END; Face <: PublicFace; PublicFace = Node OBJECT END; (* === ELEMENT CREATION === *) PROCEDURE Make(no: Oct.EdgeNo := 0): Arc; (* Creates a new unattached edge with distinct endpoints. *) PROCEDURE MakeVertex(): Vertex; PROCEDURE MakeFace(): Face; (* === ARC PROPERTIES === *) PROCEDURE Org(a: Arc): Node; PROCEDURE NOrg(a: Arc): CARDINAL; (* Same as NodeNo(Org(a)) *) PROCEDURE SetOrg(a: Arc; n: Node); PROCEDURE SetAllOrgs(a: Arc; n: Node); (* Does SetOrg(t,n) for all arcs "t" with same origin as "a". *) PROCEDURE Left(a: Arc): Node; PROCEDURE NLeft(a: Arc): CARDINAL; PROCEDURE SetLeft(a: Arc; n: Node); PROCEDURE SetAllLefts(a: Arc; n: Node); (* Does SetLeft(t,n) for all arcs "t" with same left face as "a". *) (* === EDGE PROPERTIES: === *) PROCEDURE EdgeExists(e: Edge): BOOLEAN; PROCEDURE SetEdgeExists(e: Edge; exists: BOOLEAN); PROCEDURE EdgeSpring(e: Edge): BOOLEAN; PROCEDURE SetEdgeSpring(e: Edge; spring: BOOLEAN); PROCEDURE EdgeColor(e: Edge): Color.T; PROCEDURE SetEdgeColor(e: Edge; color: Color.T); PROCEDURE EdgeRadius(e: Edge): REAL; PROCEDURE SetEdgeRadius(e: Edge; radius: REAL); (* === NODE PROPERTIES === *) PROCEDURE NodeExists(n: Node): BOOLEAN; PROCEDURE SetNodeExists(n: Node; b: BOOLEAN); PROCEDURE NodeColor(n: Node): Color.T; PROCEDURE SetNodeColor(n: Node; color: Color.T); PROCEDURE NNode(n: Node): CARDINAL; PROCEDURE SetNNode(n: Node; num: CARDINAL); (* === VERTEX PROPERTIES === *) PROCEDURE VertexFixed(v: Vertex): BOOLEAN; PROCEDURE SetVertexFixed(v: Vertex; fixed: BOOLEAN); PROCEDURE VertexRadius(v: Vertex): REAL; PROCEDURE SetVertexRadius(v: Vertex; radius: REAL); PROCEDURE VertexCoords(v: Vertex): R3.T; PROCEDURE SetVertexCoords(v: Vertex; coords: R3.T); (* === FACE PROPERTIES === *) PROCEDURE NPatch(f: Face): CARDINAL; (* Number of logical patch that contains triangle "f" *) PROCEDURE SetNPatch(f: Face; patch: CARDINAL); PROCEDURE FaceTransp(f: Face): Color.T; PROCEDURE SetFaceTransp(f: Face; color: Color.T); (* === CONSTRUCTION TOOLS === *) PROCEDURE Connect(a, b: Arc): Arc; (* Adds a new edge from Org(a) to Dest(b). The new edge will be spliced in as Onext(a) and Dnext(b). Returns the new edge. *) PROCEDURE AddSpokes(a: Arc): Arc; (* Adds a new vertex in the middle of Left(a), connected by new edges ("spokes") to all vertices of Left(a). Returns the spoke Onext(a). *) PROCEDURE MakeGrid(order: CARDINAL): ARRAY [0..7] OF Arc; (* Builds a grid of "order" by "order" square cells, each divided into 4 triangles. *) PROCEDURE SetQuarterGridProperties( c: Arc; order: CARDINAL; vertexColor: Color.T; vertexRadius: REAL; edgeColor: Color.T; edgeRadius: REAL; facePatch: CARDINAL; faceColor: Color.T; faceTransp: Color.T; ); (* Sets the style and the logical patch numbers in all vertices, edges, and triangles of one quarter of the unglued grid adjacent to the corner arc is "c". The "vertex" properties apply only to the grid corner Org(c). The "edge" properties apply only to the grid edges representing the half-edge "e" of the map (starting with Oprev(c)); and also to the grid vertices between those edges. The "face" properties apply only to the triangles contained between the the grid's side corresponding to "c", and half-edges "e" and "Tor(e)". The properties of all other vertices, edges,and faces of the grid are left unchanged. *) PROCEDURE Glue(a, b: Arc; n: CARDINAL): Arc; (* Identifies "n" edges from Left(a), starting with "a" and turning counterclockwise, with "n" edges from Right(b), starting with "b" and turning clockwise. The edges in the "b" chain are removed; the edges in the "a" chain are left in the structure. Returns the last edge of the "a" chain. *) (* === GLOBAL PROCEDURES === *) TYPE Topology = RECORD NV: INTEGER; (* Number of vertices *) NF: CARDINAL; (* Number of faces *) NE: CARDINAL; (* Number of edges *) adj: REF ARRAY OF ARRAY OF BOOLEAN; vertex: REF ARRAY OF Vertex; (* One description of each vertex *) face : REF ARRAY OF Face; (* One description of each face *) edge: REF ARRAY OF Arc; (* One arc for each edge *) out: REF ARRAY OF Arc; (* One arc for each vertex where: Org(out[v]) = vertex[v] *) side: REF ARRAY OF Arc; (* One arc for each face where: Org(side[v]) = face[v] *) END; PROCEDURE NumberVertices(a: Arc): CARDINAL; (* Assigns numbers to vertices, sets the Org fields, and returns a vector with one arc out of each vertex. Must be called before any calls to Org. *) PROCEDURE MakeTopology(a: Arc): Topology; (* Builds the adjacency matrix and vertex/edge tables for the given Triang structure. Assumes NumberVertices has been called. *) PROCEDURE InitVariable(READONLY t: Topology; VAR variable: ARRAY OF BOOLEAN); (* Sets "variable[v] := TRUE" for every vertex "v" that exists and is not fixed. *) (* === GEOMETRIC TOOLS === *) TYPE Coords = ARRAY OF R3.T; PROCEDURE InitCoords( coins: Random.T; VAR coords: Coords; radius: REAL := 1.0 ); (* Fills coords with random coordinates in the range [-radius __ +radius]. *) PROCEDURE NormalizeCoords(READONLY t: Topology; VAR coords: Coords); (* Shifts and scales all vertices so that the ones that exist have barycenter (0,0,0) and mean square radius 1.0 *) PROCEDURE FaceNormal(a: Arc; READONLY coords: Coords): R3.T; (* Normal of face Left(a). *) PROCEDURE VertexNormal(a: Arc; READONLY coords: Coords): R3.T; (* Estimated normal at Org(a), considering only neighbors that exist. *) PROCEDURE ComputeAllVertexNormals( READONLY t: Topology; READONLY coords: Coords; ): REF ARRAY OF R3.T; (* Returns a vector with the result of VertexNormal applied to each vertex of "t". *) (* === INPUT/OUTPUT === *) PROCEDURE PrintTopTri(t: Topology; name: TEXT); (* Writes "t" to disk in a format that can be read back. The file will have the given "name" with ".top" appended. *) PROCEDURE ReadTopTri(name: TEXT): Topology; (* Reads a disk file created by PrintTopTri. The file must have the given "name" with ".top" appended. *) PROCEDURE PutRay( wr: Wr.T; READONLY t: Topology; READONLY coords: Coords; ); (* Prints "t" in POVRAY format. *) PROCEDURE PutWire( wr: Wr.T; READONLY t: Topology; READONLY coords: Coords; all: BOOLEAN; (* TRUE to print also the invisible triangles. *) ); (* Prints "t" in X3D format. *) PROCEDURE R3Print(wr: Wr.T; w: R3.T); (* Prints an R3.T to "wr". *) END Triang.