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); }
private HalfEdge addAdjoiningFace(Vertex eyeVtx, HalfEdge he) { Face face = Face.createTriangle( eyeVtx, he.tail(), he.head()); faces.Add(face); face.getEdge(-1).setOpposite(he.getOpposite()); return(face.getEdge(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); }
public void checkConsistency() { // do a sanity check on the face HalfEdge hedge = he0; double maxd = 0; int numv = 0; if (numVerts < 3) { throw new Exception( "degenerate face: " + getVertexString()); } do { HalfEdge hedgeOpp = hedge.getOpposite(); if (hedgeOpp == null) { throw new Exception( "face " + getVertexString() + ": " + "unreflected half edge " + hedge.getVertexString()); } else if (hedgeOpp.getOpposite() != hedge) { throw new Exception( "face " + getVertexString() + ": " + "opposite half edge " + hedgeOpp.getVertexString() + " has opposite " + hedgeOpp.getOpposite().getVertexString()); } if (hedgeOpp.head() != hedge.tail() || hedge.head() != hedgeOpp.tail()) { throw new Exception( "face " + getVertexString() + ": " + "half edge " + hedge.getVertexString() + " reflected by " + hedgeOpp.getVertexString()); } Face oppFace = hedgeOpp.face; if (oppFace == null) { throw new Exception( "face " + getVertexString() + ": " + "no face on half edge " + hedgeOpp.getVertexString()); } else if (oppFace.mark == DELETED) { throw new Exception( "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 Exception( "face " + getVertexString() + " numVerts=" + numVerts + " should be " + numv); } }