public static boolean isFaceCrossing( IVec2[] pts, EdgeCounter edgeCount, int ptIdx1, int ptIdx2, int ptIdx3) { if (edgeCount.hasOneFace(ptIdx1, ptIdx2)) { if (isVertexOnSameSide( pts[ptIdx1], pts[ptIdx2], pts[ptIdx3], pts[edgeCount.getFaceVertexIndex(ptIdx1, ptIdx2)])) return true; } if (edgeCount.hasOneFace(ptIdx1, ptIdx3)) { if (isVertexOnSameSide( pts[ptIdx1], pts[ptIdx3], pts[ptIdx2], pts[edgeCount.getFaceVertexIndex(ptIdx1, ptIdx3)])) return true; } if (edgeCount.hasOneFace(ptIdx2, ptIdx3)) { if (isVertexOnSameSide( pts[ptIdx2], pts[ptIdx3], pts[ptIdx1], pts[edgeCount.getFaceVertexIndex(ptIdx2, ptIdx3)])) return true; } return false; }
public static void checkNakedEdge( IVec2[] pts, ArrayList<FaceIndex> faceIdx, ArrayList<IVec2[]> triangles, EdgeCounter edgeCount) { for (int i = 0; i < pts.length - 1; i++) { // IOut.p(i+"/"+pts.length); // for (int j = i + 1; j < pts.length; j++) { if (edgeCount.getEdgeNum(i, j) == 1) { boolean added = false; // for(int k=j+1; k<pts.length && !added; k++){ for (int k = 0; k < pts.length && !added; k++) { // fill triangle at the edge or, fill triangle in an obvious triangular hole // not filling when 3 edges already form a triangle FaceIndex fidx = null; boolean addFace = false; if (k != i && k != j) { int idx1 = i; int idx2 = j; int idx3 = k; // re-order if (k < i) { idx1 = k; idx2 = i; idx3 = j; } else if (k < j) { idx1 = i; idx2 = k; idx3 = j; } /* IOut.p("checking <"+i+","+j+","+k+">"); // IOut.p("isEdgeOnOutline("+idx1+","+idx2+") = "+ edgeCount.isEdgeOnOutline(idx1,idx2)); IOut.p("isEdgeOnOutline("+idx1+","+idx3+") = "+ edgeCount.isEdgeOnOutline(idx1,idx3)); IOut.p("isEdgeOnOutline("+idx2+","+idx3+") = "+ edgeCount.isEdgeOnOutline(idx2,idx3)); IOut.p("isFaceDirectionOnEdgeCorrect("+idx1+","+idx2+","+idx3+") = "+ isFaceDirectionOnEdgeCorrect(pts[idx1],pts[idx2],pts[idx3])); IOut.p("isFaceDirectionOnEdgeCorrect("+idx1+","+idx3+","+idx2+") = "+ isFaceDirectionOnEdgeCorrect(pts[idx1],pts[idx3],pts[idx2])); IOut.p("isFaceDirectionOnEdgeCorrect("+idx2+","+idx3+","+idx1+") = "+ isFaceDirectionOnEdgeCorrect(pts[idx2],pts[idx3],pts[idx1])); IOut.p("isEdgeOpen("+idx1+","+idx2+") = "+ edgeCount.isEdgeOpen(idx1,idx2)); IOut.p("isEdgeOpen("+idx1+","+idx3+") = "+ edgeCount.isEdgeOpen(idx1,idx3)); IOut.p("isEdgeOpen("+idx2+","+idx3+") = "+ edgeCount.isEdgeOpen(idx2,idx3)); */ if (edgeCount.isEdgeOnOutline(idx1, idx2) && edgeCount.isEdgeOnOutline(idx2, idx3) && edgeCount.hasOneFace(idx1, idx3) && // isFaceDirectionOnEdgeCorrect(pts[idx1],pts[idx2],pts[idx3])){ // if idx1==0, idx2 is last point on outline and order should be idx2->idx1 isFaceDirectionOnEdgeCorrect( pts[idx1 == 0 ? idx2 : idx1], pts[idx1 == 0 ? idx1 : idx2], pts[idx3])) { // IOut.p("addFace 4"); // addFace = true; } else if (edgeCount.isEdgeOnOutline(idx1, idx3) && edgeCount.isEdgeOnOutline(idx2, idx3) && edgeCount.hasOneFace(idx1, idx2) && // isFaceDirectionOnEdgeCorrect(pts[idx1],pts[idx3],pts[idx2])){ isFaceDirectionOnEdgeCorrect( pts[idx1 == 0 ? idx3 : idx1], pts[idx1 == 0 ? idx1 : idx3], pts[idx2])) { // IOut.p("addFace 5"); // addFace = true; } else if (edgeCount.isEdgeOnOutline(idx1, idx3) && edgeCount.isEdgeOnOutline(idx1, idx2) && edgeCount.hasOneFace(idx2, idx3) && // isFaceDirectionOnEdgeCorrect(pts[idx2],pts[idx3],pts[idx1])){ isFaceDirectionOnEdgeCorrect( pts[idx2 == 0 ? idx3 : idx2], pts[idx2 == 0 ? idx2 : idx3], pts[idx1])) { // IOut.p("addFace 6"); // addFace = true; } else if (edgeCount.isEdgeOnOutline(idx1, idx2) && // (edgeCount.isEdgeOpen(idx1,idx3) || edgeCount.isEdgeOpen(idx2,idx3))){ edgeCount.isEdgeOpen(idx1, idx3) && edgeCount.isEdgeOpen(idx2, idx3)) { if (isFaceDirectionOnEdgeCorrect( pts[idx1 == 0 ? idx2 : idx1], pts[idx1 == 0 ? idx1 : idx2], pts[idx3]) && !isFaceCrossing(pts, edgeCount, idx1, idx2, idx3)) { // IOut.p("addFace 1"); // addFace = true; } } else if (edgeCount.isEdgeOnOutline(idx1, idx3) && // (edgeCount.isEdgeOpen(idx1,idx2)||edgeCount.isEdgeOpen(idx2,idx3))){ edgeCount.isEdgeOpen(idx1, idx2) && edgeCount.isEdgeOpen(idx2, idx3)) { if (isFaceDirectionOnEdgeCorrect( pts[idx1 == 0 ? idx3 : idx1], pts[idx1 == 0 ? idx1 : idx3], pts[idx2]) && !isFaceCrossing(pts, edgeCount, idx1, idx2, idx3)) { // IOut.p("addFace 2"); // addFace = true; } } else if (edgeCount.isEdgeOnOutline(idx2, idx3) && // (edgeCount.isEdgeOpen(idx1,idx2)||edgeCount.isEdgeOpen(idx1,idx3))){ edgeCount.isEdgeOpen(idx1, idx2) && edgeCount.isEdgeOpen(idx1, idx3)) { // IOut.p("isFaceCrossing("+idx1+","+idx2+","+idx3+") = "+isFaceCrossing(pts, // edgeCount, idx1, idx2, idx3)); // if (isFaceDirectionOnEdgeCorrect( pts[idx2 == 0 ? idx3 : idx2], pts[idx2 == 0 ? idx2 : idx3], pts[idx1]) && !isFaceCrossing(pts, edgeCount, idx1, idx2, idx3)) { // IOut.p("addFace 3 <"+idx2+","+idx3+","+idx1+">"); // addFace = true; } } else if ((edgeCount.getEdgeNum(idx1, idx2) == 1 && edgeCount.getEdgeNum(idx1, idx3) == 1 && edgeCount.getEdgeNum(idx2, idx3) == 1 && edgeCount.getFaceVertexIndex(idx1, idx2) != -1 && edgeCount.getFaceVertexIndex(idx1, idx3) != -1 && edgeCount.getFaceVertexIndex(idx2, idx3) != -1 && ((fidx = findTriangleIndexWithEdge(faceIdx, idx1, idx2)) == null || fidx.getOtherIndex(idx1, idx2) != idx3))) { // IOut.p("addFace 7"); // addFace = true; } if (addFace) { // IOut.p("face added at <"+i+","+j+","+k+">"); // // edgeCount.addFace(i,j,k); // triangles.add(new IVec2[]{ pts[i],pts[j],pts[k]}); // faceIdx.add(new FaceIndex(i,j,k)); // IOut.p("face added at <"+idx1+","+idx2+","+idx3+">"); // edgeCount.addFace(idx1, idx2, idx3); triangles.add(new IVec2[] {pts[idx1], pts[idx2], pts[idx3]}); faceIdx.add(new FaceIndex(idx1, idx2, idx3)); added = true; } } /* if((edgeCount.getEdgeNum(i,k)==1&&edgeCount.getEdgeNum(j,k)==1 || edgeCount.getEdgeNum(i,k)==1&&edgeCount.getEdgeNum(j,k)==0 || edgeCount.getEdgeNum(i,k)==0&&edgeCount.getEdgeNum(j,k)==1 ) && (edgeCount.getFaceVertexIndex(i,j)==-1 || edgeCount.getFaceVertexIndex(i,k)==-1 || edgeCount.getFaceVertexIndex(j,k)==-1 ) || ( edgeCount.getEdgeNum(i,k)==1&&edgeCount.getEdgeNum(j,k)==1 && edgeCount.getFaceVertexIndex(i,j)!=-1 && edgeCount.getFaceVertexIndex(i,k)!=-1 && edgeCount.getFaceVertexIndex(j,k)!=-1 && ((fidx = findTriangleIndexWithEdge(faceIdx, i, j)) ==null || fidx.getOtherIndex(i,j) != k)) ){ IOut.p("face added at <"+i+","+j+","+k+">"); // edgeCount.addFace(i,j,k); triangles.add(new IVec2[]{ pts[i],pts[j],pts[k]}); faceIdx.add(new FaceIndex(i,j,k)); added=true; } */ } } } } // remove triangles which have naked edge but not on the outline // (likely to be inside of inner holes or outside of outer trim for (int i = 0; i < pts.length - 1; i++) { for (int j = i + 1; j < pts.length; j++) { if (edgeCount.getEdgeNum(i, j) == 1 && edgeCount.getFaceVertexIndex(i, j) != -1) { // IOut.p("naked edge found at <"+i+","+j+">"); // FaceIndex fidx = findTriangleIndexWithEdge(faceIdx, i, j); if (fidx != null) { int k = fidx.getOtherIndex(i, j); IVec2[] tr = findTriangleWithIndex(pts, triangles, i, j, k); if (tr != null) { triangles.remove(tr); // IOut.p("face removed at <"+i+","+j+","+k+">"); // } } } } } }