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; 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 Make(no: Oct.EdgeNo := 0): Arc; PROCEDURE Org(a: Arc): Node; PROCEDURE NOrg(a: Arc): CARDINAL; PROCEDURE Degree(a: Arc): CARDINAL; (* Get how many edges out of one vertex *) 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". *) PROCEDURE NPatch(f: Face): CARDINAL; (* Number of logical patch that contains triangle "f" *) PROCEDURE SetNPatch(f: Face; patch: CARDINAL); PROCEDURE NodeExists(n: Node): BOOLEAN; PROCEDURE SetNodeExists(n: Node; b: BOOLEAN); PROCEDURE SetNodeColor(f: Node; color: Color.T); PROCEDURE SetVertexRadius(v: Vertex; radius: REAL); PROCEDURE VertexFixed(v: Vertex): BOOLEAN; PROCEDURE SetVertexFixed(v: Vertex; b: BOOLEAN); PROCEDURE SetFaceTransp(f: Face; color: Color.T); PROCEDURE EdgeExists(e: Edge): BOOLEAN; PROCEDURE SetEdgeExists(a: Arc; b: BOOLEAN); PROCEDURE EdgeSpring(e: Edge): BOOLEAN; PROCEDURE SetEdgeSpring(e: Arc; b: BOOLEAN); PROCEDURE SetEdgeColor(e: Arc; color: Color.T); PROCEDURE SetEdgeRadius(e: Arc; radius: REAL); PROCEDURE SetVertexCoords(v: Vertex; coords: R3.T); PROCEDURE SetCoords(READONLY t: Topology; READONLY coords: Coords); PROCEDURE GetVertexCoords(v: Vertex): R3.T; PROCEDURE GetCoords(READONLY t: Topology; VAR coords: Coords); 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 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. *) 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 PrintTopTri(READONLY t: Topology; shape: TEXT); PROCEDURE ReadTopTri(shape: TEXT): Topology; TYPE Coords = ARRAY OF R3.T; PROCEDURE R3Print(wr: Wr.T; w: R3.T); 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 InitVariable(READONLY t: Topology; VAR variable: ARRAY OF BOOLEAN); PROCEDURE InitCoords(VAR coords: Coords; coins: Random.T); 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 ComputeAllVertexNormals( READONLY t: Topology; READONLY coords: Coords; ): REF ARRAY OF R3.T; 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. *) END Triang.