INTERFACE Energy; IMPORT LR3, Triang; FROM Triang IMPORT Topology; (* A generic energy function *) TYPE Coords = Triang.Coords; (* A vector of vertex coordinates *) Gradient = ARRAY OF LR3.T; (* A vector of energy gradients per vertex *) T = OBJECT METHODS defTop (READONLY top: Topology); (* Attaches the energy evaluator to some topological triangulation. Must be called at least once before "defVar" below. *) defVar (READONLY variable: ARRAY OF BOOLEAN); (* Tells "eval" which vertices "v" should be considered variables ("variable[v]=TRUE") or fixed parameters ("variable[v]=FALSE"); see below. Must be called at least once before the first use of "eval". Since it may be an expensive operation, clients should avoid calling it if the variable vertex set hasn't changed. *) eval ( READONLY c: Coords; VAR e: LONGREAL; grad: BOOLEAN; VAR eDc: Gradient; ); (* Returns in "e" the energy of triangulation "t" when the vertices have the coordinates "c". Also, if "grad" is TRUE, "eval" will return in "eDc" the gradient of "e", that is, the partial derivatives of "e" relative to each element of "c". An "Energy.T" object is typically used inside optimization loops where only some vertices are being adjusted, while the others are kept fixed in place. In that context the absolute value of the energy is not important; only energy differences are important. Accordingly, the "eval" method is free to omit any terms of the energy formula that depend only on fixed vertices. (However, the decision to omit a term must not depend on "c".) The client should be aware that if vertex "v" is fixed, the corresponding component of the gradient "eDc[v]" may not be set by "evalGrad", and therefore should not be used. *) name(): TEXT; (* Prints a description of the energy function. *) END; END Energy.