/**
   * Determine neighbours vertices for the given vertex.
   *
   * @param vertex the vertex to get the neighbour for
   * @return the determined neighbours.
   */
  private ArrayList<Vertex> getNeighboursVertices(Vertex vertex) {
    ArrayList<Vertex> neighbours = new ArrayList<Vertex>();
    HalfEdge first = vertex.getHalfEdge();
    HalfEdge next = first;

    do {
      neighbours.add(next.getOpposite().getStartVertex());
      next = next.getOpposite().getNext();
    } while (next != first);

    return neighbours;
  }
 public void computeVertexNormals() {
   for (HalfEdge first : halfEdges) {
     HalfEdge cur = first;
     Vector3 sum = cur.getFacet().getNormal();
     do {
       cur = cur.getOpposite().getNext();
       sum.add(cur.getFacet().getNormal());
     } while (cur != first);
     first.getStartVertex().setNormal(sum.getNormalized());
   }
 }
Exemple #3
0
  public int mergeAdjacentFace(HalfEdge hedgeAdj, Face[] discarded) {
    Face oppFace = hedgeAdj.oppositeFace();
    int numDiscarded = 0;

    discarded[numDiscarded++] = oppFace;
    oppFace.mark = DELETED;

    HalfEdge hedgeOpp = hedgeAdj.getOpposite();

    HalfEdge hedgeAdjPrev = hedgeAdj.prev;
    HalfEdge hedgeAdjNext = hedgeAdj.next;
    HalfEdge hedgeOppPrev = hedgeOpp.prev;
    HalfEdge hedgeOppNext = hedgeOpp.next;

    while (hedgeAdjPrev.oppositeFace() == oppFace) {
      hedgeAdjPrev = hedgeAdjPrev.prev;
      hedgeOppNext = hedgeOppNext.next;
    }

    while (hedgeAdjNext.oppositeFace() == oppFace) {
      hedgeOppPrev = hedgeOppPrev.prev;
      hedgeAdjNext = hedgeAdjNext.next;
    }

    HalfEdge hedge;

    for (hedge = hedgeOppNext; hedge != hedgeOppPrev.next; hedge = hedge.next) {
      hedge.face = this;
    }

    if (hedgeAdj == he0) {
      he0 = hedgeAdjNext;
    }

    // handle the half edges at the head
    Face discardedFace;

    discardedFace = connectHalfEdges(hedgeOppPrev, hedgeAdjNext);
    if (discardedFace != null) {
      discarded[numDiscarded++] = discardedFace;
    }

    // handle the half edges at the tail
    discardedFace = connectHalfEdges(hedgeAdjPrev, hedgeOppNext);
    if (discardedFace != null) {
      discarded[numDiscarded++] = discardedFace;
    }

    computeNormalAndCentroid();
    checkConsistency();

    return numDiscarded;
  }
Exemple #4
0
  private Face connectHalfEdges(HalfEdge hedgePrev, HalfEdge hedge) {
    Face discardedFace = null;

    if (hedgePrev.oppositeFace()
        == hedge.oppositeFace()) { // then there is a redundant edge that we can get rid off

      Face oppFace = hedge.oppositeFace();
      HalfEdge hedgeOpp;

      if (hedgePrev == he0) {
        he0 = hedge;
      }
      if (oppFace.numVertices() == 3) { // then we can get rid of the opposite face altogether
        hedgeOpp = hedge.getOpposite().prev.getOpposite();

        oppFace.mark = DELETED;
        discardedFace = oppFace;
      } else {
        hedgeOpp = hedge.getOpposite().next;

        if (oppFace.he0 == hedgeOpp.prev) {
          oppFace.he0 = hedgeOpp;
        }
        hedgeOpp.prev = hedgeOpp.prev.prev;
        hedgeOpp.prev.next = hedgeOpp;
      }
      hedge.prev = hedgePrev.prev;
      hedge.prev.next = hedge;

      hedge.opposite = hedgeOpp;
      hedgeOpp.opposite = hedge;

      // oppFace was modified, so need to recompute
      oppFace.computeNormalAndCentroid();
    } else {
      hedgePrev.next = hedge;
      hedge.prev = hedgePrev;
    }
    return discardedFace;
  }
Exemple #5
0
  void checkConsistency() {
    // do a sanity check on the face
    HalfEdge hedge = he0;
    double maxd = 0;
    int numv = 0;

    if (numVerts < 3) {
      throw new InternalErrorException("degenerate face: " + getVertexString());
    }
    do {
      HalfEdge hedgeOpp = hedge.getOpposite();
      if (hedgeOpp == null) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "unreflected half edge "
                + hedge.getVertexString());
      } else if (hedgeOpp.getOpposite() != hedge) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "opposite half edge "
                + hedgeOpp.getVertexString()
                + " has opposite "
                + hedgeOpp.getOpposite().getVertexString());
      }
      if (hedgeOpp.head() != hedge.tail() || hedge.head() != hedgeOpp.tail()) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "half edge "
                + hedge.getVertexString()
                + " reflected by "
                + hedgeOpp.getVertexString());
      }
      Face oppFace = hedgeOpp.face;
      if (oppFace == null) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "no face on half edge "
                + hedgeOpp.getVertexString());
      } else if (oppFace.mark == DELETED) {
        throw new InternalErrorException(
            "face "
                + getVertexString()
                + ": "
                + "opposite face "
                + oppFace.getVertexString()
                + " not on hull");
      }
      double d = Math.abs(distanceToPlane(hedge.head().pnt));
      if (d > maxd) {
        maxd = d;
      }
      numv++;
      hedge = hedge.next;
    } while (hedge != he0);

    if (numv != numVerts) {
      throw new InternalErrorException(
          "face " + getVertexString() + " numVerts=" + numVerts + " should be " + numv);
    }
  }