/** @param f */ HE_FaceFaceCirculator(final HE_Face f) { _start = f.getHalfedge(); _current = null; }
/** @param el */ public void copyProperties(final HE_Face el) { super.copyProperties(el); facecolor = el.getColor(); textureId = el.textureId; }
/* * (non-Javadoc) * * @see wblut.hemesh.HE_Modifier#apply(wblut.hemesh.HE_Mesh) */ @Override public HE_Mesh apply(final HE_Mesh mesh) { cut = new HE_Selection(mesh); cutEdges = new HE_Selection(mesh); // no plane defined if (P == null) { return mesh; } // empty mesh if (mesh.getNumberOfVertices() == 0) { return mesh; } // check if plane intersects mesh final WB_Plane lP = new WB_Plane(P.getNormal(), P.d() + offset); if (!WB_Intersection.checkIntersection3D(mesh.getAABB(), lP)) { return mesh; } final WB_AABBTree tree = new WB_AABBTree(mesh, 64); final HE_Selection faces = new HE_Selection(mesh); faces.addFaces(HE_Intersection.getPotentialIntersectedFaces(tree, lP)); faces.collectVertices(); faces.collectEdgesByFace(); WB_Classification tmp; final HashMap<Long, WB_Classification> vertexClass = new HashMap<Long, WB_Classification>(); HE_Vertex v; final Iterator<HE_Vertex> vItr = faces.vItr(); while (vItr.hasNext()) { v = vItr.next(); tmp = lP.classifyPointToPlane(v); vertexClass.put(v.key(), tmp); } List<HE_Vertex> faceVertices = new ArrayList<HE_Vertex>(); final HE_Selection split = new HE_Selection(mesh); final FastMap<Long, Double> edgeInt = new FastMap<Long, Double>(); final Iterator<HE_Halfedge> eItr = faces.eItr(); HE_Halfedge e; while (eItr.hasNext()) { e = eItr.next(); if (vertexClass.get(e.getStartVertex().key()) == WB_Classification.ON) { if (vertexClass.get(e.getEndVertex().key()) == WB_Classification.ON) { cutEdges.add(e); e.setInternalLabel(1); e.getPair().setInternalLabel(1); } else { edgeInt.put(e.key(), 0.0); } } else if (vertexClass.get(e.getStartVertex().key()) == WB_Classification.BACK) { if (vertexClass.get(e.getEndVertex().key()) == WB_Classification.ON) { edgeInt.put(e.key(), 1.0); } else if (vertexClass.get(e.getEndVertex().key()) == WB_Classification.FRONT) { edgeInt.put(e.key(), HE_Intersection.getIntersection(e, lP)); } } else { if (vertexClass.get(e.getEndVertex().key()) == WB_Classification.ON) { edgeInt.put(e.key(), 1.0); } else if (vertexClass.get(e.getEndVertex().key()) == WB_Classification.BACK) { edgeInt.put(e.key(), HE_Intersection.getIntersection(e, lP)); } } } for (final Map.Entry<Long, Double> en : edgeInt.entrySet()) { final HE_Halfedge ce = mesh.getHalfedgeByKey(en.getKey()); final double u = en.getValue(); if (ce.getFace() != null) { split.add(ce.getFace()); } if (ce.getPair().getFace() != null) { split.add(ce.getPair().getFace()); } if (u == 0.0) { split.add(ce.getStartVertex()); } else if (u == 1.0) { split.add(ce.getEndVertex()); } else { split.add(mesh.splitEdge(ce, u).vItr().next()); } } HE_Face f; final Iterator<HE_Face> fItr = split.fItr(); while (fItr.hasNext()) { f = fItr.next(); faceVertices = f.getFaceVertices(); int firstVertex = -1; int secondVertex = -1; final int n = faceVertices.size(); for (int j = 0; j < n; j++) { v = faceVertices.get(j); if (split.contains(v)) { if (firstVertex == -1) { firstVertex = j; j++; // if one cut point is found, skip next point. // There should be at least one other vertex in // between for a proper cut. } else { secondVertex = j; break; } } } if ((firstVertex != -1) && (secondVertex != -1)) { cut.add(f); final HE_Selection out = mesh.splitFace(f, faceVertices.get(firstVertex), faceVertices.get(secondVertex)); final HE_Face nf = out.fItr().next(); cut.add(nf); final HE_Halfedge ne = out.eItr().next(); ne.setInternalLabel(1); cutEdges.add(ne); } } return mesh; }