// For users of this class: Don't fill the maps directly, call // mapAnchor + mapCurve. srecord noeq G22MeshMapping(G22Mesh mesh1, G22Mesh mesh2) { delegate Anchor, Curve to G22Mesh. // A mapping of a curve to another curve may be "flipped" // (start becomes end and end becomes start) srecord MappedCurve(Curve curve, bool flipped) { Curve get() { ret curve; } Anchor start() { ret curve.anchor(flipped); } Anchor end() { ret curve.anchor(!flipped); } } // For both maps: keys are from mesh1, values are from mesh2 new BijectiveMap anchorMap; // forward (mesh1 -> mesh2) and backward (mesh2 -> mesh1) new Map curveMap; new Map curveBackwardMap; // General validity check that should cover all bases void validityCheck() { // For anchors, we only need to check that they come from the // right meshes. Bijectiveness is ensured by anchorMap itself. for (a1, a2 : anchorMap) { assertTrue(mesh1.containsAnchor(a1)); assertTrue(mesh2.containsAnchor(a2)); } for (c1, c2 : curveMap) { assertTrue(mesh1.containsCurve(c1)); assertTrue(mesh2.containsCurve(c2!)); // Check compatibility with anchor mappings assertEquals(c2.start(), getAnchorMapping(c1.start)); assertEquals(c2.end(), getAnchorMapping(c1.end)); } } // A mapping is complete iff all anchors and curves from both // meshes are covered. bool isComplete() { ret allEq(l(anchorMap), l(mesh1.anchors()), l(mesh2.anchors())) && allEq(l(curveMap), l(mesh1.curves()), l(mesh2.curves())); } void mapAnchor(Anchor a1, Anchor a2) { anchorMap.put(a1, a2); } void mapCurve(Curve c1, Curve c2, bool flipped) { curveMap.put(c1, new MappedCurve(c2, flipped)); curveBackwardMap.put(c2, new MappedCurve(c1, flipped)); } Anchor getAnchorMapping aka get(Anchor a) { ret anchorMap.get(a); } MappedCurve getCurveMapping aka get(Curve c) { ret curveMap.get(c); } bool isMapped(Anchor a1) { ret get(a1) != null; } bool isMapped(Curve c1) { ret get(c1) != null; } }