Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

168
LINES

< > BotCompany Repo | #1035062 // G22MeshMapping - map one mesh to another one (bijectively mapping anchors and curves)

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (11403L) is out of date.

// 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
  BijectiveMap<Anchor> anchorMap = new BijectiveMap(true);
  
  // forward (mesh1 -> mesh2) and backward (mesh2 -> mesh1)
  new LinkedHashMap<Curve, MappedCurve> curveMap;
  new LinkedHashMap<Curve, MappedCurve> curveBackwardMap;
  
  // General validity check that should cover all bases
  
  void validityCheck() {
    if (mesh1 == mesh2)
      fail("Mesh1 and mesh2 must not be the same object");
      
    // For anchors, we only need to check that they come from the
    // right meshes. Bijectiveness is ensured by anchorMap itself.
    
    for (a1, a2 : anchorMap) {
      assertAnchorInMesh(a1, +mesh1);
      assertAnchorInMesh(a2, +mesh2);
    }
    
    for (c1, c2 : curveMap) {
      assertTrue(c1 + " is in mesh1", mesh1.containsCurve(c1));
      assertTrue(c2 + " is in mesh2", mesh2.containsCurve(c2!));
      
      // Check compatibility with anchor mappings
      
      assertEquals("Start point", c2.start(), getAnchorMapping(c1.start));
      assertEquals("End point", c2.end(), getAnchorMapping(c1.end));
    }
  }
  
  S validityError() {
    try {
      validityCheck();
      null;
    } catch e {
      ret "Validity error: " + e.getMessage();
    }
  }
  
  bool isValid() { ret validityError() == null; }
  
  // 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 assertAnchorInMesh(Anchor a, S meshName, G22Mesh mesh) {
  assertTrue(a + " is in " + meshName, mesh.containsAnchor(a));
  }
  
  AutoCloseable tempMapAnchor(Anchor a1, Anchor a2) {
    assertAnchorInMesh(a1, +mesh1);
    assertAnchorInMesh(a2, +mesh2);
    ret tempMapPut(anchorMap, a1, a2);
  }
 
  void mapAnchor(Anchor a1, Anchor a2) {
    assertAnchorInMesh(a1, +mesh1);
    assertAnchorInMesh(a2, +mesh2);
    anchorMap.put(a1, a2);
  }
  
  // Note: doesn't remove the curve mappings
  void unmapAnchor(Anchor a1) {
    anchorMap.remove(a1);
  }
  
  AutoCloseable tempMapCurve(Curve c1, Curve c2, bool flipped) {
    new L<AutoCloseable> closers;
    
    var forwardMapping = new MappedCurve(c2, flipped);
    var backwardMapping = new MappedCurve(c1, flipped);
    closers.add(tempMapPut(curveMap, c1, forwardMapping));
    closers.add(tempMapPut(curveBackwardMap, c2, backwardMapping));
    
    // Automatically map the anchors
    closers.add(tempMapAnchor(c1.start, forwardMapping.start());
    closers.add(tempMapAnchor(c1.end, forwardMapping.end());
    ret combineAutoCloseables(closers);
  }
  
  void mapCurve(Curve c1, Curve c2, bool flipped) {
    var forwardMapping = new MappedCurve(c2, flipped);
    var backwardMapping = new MappedCurve(c1, flipped);
    curveMap.put(c1, forwardMapping);
    curveBackwardMap.put(c2, backwardMapping);
    
    // Automatically map the anchors
    mapAnchor(c1.start, forwardMapping.start());
    mapAnchor(c1.end, forwardMapping.end());
  }
  
  // The following functions take anchors and curves from either mesh
  
  Anchor getAnchorMapping aka get(Anchor a) {
    try object anchorMap.get(a);
    ret anchorMap.inverseGet(a);
  }
  
  MappedCurve getCurveMapping aka get(Curve c) {
    try object curveMap.get(c);
    ret curveBackwardMap.get(c);
  }
  
  bool isMapped(Anchor a) {
    ret get(a) != null;
  }
  
  bool isMapped(Curve c) {
    ret get(c) != null;
  }
  
  L<Int> anchorMappingIndices() {
    var idx = mapItemsToListIndex(mesh2.anchorList());
    ret map(mesh1.anchorList(), a -> idx.get(get(a)));
  }
  
  L<Int> curveMappingIndices() {
    var idx = mapItemsToListIndex(mesh2.curveList());
    ret map(mesh1.curveList(), a -> {
      var c = get(a);
      ret c == null ?: idx.get(c!);
    });
  }
  
  toString {
    ret "Mapped anchors: " + anchorMappingIndices()
      + ", mapped curves: " + curveMappingIndices();
  }
  
  void drawMappedPartOfMesh1(Graphics2D g) {
    for (anchor : keys(anchorMap))
      new G22VisualizeMeshes().drawAnchor(g, anchor.pt);
    for (curve : keys(curveMap))
      new G22VisualizeMeshes().drawCurve(g, curve);
  }
  
  void drawMappedPartOfMesh2(Graphics2D g) {
    for (anchor : values(anchorMap))
      new G22VisualizeMeshes().drawAnchor(g, anchor.pt);
    for (curve : values(curveMap)) {
      new G22VisualizeMeshes vm;
      if (curve.flipped)
        vm.curveColor(Color.green);
      vm.drawCurve(g, curve!);
    }
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035062
Snippet name: G22MeshMapping - map one mesh to another one (bijectively mapping anchors and curves)
Eternal ID of this version: #1035062/39
Text MD5: 21f1d489130e875e86744cc54c2229d5
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-05-06 20:44:00
Source code size: 5170 bytes / 168 lines
Pitched / IR pitched: No / No
Views / Downloads: 146 / 349
Version history: 38 change(s)
Referenced in: [show references]