MODULE SMCFeat; (* Reveals the features, that is the physical characteristic (serial number, geometry, style) of the elements -- vertex, edge, border and face -- corresponding to a corner. The serial number of each element is a numerical value speficied (in the input) by the client and if the map is modified these values are recomputed (on output) by the programs. The vertex's geometry is the coordinates of the point corresponding to the vertex where the point is represented by the Plucker coefficients of its stabbing line. The edge's geometry is the coefficients of the plane whose intersection with the sphere "S2" defines the edge. We do NOT define the geometry of borders and faces since the geometry of these elements is implicitly defined by the geometry of its elements (vertices and faces), and also, by the geometry of the spherical surface. The feature "style" defines the visual characteristics of the elements. Created in Sep. 30, 1997 by Marcus Vinicius A. Andrade Last edited in Sep. 30, 1997 by Marcus Vinicius A. Andrade *) FROM SMGeo IMPORT Point, Circle, Arc, Sign; IMPORT SMGeo; REVEAL Element = PublicElement BRANDED OBJECT num : TNumber := 0; (* serial number *) mrk : BOOLEAN := FALSE; (* mark to indicate visited/unvisited *) style: TStyle := 0; (* rendering style *) OVERRIDES mark := MarkElem; unmark := UnmarkElem; isMarked := IsElemMarked; getNum := GetElemNum; setNum := SetElemNum; getStyle := GetElemStyle; setStyle := SetElemStyle; END; VFType = PublicVFType BRANDED OBJECT geom : Point; OVERRIDES setGeom := SetVGeom; getGeom := GetVGeom; END; EFType = PublicEFType BRANDED OBJECT geom : Circle; OVERRIDES setGeom := SetEGeom; getGeom := GetEGeom; END; HEFType = PublicHEFType BRANDED OBJECT (* ---------------------------------------------------------------- *) (* the halfedge's geometry consists of the coefficients of the *) (* supporting circle plus "d \in \{-1,0,+1\}" which indicates the *) (* sense of travel around that circle; that is, "+1" indicates that *) (* the circle must be travelled in the positive direction, "0" *) (* indicates that the edge is useless (such as in an isolated *) (* vertex) and "-1" indicates that the circle must be travelled in *) (* its opposite direction. *) (* ---------------------------------------------------------------- *) circ : EFType; d : Sign := 0; wasbroken : BOOLEAN := FALSE; OVERRIDES initGeom := InitHEGeom; setGeom := SetHEGeom; getGeom := GetHEGeom; edge := Edge; fwd := Fwd; END; BFType = PublicBFT BRANDED OBJECT END; FFType = PublicFFT BRANDED OBJECT END; T = PublicT BRANDED OBJECT v : VFType := NIL; e : HEFType := NIL; OVERRIDES vertex := Vertex; halfEdge := HalfEdge; initVertex := InitVFeat; setVertex := SetVertex; initHalfEdge := InitHEFeat; setHalfEdge := SetHEdge; getGeoOfArc := GetGeoOfArc; END; (* ------------------------------------------------ *) (* General methods of Element *) (* ------------------------------------------------ *) PROCEDURE MarkElem(self: Element) = BEGIN self.mrk := TRUE; END MarkElem; PROCEDURE UnmarkElem(self: Element) = BEGIN self.mrk := FALSE; END UnmarkElem; PROCEDURE IsElemMarked(self: Element) : BOOLEAN = BEGIN RETURN self.mrk END IsElemMarked; PROCEDURE GetElemNum(self: Element) : TNumber = BEGIN RETURN self.num END GetElemNum; PROCEDURE SetElemNum(self: Element; n: TNumber) = BEGIN self.num := n END SetElemNum; PROCEDURE GetElemStyle(self: Element) : TStyle = BEGIN RETURN self.style END GetElemStyle; PROCEDURE SetElemStyle(self: Element; s: TStyle) = BEGIN self.style := s END SetElemStyle; (* ------------------------------------------------ *) (* Methods of Vertex *) (* ------------------------------------------------ *) PROCEDURE SetVGeom(self: VFType; p: Point) = BEGIN self.geom := p END SetVGeom; PROCEDURE GetVGeom(self: VFType) : Point = BEGIN RETURN self.geom END GetVGeom; (* ------------------------------------------------ *) (* Methods of Edge *) (* ------------------------------------------------ *) PROCEDURE SetEGeom(self: EFType; c: Circle) = BEGIN self.geom := c; END SetEGeom; PROCEDURE GetEGeom(self: EFType) : Circle = BEGIN RETURN self.geom END GetEGeom; (* ------------------------------------------------ *) (* Methods of HalfEdge *) (* ------------------------------------------------ *) PROCEDURE InitHEGeom(self: HEFType; c: Circle; d: Sign) = BEGIN self.circ:=NEW(EFType); self.circ.geom:=c; self.d:=d END InitHEGeom; PROCEDURE SetHEGeom(self: HEFType; e: EFType; d: Sign) = BEGIN self.circ:=e; self.d := d END SetHEGeom; PROCEDURE GetHEGeom(self: HEFType) : Circle = BEGIN IF self.d >= 0 THEN RETURN self.circ.getGeom() ELSE RETURN SMGeo.InvCircle(self.circ.getGeom()) END; END GetHEGeom; PROCEDURE Edge(self: HEFType) : EFType = BEGIN RETURN self.circ END Edge; PROCEDURE Fwd(self: HEFType) : Sign = BEGIN RETURN self.d END Fwd; (* ------------------------------------------------ *) (* Methods of the type Corner *) (* ------------------------------------------------ *) PROCEDURE Vertex(self: T) : VFType = BEGIN RETURN self.v END Vertex; PROCEDURE HalfEdge(self: T) : HEFType = BEGIN RETURN self.e END HalfEdge; PROCEDURE InitVFeat(self: T) = BEGIN self.v:=NEW(VFType) END InitVFeat; PROCEDURE SetVertex(self: T; v: VFType) = BEGIN self.v:=v END SetVertex; PROCEDURE InitHEFeat(self: T) = BEGIN self.e:=NEW(HEFType); END InitHEFeat; PROCEDURE SetHEdge(self: T; e: EFType; d: Sign) = BEGIN self.e.circ:=e; self.e.d:=d; END SetHEdge; PROCEDURE GetGeoOfArc(self: T; c: T) : Arc = VAR sc: Circle; p,q : Point; BEGIN IF self.e # NIL THEN (* it isn't an isolated vertex *) IF self.v = NIL THEN (* it's an oval *) p:= NIL; q:= NIL ELSE p:=self.vertex().getGeom(); q:=c.vertex().getGeom(); END; sc:= self.halfEdge().getGeom(); RETURN SMGeo.MakeArc(p,q,sc) ELSE RETURN NIL END END GetGeoOfArc; BEGIN END SMCFeat.