srecord noeq G22MeshMapper_v2(G22Mesh mesh1, G22Mesh mesh2) { // import the important classes delegate Anchor, Curve to G22Mesh. G22MeshMapping mm; // index structures MultiMap anchorsByArity2; // EXCEPTIONS (e.g. meshes don't match in signature) // set to the reason why when a mapping is deemed impossible settable O rejectedBecause; bool rejected() { ret rejectedBecause != null; } // INTERNAL VARS bool prechecksDone; S sig1, sig2; G22MeshMapping get() { ret mm; } void search_step1() { prechecks(); if (rejected()) ret; // make empty mapping mm = new G22MeshMapping(mesh1, mesh2); anchorsByArity2 = multiMapIndex(mesh2.anchors(), a -> a.arity()); Anchor anchor1 = random(mesh1.anchors()); Anchor anchor2 = random(anchorsByArity2.get(anchor1.arity()); mapAnchor(anchor1, anchor2); } bool search_step2() { bool change; for (curve1 : mesh1.curves()) { // skip if curve is already mapped if (mm.isMapped(curve1)) continue with print("Curve is mapped: " + curve1); // check if anchors are mapped Anchor start2 = mm.get(curve1.start); Anchor end2 = mm.get(curve1.end); // If neither anchor is mapped, postpone this curve if (start2 == null || end2 == null) continue with print("Curve is not discovered yet: " + curve1); // Start at the mapped anchor, choose a viable curve in mesh2 to map to bool startAtEnd = end2 != null; Anchor a1other = curve1.anchor(!startAtEnd); Anchor a2 = mm.get(curve1.anchor(startAtEnd)); new L possibleCurves; for (c2 : a2.curves()) { if (mm.isMapped(c2)) continue; // check for arity match Anchor a3 = c2.anchorOpposite(a2); if (a3.arity() != a1other.arity()) continue; // This curve is viable as a mapping target possibleCurves.add(c2); } print("Possible curves to map " + curve1 + " to: " + possibleCurves); if (empty(possibleCurves)) ret false with rejectedBecause("Could not map curve " + curve1); // Map the curve Curve c2 = random(possibleCurves); bool flipped = c2.start() != a2; print("Mapping curve " + curve1 + " to " + c2); mm.mapCurve(curve1, c2, flipped); set change; } ret change; } void mapAnchor(Anchor anchor1, Anchor anchor2) { mm.mapAnchor(anchor1, anchor2); } protected void prechecks { set prechecksDone; sig1 = mesh1.signature(); sig2 = mesh1.signature(); if (!eq(sig1, sig2)) ret with rejectedBecause(G22SignatureMismatch(mesh1, mesh2)); } }