G3dNatsImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Glassner, February 19, 1991 10:43 am PST
Jules Bloomenthal August 26, 1992 3:25 pm PDT
DIRECTORY G2dBasic, G3dBasic, G3dNats, Real, Rope;
Imported Types
ROPE: TYPE ~ Rope.ROPE;
IntegerPairSequence: TYPE ~ G2dBasic.IntegerPairSequence;
IntegerPairSequenceRep: TYPE ~ G2dBasic.IntegerPairSequenceRep;
NatSequence: TYPE ~ G2dBasic.NatSequence;
NatSequenceRep: TYPE ~ G2dBasic.NatSequenceRep;
BoolSequence: TYPE ~ G3dBasic.BoolSequence;
BoolSequenceRep: TYPE ~ G3dBasic.BoolSequenceRep;
NatTable: TYPE ~ G3dNats.NatTable;
NatTableRep: TYPE ~ G3dNats.NatTableRep;
Error: PUBLIC SIGNAL [reason: ROPE] = CODE;
NatSequence Support
NewNatSequence3:
PUBLIC
PROC [v0, v1, v2:
INT]
RETURNS [nats: NatSequence] ~ {
nats ¬ NEW[NatSequenceRep[3]];
nats.length ¬ 3;
nats[0] ¬ v0;
nats[1] ¬ v1;
nats[2] ¬ v2;
};
EqualNatSequences:
PUBLIC
PROC [s1, s2: NatSequence]
RETURNS [
BOOL] ~ {
Return TRUE iff the two surfaces are the same
match: BoolSequence ¬ NEW[BoolSequenceRep[s1.length]];
match.length ¬ s1.length;
IF s1=NIL OR s2=NIL THEN RETURN [FALSE];
IF s1.length # s2.length THEN RETURN [FALSE];
FOR i:
INT
IN [0 .. s1.length)
DO
match[i] ¬ FALSE;
FOR j:
INT
IN [0 .. s2.length)
DO
IF s2[j] = s1[i] THEN { match[i] ¬ TRUE; EXIT; };
ENDLOOP;
ENDLOOP;
FOR i:
INT
IN [0 .. match.length)
DO
IF NOT match[i] THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
};
GetCommonElementInNatSequences:
PUBLIC
PROC [n1, n2: NatSequence]
RETURNS [
INT ¬ -1] ~ {
dumb n2 test, but I only expect these to be three long anyway. Return -1 if none shared.
IF n1=NIL OR n2=NIL THEN RETURN;
FOR i:
INT
IN [0 .. n1.length)
DO
FOR j:
INT
IN [0 .. n2.length)
DO
IF n1[i] = n2[j] THEN RETURN [n1[i]];
ENDLOOP;
ENDLOOP;
};
GetNatSequenceIndex:
PUBLIC
PROC [nats: NatSequence, nat:
NAT]
RETURNS [
INT ¬ -1] ~ {
return index into sequence where nat appears, else -1
IF nats=NIL THEN RETURN;
FOR i:
INT
IN [0 .. nats.length)
DO
IF nats[i] = nat THEN RETURN[i];
ENDLOOP;
};
ReplaceNatInSequence:
PUBLIC
PROC[n: NatSequence, old, new:
NAT]
RETURNS[r: NatSequence]~{
r ¬ NIL;
IF n=NIL THEN RETURN;
FOR i:
INT
IN [0 .. n.length)
DO
IF n[i] # old
THEN r ¬ G2dBasic.AddToNatSequence[r, n[i]]
ELSE r ¬ G2dBasic.AddToNatSequence[r, new];
ENDLOOP;
};
RemoveNatInSequence:
PUBLIC
PROC[n: NatSequence, old:
NAT]
RETURNS [r: NatSequence ¬
NIL ]~{
IF n=NIL THEN RETURN;
FOR i:
INT
IN [0 .. n.length)
DO
IF n[i] # old THEN r ¬ G2dBasic.AddToNatSequence[r, n[i]]
ENDLOOP;
};
GetUniqueElement:
PUBLIC
PROC [ns: NatSequence]
RETURNS [unique:
INT ¬ -1] ~ {
returns the single unrepeated element in ns
IF ns=NIL THEN RETURN;
FOR i:
INT
IN [0 .. ns.length)
DO
repeat: BOOL ¬ FALSE;
FOR j:
INT
IN [0 .. ns.length)
DO
IF (i#j) AND (ns[i]=ns[j]) THEN repeat¬TRUE;
ENDLOOP;
IF
NOT repeat
THEN
IF unique < 0
THEN unique ¬ ns[i]
ELSE Error["no single unique element"]
ENDLOOP;
};
GetRepeatedElement:
PUBLIC
PROC [ns: NatSequence]
RETURNS [
INT ¬ -1] ~ {
IF ns=NIL THEN RETURN;
FOR i:
INT
IN [0 .. ns.length)
DO
FOR j:
INT
IN [0 .. ns.length)
DO
IF (i#j) AND (ns[i]=ns[j]) THEN RETURN[ns[i]];
ENDLOOP;
ENDLOOP;
};
GetElementNotShared:
PUBLIC
PROC [v:
NAT, ns: NatSequence]
RETURNS [unique:
INT ¬ -1] ~ {
returns that single element in n1 that is not v
IF ns=NIL THEN RETURN;
FOR i:
INT
IN [0 .. ns.length)
DO
IF ns[i] # v
THEN
IF unique < 0 THEN unique ¬ ns[i]
ELSE Error["repeated unique vertex"];
ENDLOOP;
};
NatInSequence:
PUBLIC
PROC [nat:
NAT, seq: NatSequence]
RETURNS [
BOOL] ~ {
test if this nat is in this sequence
IF seq=NIL THEN RETURN [FALSE];
FOR i: INT IN [0 .. seq.length) DO IF seq[i]=nat THEN RETURN [TRUE]; ENDLOOP;
RETURN[FALSE];
};
NatSequenceLength:
PUBLIC
PROC [seq: NatSequence]
RETURNS [
INT] ~ {
IF seq = NIL THEN RETURN[0] ELSE RETURN [seq.length];
};
NatTable Sequences
CopyNatTable:
PUBLIC
PROC [nats: NatTable]
RETURNS [NatTable] ~ {
copy: NatTable ¬ NIL;
IF nats #
NIL
THEN {
copy ¬ NEW[NatTableRep[nats.length]];
copy.length ¬ nats.length;
FOR n: NAT IN [0..nats.length) DO copy[n] ¬ nats[n]; ENDLOOP;
};
RETURN[copy];
};
AddToNatTable:
PUBLIC
PROC [nats: NatTable, nat: NatSequence]
RETURNS [NatTable] ~ {
IF nats = NIL THEN nats ¬ NEW[NatTableRep[1]];
IF nats.length = nats.maxLength THEN nats ¬ LengthenNatTable[nats];
nats[nats.length] ¬ nat;
nats.length ¬ nats.length+1;
RETURN[nats];
};
LengthenNatTable:
PUBLIC
PROC [nats: NatTable, amount:
REAL ¬ 1.3]
RETURNS [new: NatTable] ~ {
newLength: CARDINAL ¬ Real.Ceiling[amount*nats.maxLength];
newLength ¬ MAX[newLength, 3];
new ¬ NEW[NatTableRep[newLength]];
FOR i: NAT IN [0..nats.length) DO new[i] ¬ nats[i]; ENDLOOP;
new.length ¬ nats.length;
};
Scratch Pool
scratchNats: ARRAY [0..10) OF NatSequence ¬ ALL[NIL];
scratchIntegerPairs:
ARRAY [0..10)
OF IntegerPairSequence ¬
ALL[
NIL];
ObtainScratchNats:
PUBLIC ENTRY
PROC [length:
INTEGER]
RETURNS [NatSequence] ~ {
FOR i:
NAT
IN [0..10)
DO
scratch: NatSequence ¬ scratchNats[i];
IF scratch = NIL OR scratch.maxLength < CARDINAL[length] THEN LOOP;
scratchNats[i] ¬ NIL;
RETURN[scratch];
ENDLOOP;
RETURN[NEW[NatSequenceRep[length]]];
};
ReleaseScratchNats:
PUBLIC ENTRY
PROC [scratch: NatSequence] ~ {
FOR i:
INTEGER
IN [0..10)
DO
IF scratchNats[i] # NIL AND scratch.maxLength <= scratchNats[i].maxLength THEN LOOP;
scratchNats[i] ¬ scratch;
RETURN;
ENDLOOP;
};
ObtainScratchIntegerPairs:
PUBLIC ENTRY
PROC [length:
INTEGER]
RETURNS [IntegerPairSequence]
~ {
FOR i:
NAT
IN [0..10)
DO
scratch: IntegerPairSequence ¬ scratchIntegerPairs[i];
IF scratch = NIL OR scratch.maxLength < CARDINAL[length] THEN LOOP;
scratchIntegerPairs[i] ¬ NIL;
RETURN[scratch];
ENDLOOP;
RETURN[NEW[IntegerPairSequenceRep[length]]];
};
ReleaseScratchIntegerPairs:
PUBLIC ENTRY
PROC [scratch: IntegerPairSequence] ~ {
FOR i:
INTEGER
IN [0..10)
DO
IF scratchIntegerPairs[i] #
NIL
AND scratch.maxLength <= scratchIntegerPairs[i].maxLength
THEN LOOP;
scratchIntegerPairs[i] ¬ scratch;
RETURN;
ENDLOOP;
};