diff --git a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java index 947f609..b4a5df0 100644 --- a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java +++ b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/OrientedFace.java @@ -34,6 +34,12 @@ public abstract class OrientedFace implements Iterable { + private volatile V adjacentVertexOrdinal; + + void clear() { + adjacentVertexOrdinal = null; + } + /** * Perform a flip for deletion of the vertex from the tetrahedralization. The incident and adjacent tetrahedra form * an ear of the star set of tetrahedra adjacent to v. @@ -287,23 +293,25 @@ public Tetrahedron[] flip3to2(int reflexEdge) { * @return */ public Vertex getAdjacentVertex() { - if (getAdjacentVertexOrdinal() == null) { + var current = getAdjacentVertexOrdinal(); + if (current == null) { return null; } - return getAdjacent().getVertex(getAdjacentVertexOrdinal()); + return getAdjacent().getVertex(current); } - /** - * The vertex in the adjacent tetrahedron opposite of this face - */ /** * Answer the canonical ordinal of the vertex in the adjacent tetrahedron which is opposite of this face. * * @return */ public V getAdjacentVertexOrdinal() { - Tetrahedron adjacent = getAdjacent(); - return adjacent == null ? null : adjacent.ordinalOf(getIncident()); + var current = adjacentVertexOrdinal; + if (current == null) { + Tetrahedron adjacent = getAdjacent(); + current = adjacentVertexOrdinal = adjacent == null ? null : adjacent.ordinalOf(getIncident()); + } + return current; } /** diff --git a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java index abab242..7c7ea2e 100644 --- a/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java +++ b/lucien/src/main/java/com/hellblazer/luciferase/lucien/grid/Tetrahedron.java @@ -551,6 +551,7 @@ boolean isDeleted() { * @return */ V ordinalOf(Tetrahedron neighbor) { + clear(); if (nA == neighbor) { return A; } @@ -569,6 +570,13 @@ V ordinalOf(Tetrahedron neighbor) { throw new IllegalArgumentException("Not a neighbor: " + neighbor); } + private void clear() { + faceADB.clear(); + faceBCA.clear(); + faceCBD.clear(); + faceDAC.clear(); + } + /** * Patch the new tetrahedron created by a flip of the receiver by seting the neighbor to the value in the receiver *

@@ -633,6 +641,7 @@ void removeAnyDegenerateTetrahedronPair() { } void setNeighbor(V v, Tetrahedron n) { + clear(); if (v == A) { nA = n; return; @@ -645,25 +654,26 @@ void setNeighbor(V v, Tetrahedron n) { nC = n; return; } - if (v == D) { - nD = n; - return; - } + nD = n; } void setNeighborA(Tetrahedron t) { + clear(); nA = t; } void setNeighborB(Tetrahedron t) { + clear(); nB = t; } void setNeighborC(Tetrahedron t) { + clear(); nC = t; } void setNeighborD(Tetrahedron t) { + clear(); nD = t; }