Program: 178231
Project: 178231
Buggy source:
/** 
 * Compute the bridge infill for unsupported polygons for a slice.  This is very heuristic...
 * @param unSupported
 * @param slice
 * @param layerConditions
 * @return
 */
public RrPolygonList bridgeHatch(BooleanGridList unSupported,BooleanGridList lands,LayerRules layerConditions){
  RrPolygonList result=new RrPolygonList();
  for (int i=0; i < lands.size(); i++) {
    BooleanGrid landPattern=lands.get(i);
    BooleanGrid land1;
    while ((land1=findLand(landPattern)) != null) {
      Rr2Point cen1=land1.findCentroid();
      landPattern=BooleanGrid.difference(landPattern,land1);
      if (cen1 == null) {
        Debug.e("String_Node_Str");
        continue;
      }
      int bridgesIndex=findBridges(unSupported,cen1);
      if (bridgesIndex < 0) {
        Debug.d("String_Node_Str");
        continue;
      }
      BooleanGrid bridges=unSupported.get(bridgesIndex);
      BooleanGrid bridge=bridges.floodCopy(cen1);
      if (bridge == null)       continue;
      BooleanGrid land2=null;
      land2=BooleanGrid.intersection(bridge,landPattern);
      Rr2Point cen2=land2.findCentroid();
      if (cen2 == null) {
        Debug.d("String_Node_Str");
        result.add(bridge.hatch(layerConditions.getHatchDirection(bridge.attribute().getExtruder()),bridge.attribute().getExtruder().getExtrusionInfillWidth(),bridge.attribute()));
      }
 else {
        landPattern=BooleanGrid.difference(landPattern,land2);
        Rr2Point centroidDirection=Rr2Point.sub(cen2,cen1).norm();
        Rr2Point bridgeDirection=centroidDirection;
        double spMax=Double.NEGATIVE_INFINITY;
        double sp;
        RrPolygonList bridgeOutline=bridge.allPerimiters(bridge.attribute());
        for (int pol=0; pol < bridgeOutline.size(); pol++) {
          RrPolygon polygon=bridgeOutline.polygon(i);
          for (int vertex1=0; vertex1 < polygon.size(); vertex1++) {
            int vertex2=vertex1 + 1;
            if (vertex2 >= polygon.size())             vertex2=0;
            Rr2Point edge=Rr2Point.sub(polygon.point(vertex2),polygon.point(vertex1));
            if ((sp=Math.abs(Rr2Point.mul(edge,centroidDirection))) > spMax) {
              spMax=sp;
              bridgeDirection=edge;
            }
          }
        }
        result.add(bridge.hatch(new RrHalfPlane(new Rr2Point(0,0),bridgeDirection),bridge.attribute().getExtruder().getExtrusionInfillWidth(),bridge.attribute()));
      }
      BooleanGridList b=new BooleanGridList();
      b.add(bridge);
      unSupported=BooleanGridList.differences(unSupported,b);
    }
  }
  return result;
}

Fixed version (ground truth):
/** 
 * Compute the bridge infill for unsupported polygons for a slice.  This is very heuristic...
 * @param infill
 * @param lands
 * @param layerConditions
 * @return
 */
public InFillPatterns bridgeHatch(InFillPatterns infill,BooleanGridList lands,LayerRules layerConditions){
  InFillPatterns result=new InFillPatterns(infill);
  BooleanGridList b;
  for (int i=0; i < lands.size(); i++) {
    BooleanGrid landPattern=lands.get(i);
    BooleanGrid land1;
    while ((land1=findLand(landPattern)) != null) {
      Rr2Point cen1=land1.findCentroid();
      landPattern=BooleanGrid.difference(landPattern,land1);
      if (cen1 == null) {
        Debug.e("String_Node_Str");
        continue;
      }
      int bridgesIndex=findBridges(result.bridges,cen1);
      if (bridgesIndex < 0) {
        Debug.d("String_Node_Str");
        continue;
      }
      BooleanGrid bridges=result.bridges.get(bridgesIndex);
      BooleanGrid bridge=bridges.floodCopy(cen1);
      if (bridge == null)       continue;
      BooleanGrid land2=null;
      land2=BooleanGrid.intersection(bridge,landPattern);
      Rr2Point cen2=land2.findCentroid();
      if (cen2 == null) {
        Debug.d("String_Node_Str");
        result.hatchedPolygons.add(bridge.hatch(layerConditions.getHatchDirection(bridge.attribute().getExtruder()),bridge.attribute().getExtruder().getExtrusionInfillWidth(),bridge.attribute()));
        b=new BooleanGridList();
        b.add(bridge);
        result.insides=BooleanGridList.differences(result.insides,b);
        result.surfaces=BooleanGridList.differences(result.surfaces,b);
      }
 else {
        landPattern=BooleanGrid.difference(landPattern,land2);
        Rr2Point centroidDirection=Rr2Point.sub(cen2,cen1).norm();
        Rr2Point bridgeDirection=centroidDirection;
        double spMax=Double.NEGATIVE_INFINITY;
        double sp;
        RrPolygonList bridgeOutline=bridge.allPerimiters(bridge.attribute());
        for (int pol=0; pol < bridgeOutline.size(); pol++) {
          RrPolygon polygon=bridgeOutline.polygon(i);
          for (int vertex1=0; vertex1 < polygon.size(); vertex1++) {
            int vertex2=vertex1 + 1;
            if (vertex2 >= polygon.size())             vertex2=0;
            Rr2Point edge=Rr2Point.sub(polygon.point(vertex2),polygon.point(vertex1));
            if ((sp=Math.abs(Rr2Point.mul(edge,centroidDirection))) > spMax) {
              spMax=sp;
              bridgeDirection=edge;
            }
          }
        }
        result.hatchedPolygons.add(bridge.hatch(new RrHalfPlane(new Rr2Point(0,0),bridgeDirection),bridge.attribute().getExtruder().getExtrusionInfillWidth(),bridge.attribute()));
        b=new BooleanGridList();
        b.add(bridge);
        result.insides=BooleanGridList.differences(result.insides,b);
        result.surfaces=BooleanGridList.differences(result.surfaces,b);
      }
      b=new BooleanGridList();
      b.add(bridge);
      result.bridges=BooleanGridList.differences(result.bridges,b);
    }
  }
  return result;
}