예제 #1
0
  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;
  }
예제 #2
0
  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+">"); //
            }
          }
        }
      }
    }
  }