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 String getVertexString() { String s = null; HalfEdge he = he0; do { if (s == null) { s = "" + he.head().index; } else { s += " " + he.head().index; } he = he.next; }while (he != he0); return(s); }
public void getVertexIndices(int[] idxs) { HalfEdge he = he0; int i = 0; do { idxs[i++] = he.head().index; he = he.next; }while (he != he0); }
private void markFaceVertices(Face face, int mark) { HalfEdge he0 = face.getFirstEdge(); HalfEdge he = he0; do { he.head().index = mark; he = he.next; }while (he != he0); }
public void computeCentroid(point3d centroid) { centroid.setZero(); HalfEdge he = he0; do { centroid.add(he.head().pnt); he = he.next; }while (he != he0); centroid.scale(1 / (double)numVerts); }
public void computeNormal(vector3d normal) { HalfEdge he1 = he0.next; HalfEdge he2 = he1.next; point3d p0 = he0.head().pnt; point3d p2 = he1.head().pnt; double d2x = p2.x - p0.x; double d2y = p2.y - p0.y; double d2z = p2.z - p0.z; normal.setZero(); numVerts = 2; while (he2 != he0) { double d1x = d2x; double d1y = d2y; double d1z = d2z; p2 = he2.head().pnt; d2x = p2.x - p0.x; d2y = p2.y - p0.y; d2z = p2.z - p0.z; normal.x += d1y * d2z - d1z * d2y; normal.y += d1z * d2x - d1x * d2z; normal.z += d1x * d2y - d1y * d2x; he1 = he2; he2 = he2.next; numVerts++; } area = normal.norm(); normal.scale(1 / area); }
public HalfEdge findEdge(Vertex vt, Vertex vh) { HalfEdge he = he0; do { if (he.head() == vh && he.tail() == vt) { return(he); } he = he.next; }while (he != he0); return(null); }
private double areaSquared(HalfEdge hedge0, HalfEdge hedge1) { point3d p0 = hedge0.tail().pnt; point3d p1 = hedge0.head().pnt; point3d p2 = hedge1.head().pnt; double dx1 = p1.x - p0.x; double dy1 = p1.y - p0.y; double dz1 = p1.z - p0.z; double dx2 = p2.x - p0.x; double dy2 = p2.y - p0.y; double dz2 = p2.z - p0.z; double x = dy1 * dz2 - dz1 * dy2; double y = dz1 * dx2 - dx1 * dz2; double z = dx1 * dy2 - dy1 * dx2; return(x * x + y * y + z * z); }
private void setHull(double[] coords, int nump, int[][] faceIndices, int numf) { initBuffers(nump); setPoints(coords, nump); computeMaxAndMin(); for (int i = 0; i < numf; i++) { Face face = Face.create(pointBuffer, faceIndices[i]); HalfEdge he = face.he0; do { HalfEdge heOpp = findHalfEdge(he.head(), he.tail()); if (heOpp != null) { he.setOpposite(heOpp); } he = he.next; }while (he != face.he0); faces.Add(face); } }
public void computeNormal(vector3d normal, double minArea) { computeNormal(normal); if (area < minArea) { // make the normal more robust by removing // components parallel to the longest edge HalfEdge hedgeMax = null; double lenSqrMax = 0; HalfEdge hedge = he0; do { double lenSqr = hedge.lengthSquared(); if (lenSqr > lenSqrMax) { hedgeMax = hedge; lenSqrMax = lenSqr; } hedge = hedge.next; }while (hedge != he0); point3d p2 = hedgeMax.head().pnt; point3d p1 = hedgeMax.tail().pnt; double lenMax = Math.Sqrt(lenSqrMax); double ux = (p2.x - p1.x) / lenMax; double uy = (p2.y - p1.y) / lenMax; double uz = (p2.z - p1.z) / lenMax; double dot = normal.x * ux + normal.y * uy + normal.z * uz; normal.x -= dot * ux; normal.y -= dot * uy; normal.z -= dot * uz; normal.normalize(); } }
private void getFaceIndices(int[] indices, Face face, int flags) { bool ccw = ((flags & CLOCKWISE) == 0); bool indexedFromOne = ((flags & INDEXED_FROM_ONE) != 0); bool pointRelative = ((flags & POINT_RELATIVE) != 0); HalfEdge hedge = face.he0; int k = 0; do { int idx = hedge.head().index; if (pointRelative) { idx = vertexPointIndices[idx]; } if (indexedFromOne) { idx++; } indices[k++] = idx; hedge = (ccw ? hedge.next : hedge.prev); }while (hedge != face.he0); }
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); } }