G3dWingedEdge.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved
Glassner, March 10, 1990 6:37:23 pm PST
Jules Bloomenthal July 15, 1992 5:13 pm PDT
DIRECTORY G3dBasic, G3dShape, Rope;
Imported Types
Quad: TYPE ~ G3dBasic.Quad;
Face: TYPE ~ G3dShape.Face;
Shape: TYPE ~ G3dShape.Shape;
Validity: TYPE ~ G3dShape.Validity;
Vertex: TYPE ~ G3dShape.Vertex;
SurfaceSequence: TYPE ~ G3dShape.SurfaceSequence;
ROPE: TYPE ~ Rope.ROPE;
Local Types
A Note on These Data Structures
There is a note on the architecture of the interface at the end of this file. The general structure is that faces, edges, and vertices are stored in rings (a doubly-linked list). A WShape contains three rings, one each for faces, edges, and vertices. Each edge points to a data structure called WEdgeData, which contains the information for that edge. Each face contains an edge ring describing the edges around that face. Each vertex contains an edge ring of all edges around that vertex. All duplicate instantiations of an edge point to a single WEdgeData structure (this contains a pointer back to its "owner" in the master edge ring in the WShape). Here is a pictorial description of a WShape:
[Artwork node; type 'Artwork on' to command tool]
The fundamental building block in the system is the edge, represented by WEdgeData. An edge is a directed connection between two vertices (from aVertex to bVertex). Each edge separates two faces (viewing the edge as below, aFace is below and bFace is above). An edge has four "wings"; these are the first edges around the vertex encountered in the specified direction. Again referring to the figure below, on aFace we travel clockwise from the edge to reach aCWedge, and counterclockwise to reach aCCWedge; similarly for bFace and its wings, bCWedge and bCCWedge.
[Artwork node; type 'Artwork on' to command tool]
Much of the architecture of this interface has been designed to insulate the user from dealing directly with these data structures when executing topological and geometrical operations. Changes to the topology are rather hard to implement; because of the redundancy in the data structures, many pointers must be carefully moved, and in the right order. The most important high-level topological operations are given below under "Euler Operators"; the implementation provides details for these routines.
Sometimes you may need to adjust the data structures yourself; I recommend careful study of the data types and the implementations mentioned above, followed by extensive testing; sometimes the correct pointer-stitching order is not obvious, and subtle problems can arise. If you stick to the high-level routines in this interface you should be okay.
WShape: TYPE ~ REF WShapeRep;
WShapeRep:
TYPE ~
RECORD [
vertexRing: WVertex ¬ NIL,
edgeRing: WEdge ¬ NIL,
faceRing: WFace ¬ NIL,
next, previous: WShape ¬ NIL,
vertexValidities: ARRAY Validity OF BOOL ¬ ALL[FALSE], -- to convert back
faceValidities: ARRAY Validity OF BOOL ¬ ALL[FALSE], -- to a shape
index: INT ¬ 0,
clientData: REF ANY ¬ NIL
];
WFace: TYPE ~ REF WFaceRep;
WFaceRep:
TYPE ~
RECORD [
basicFace: Face ¬ NIL,
edgeRing: WEdge ¬ NIL,
next, previous: WFace ¬ NIL,
index: INT ¬ 0,
clientData: REF ANY ¬ NIL
];
WEdgeData: TYPE ~ REF WEdgeDataRep;
WEdgeDataRep:
TYPE ~
RECORD [
aCWedge, bCWedge: WEdge ¬ NIL,
aCCWedge, bCCWedge: WEdge ¬ NIL,
aVertex, bVertex: WVertex ¬ NIL,
aFace, bFace: WFace ¬ NIL,
index: INT ¬ 0,
owner: WEdge ¬ NIL,
clientData: REF ANY ¬ NIL
];
WEdge: TYPE ~ REF WEdgeRep;
WEdgeRep:
TYPE ~
RECORD [
edgeData: WEdgeData ¬ NIL,
next, previous: WEdge ¬ NIL,
clientData: REF ANY ¬ NIL
];
WVertex: TYPE ~ REF WVertexRep;
WVertexRep:
TYPE ~
RECORD [
basicVertex: Vertex ¬ NIL,
edgeRing: WEdge ¬ NIL,
next, previous: WVertex ¬ NIL,
index: INT ¬ 0,
clientData: REF ANY ¬ NIL
];
ClockDirection: TYPE ~ { cw, ccw };
Vertex Access Procedures
NextVertexAroundFaceFromEdge:
PROC [edge: WEdge, face: WFace, dir: ClockDirection]
RETURNS [WVertex];
Walks around the face in the specified direction from the edge to return the next vertex
NextVertexAroundFaceFromVertex:
PROC [vertex: WVertex, face: WFace, dir: ClockDirection]
RETURNS [WVertex];
Walks around the face in the specified direction from the vertex to return the next vertex
NextVertexAroundVertex:
PROC [vertex: WVertex, face: WFace, dir: ClockDirection]
RETURNS [WVertex];
Same as NextVertexAroundFaceFromVertex
VertexAcrossEdge:
PROC [vertex: WVertex, edge: WEdge]
RETURNS [WVertex];
Returns the vertex across the given edge from the given vertex
Edge Access Procedures
NextEdgeAroundFaceFromEdge:
PROC
[edge: WEdge, face: WFace, dir: ClockDirection] RETURNS [WEdge];
Walks around the face in the given direction from the given edge
NextEdgeAroundVertex:
PROC
[vertex: WVertex, edge: WEdge, dir: ClockDirection] RETURNS [WEdge];
Returns the next edge around the given vertex. The order of edges is unspecified and may change as edges are added and removed.
NextEdgeAroundFaceFromVertex:
PROC
[vertex: WVertex, face: WFace, dir: ClockDirection] RETURNS [WEdge];
Walks around the face in the given direction from the given vertex
Construction Utility Procedures
InsertVertexIntoRing:
PROC [v: WVertex, vRing: WVertex]
RETURNS [WVertex];
Inserts the given vertex into the ring and returns the new, updated ring
InsertCopyOfVertexIntoRing:
PROC [v: WVertex, vRing: WVertex]
RETURNS [WVertex];
Inserts a copy of the given vertex into the ring and returns the new, updated ring
InsertEdgeIntoRing:
PROC [e: WEdge, eRing: WEdge]
RETURNS [WEdge];
Inserts the given edge into the ring and returns the new, updated ring
InsertCopyOfEdgeIntoRing:
PROC [e: WEdge, eRing: WEdge]
RETURNS [WEdge];
Inserts a copy of the given edge into the ring and returns the new, updated ring
InsertFaceIntoRing:
PROC [f: WFace, fRing: WFace]
RETURNS [WFace];
Inserts the given face into the ring and returns the new, updated ring
InsertCopyOfFaceIntoRing:
PROC [f: WFace, fRing: WFace]
RETURNS [WFace];
Inserts the given face into the ring and returns the new, updated ring
ReverseEdgeRing:
PROC [eRing: WEdge];
Reverses the order of edges in the ring
SetWings:
PROC [e1, e2: WEdge];
Sets the relevant pair of wings between the two edges (1 wing each is affected)
Toplogical Predicates
EdgeAdjacentToFace:
PROC [edge: WEdge, face: WFace]
RETURNS [
BOOL];
Returns TRUE if the edge is adjacent to the face
VertexAdjacentToFace:
PROC [vertex: WVertex, face: WFace]
RETURNS [
BOOL];
Returns TRUE if the vertex is adjacent to the face
VertexAdjacentToEdge:
PROC [vertex: WVertex, edge: WEdge]
RETURNS [
BOOL];
Returns TRUE if the vertex is adjacent to the edge
SpurVertex:
PROC [vertex: WVertex]
RETURNS [
BOOL];
Returns TRUE if the vertex is a spur
WireEdge:
PROC [edge: WEdge]
RETURNS [
BOOL];
Returns TRUE if the vertex is a wire
Valencies
EdgesAroundVertex:
PROC [vertex: WVertex]
RETURNS [numEdges:
INT ¬ 0];
Returns the number of edges around the given vertex
FacesAroundVertex:
PROC [vertex: WVertex]
RETURNS [
INT];
Returns the number of faces around the given vertex
VerticesAroundEdge:
PROC [edge: WEdge]
RETURNS [
INT];
Returns the number of vertices around the given edge
FacesAroundEdge:
PROC [edge: WEdge]
RETURNS [
INT];
Returns the number of faces around the given edge
VerticesAroundFace:
PROC [face: WFace]
RETURNS [
INT];
Returns the number of vertices around the given face
EdgesAroundFace:
PROC [face: WFace]
RETURNS [numEdges:
INT ¬ 0];
Returns the number of edges around the given face
VerticesInWShape:
PROC [wShape: WShape]
RETURNS [
INT];
Returns the number of vertices in the entire shape
EdgesInWShape:
PROC [wShape: WShape]
RETURNS [
INT];
Returns the number of edges in the entire shape
FacesInWShape:
PROC [wShape: WShape]
RETURNS [
INT];
Returns the number of faces in the entire shape
Genus:
PROC [wShape: WShape]
RETURNS [
INT];
Return the topological genus of the surface (usually 2)
Euler Operators
SplitEdge:
PROC [wShape: WShape, edge: WEdge]
RETURNS [newV: WVertex];
Insert a new vertex in the edge and the vertex
CollapseEdge:
PROC [wShape: WShape, edge: WEdge]
RETURNS [WVertex];
Shrink the edge down to one vertex
RemoveEdge:
PROC [wShape: WShape, edge: WEdge]
RETURNS [WFace];
Remove the edge and return the face subsuming the two old faces
InsertBridge:
PROC [wShape: WShape, v1, v2: WVertex]
RETURNS [newFace: WFace ¬ NIL, newEdge: WEdge ¬ NIL];
Insert a new edge between the two vertices. Usually these were created with SplitEdge. This operation creates a new face and a new edge, both of which are returned.
RemoveVertex:
PROC [wShape: WShape, v1: WVertex]
RETURNS [newEdge: WEdge ¬
NIL];
Insert a new edge between the two vertices