private static boolean step(int faceIndex) {
		Triangle t = faces.get(faceIndex);
		// 2. Get most distant point of the face's point set
		Vector3f furthestPoint = null;
		int furthestPointID = -1;
		Vector3f A = vertices.get(t.a);
		List<Vector3f> facepoints = listsOfFacePoints.get(faceIndex);
		float distance = 0;
		for (int i = 0; i < facepoints.size(); i++) {
			Vector3f P = facepoints.get(i);
			float dist = VecMath.dotproduct(VecMath.subtraction(P, A, tmpvec), t.normal);
			if (dist >= distance) {
				distance = dist;
				furthestPoint = P;
				furthestPointID = i;
			}
		}
		if (furthestPointID == -1 || vertices.contains(furthestPoint)) { // TODO: check
			return true;
		}
		facepoints.remove(furthestPointID);
		vertices.add(furthestPoint);
		furthestPointID = vertices.size() - 1;
		lastremovedTriangles.clear();
		lastremovedTriangles.add(faces.remove(faceIndex));
		listsOfFacePoints.remove(faceIndex);
		// 3. Find all faces that can be seen from this point
		HashSet<Integer> lightFaceVertices = new HashSet<Integer>(); // HAS TO BE REINITIALIZED... don't ask why.
		lightFaceVertices.add(t.a);
		lightFaceVertices.add(t.b);
		lightFaceVertices.add(t.c);
		List<Triangle> vertsA = new ArrayList<Triangle>();
		List<Triangle> vertsB = new ArrayList<Triangle>();
		List<Triangle> vertsC = new ArrayList<Triangle>();
		vertsA.add(t);
		vertsB.add(t);
		vertsC.add(t);
		lightFaceVerticesToTriangles.clear();
		lightFaceVerticesToTriangles.put(t.a, vertsA);
		lightFaceVerticesToTriangles.put(t.b, vertsB);
		lightFaceVerticesToTriangles.put(t.c, vertsC);
		for (int i = faces.size() - 1; i >= 0; i--) {
			Triangle tri = faces.get(i);
			Vector3f triA = vertices.get(tri.a);
			if (VecMath.dotproduct(tri.normal, VecMath.subtraction(furthestPoint, triA, tmpvec)) > 0) {
				lastremovedTriangles.add(faces.remove(i));
				lightFaceVertices.add(tri.a);
				lightFaceVertices.add(tri.b);
				lightFaceVertices.add(tri.c);
				if ((vertsA = lightFaceVerticesToTriangles.get(tri.a)) != null) {
					vertsA.add(tri);
				} else {
					vertsA = new ArrayList<Triangle>();
					vertsA.add(tri);
					lightFaceVerticesToTriangles.put(tri.a, vertsA);
				}
				if ((vertsB = lightFaceVerticesToTriangles.get(tri.b)) != null) {
					vertsB.add(tri);
				} else {
					vertsB = new ArrayList<Triangle>();
					vertsB.add(tri);
					lightFaceVerticesToTriangles.put(tri.b, vertsB);
				}
				if ((vertsC = lightFaceVerticesToTriangles.get(tri.c)) != null) {
					vertsC.add(tri);
				} else {
					vertsC = new ArrayList<Triangle>();
					vertsC.add(tri);
					lightFaceVerticesToTriangles.put(tri.c, vertsC);
				}
				facepoints.addAll(listsOfFacePoints.remove(i));
			}
		}
		// 4.0 Remove all vertices that are only connected to lightFaceVertices
		Iterator<Integer> iter = lightFaceVertices.iterator();
		toRemove.clear();
		for (int i = 0; i < lightFaceVertices.size(); i++) {
			int vert = iter.next(); // TODO: check
			if (lightFaceVerticesToTriangles.get(vert).size() == adjacentsMap.get(vert).size()) {
				toRemove.add(vert);
			}
		}
		for (Integer i : toRemove) {
			for (Integer adj : adjacentsMap.get(i)) {
				adjacentsMap.get(adj).remove(i);
				tmppair.set(i, adj);
				edgesToTriangles.remove(tmppair);
			}
			lightFaceVertices.remove((int) i);
			vertices.set((int) i, null);
			freeVertexPositions.add(i);
		}
		// 4.1 Get vertices on border between lit and unlit triangles
		HashSet<Integer> vertsOnEdge = new HashSet<Integer>(); // HAS TO BE REINITIALIZED
		for (Integer vert : lightFaceVertices) {
			vertsOnEdge.add(vert);
		}
		// 4.2 Get edges on border
		int currentVert = vertsOnEdge.iterator().next();
		edge.clear(); // TODO: make HashSet (no! has to be ordered list!)
		for (int i = 0; i < vertsOnEdge.size(); i++) {
			edge.add(currentVert);
			ArrayList<Integer> adjs = adjacentsMap.get(currentVert);
			List<Triangle> vertexLightTriangles = lightFaceVerticesToTriangles.get(currentVert);
			for (int j = 0; j < adjs.size(); j++) {
				Integer currAdj = adjs.get(j);
				if (vertsOnEdge.contains(currAdj) && !edge.contains(currAdj)) {
					int tricount = 0;
					for (int k = 0; k < vertexLightTriangles.size() && tricount < 2; k++) {
						Triangle kTri = vertexLightTriangles.get(k);
						if (kTri.a == currAdj || kTri.b == currAdj || kTri.c == currAdj) {
							tricount++;
						}
					}
					if (tricount == 1) {
						currentVert = currAdj;
						break;
					}
				}
			}
		}
		// 4.2.1 remove old adjacents (crossing triangle hole)
		int edgesize = edge.size();
		int edgesizeMinusOne = edgesize - 1;
		for (int i = 0; i < edgesize; i++) {
			currentVert = edge.get(i);
			removeAdj.clear();
			for (Integer adj : adjacentsMap.get(currentVert)) {
				if (edge.contains(adj)) {
					int adjIndexOnEdge = edge.indexOf(adj);
					if (Math.abs(i - adjIndexOnEdge) > 1 && !(i == 0 && adjIndexOnEdge == edgesizeMinusOne)
							&& !(i == edgesizeMinusOne && adjIndexOnEdge == 0)) {
						tmppair.set(currentVert, adj);
						Pair<Triangle, Triangle> edgeTriangles = edgesToTriangles.get(tmppair);
						// TODO: performance
						if (lastremovedTriangles.contains(edgeTriangles.getFirst())
								&& lastremovedTriangles.contains(edgeTriangles.getSecond())) {
							removeAdj.add(adj);
							edgesToTriangles.remove(edgeTriangles);
						}
					}
				}
			}
			for (Integer removAdjacent : removeAdj) { // TODO: make faster
				adjacentsMap.get(currentVert).remove(removAdjacent);
			}
		}
		// 4.3 Stitch holes using edge
		newLightFaces.clear();
		ArrayList<Integer> furthestPointNeighbours = new ArrayList<Integer>(edge.size());
		A = vertices.get(edge.get(0));
		Vector3f B = vertices.get(edge.get(1));
		Vector3f C = vertices.get(edge.get(2));
		for (int i = 3; i < edge.size() && !linearIndependent(A, B, C); i++) {
			C = vertices.get(edge.get(i));
		}
		Vector3f normal = VecMath.computeNormal(A, B, C);
		boolean correctOrientation = VecMath.dotproduct(normal, VecMath.subtraction(A, furthestPoint, tmpvec)) < 0;
		int vertIDb = edge.get(0);
		for (int i = 0; i < edge.size(); i++) {
			int vertIDa = vertIDb;
			if (i < edge.size() - 1) {
				vertIDb = edge.get(i + 1);
			} else {
				vertIDb = edge.get(0);
			}
			Vector3f vA = vertices.get(vertIDa);
			Vector3f vB = vertices.get(vertIDb);
			Vector3f norm = VecMath.computeNormal(vA, vB, furthestPoint);
			Triangle stitchTriangle;
			if (correctOrientation) {
				stitchTriangle = new Triangle(vertIDa, vertIDb, furthestPointID, norm);
			} else {
				norm.negate();
				stitchTriangle = new Triangle(vertIDa, furthestPointID, vertIDb, norm);
			}
			faces.add(0, stitchTriangle);
			newLightFaces.add(stitchTriangle);
			// Update adjacents map
			adjacentsMap.get(vertIDa).add(furthestPointID);
			tmppair.set(vertIDa, vertIDb);
			Pair<Triangle, Triangle> oldEdgeInfo = edgesToTriangles.get(tmppair);
			// find out which triangle got deleted
			if (lastremovedTriangles.contains(oldEdgeInfo.getFirst())) {
				oldEdgeInfo.setFirst(stitchTriangle);
			} else {
				oldEdgeInfo.setSecond(stitchTriangle);
			}
			tmppair.set(vertIDa, furthestPointID);
			oldEdgeInfo = edgesToTriangles.get(tmppair);
			if (oldEdgeInfo != null) {
				oldEdgeInfo.setSecond(stitchTriangle);
			} else {
				// TODO: just relevant for first iteration, move before loop
				edgesToTriangles.put(new Pair<Integer, Integer>(vertIDa, furthestPointID),
						new Pair<Triangle, Triangle>(null, stitchTriangle));
			}
			tmppair.set(vertIDb, furthestPointID);
			oldEdgeInfo = edgesToTriangles.get(tmppair);
			if (oldEdgeInfo != null) {
				// TODO: just relevant for last iteration
				oldEdgeInfo.setFirst(stitchTriangle);
			} else {
				edgesToTriangles.put(new Pair<Integer, Integer>(vertIDb, furthestPointID),
						new Pair<Triangle, Triangle>(stitchTriangle, null));
			}
			furthestPointNeighbours.add(vertIDa);
		}
		// 5. Assign all points of all light-faces to the new created faces
		adjacentsMap.put(furthestPointID, furthestPointNeighbours);
		for (Triangle tri : newLightFaces) {
			listsOfFacePoints.add(0, getLightPoints(tri, facepoints));
		}
		// 6. Push new created faces on the stack and start at (1))
		return false;
	}
private static boolean step(int faceIndex) {
		Triangle t = faces.get(faceIndex);
	
		Vector3f furthestPoint = null;
		int furthestPointID = -1;
		Vector3f A = vertices.get(t.a);
		List<Vector3f> facepoints = listsOfFacePoints.get(faceIndex);
		float distance = 0;
		for (int i = 0; i < facepoints.size(); i++) {
			Vector3f P = facepoints.get(i);
			float dist = VecMath.dotproduct(VecMath.subtraction(P, A, tmpvec), t.normal);
			if (dist >= distance) {
				distance = dist;
				furthestPoint = P;
				furthestPointID = i;
			}
		}
		if (furthestPointID == -1 || vertices.contains(furthestPoint)) {
			return true;
		}
		facepoints.remove(furthestPointID);
		vertices.add(furthestPoint);
		furthestPointID = vertices.size() - 1;
		lastremovedTriangles.clear();
		lastremovedTriangles.add(faces.remove(faceIndex));
		listsOfFacePoints.remove(faceIndex);
	
		HashSet<Integer> lightFaceVertices = new HashSet<Integer>();
		lightFaceVertices.add(t.a);
		lightFaceVertices.add(t.b);
		lightFaceVertices.add(t.c);
		List<Triangle> vertsA = new ArrayList<Triangle>();
		List<Triangle> vertsB = new ArrayList<Triangle>();
		List<Triangle> vertsC = new ArrayList<Triangle>();
		vertsA.add(t);
		vertsB.add(t);
		vertsC.add(t);
		lightFaceVerticesToTriangles.clear();
		lightFaceVerticesToTriangles.put(t.a, vertsA);
		lightFaceVerticesToTriangles.put(t.b, vertsB);
		lightFaceVerticesToTriangles.put(t.c, vertsC);
		for (int i = faces.size() - 1; i >= 0; i--) {
			Triangle tri = faces.get(i);
			Vector3f triA = vertices.get(tri.a);
			if (VecMath.dotproduct(tri.normal, VecMath.subtraction(furthestPoint, triA, tmpvec)) > 0) {
				lastremovedTriangles.add(faces.remove(i));
				lightFaceVertices.add(tri.a);
				lightFaceVertices.add(tri.b);
				lightFaceVertices.add(tri.c);
				if ((vertsA = lightFaceVerticesToTriangles.get(tri.a)) != null) {
					vertsA.add(tri);
				} else {
					vertsA = new ArrayList<Triangle>();
					vertsA.add(tri);
					lightFaceVerticesToTriangles.put(tri.a, vertsA);
				}
				if ((vertsB = lightFaceVerticesToTriangles.get(tri.b)) != null) {
					vertsB.add(tri);
				} else {
					vertsB = new ArrayList<Triangle>();
					vertsB.add(tri);
					lightFaceVerticesToTriangles.put(tri.b, vertsB);
				}
				if ((vertsC = lightFaceVerticesToTriangles.get(tri.c)) != null) {
					vertsC.add(tri);
				} else {
					vertsC = new ArrayList<Triangle>();
					vertsC.add(tri);
					lightFaceVerticesToTriangles.put(tri.c, vertsC);
				}
				facepoints.addAll(listsOfFacePoints.remove(i));
			}
		}
	
		Iterator<Integer> iter = lightFaceVertices.iterator();
		toRemove.clear();
		for (int i = 0; i < lightFaceVertices.size(); i++) {
			int vert = iter.next();
			if (lightFaceVerticesToTriangles.get(vert).size() == adjacentsMap.get(vert).size()) {
				toRemove.add(vert);
			}
		}
		for (Integer i : toRemove) {
			for (Integer adj : adjacentsMap.get(i)) {
				adjacentsMap.get(adj).remove(i);
				tmppair.set(i, adj);
				edgesToTriangles.remove(tmppair);
			}
			lightFaceVertices.remove((int) i);
			vertices.set((int) i, null);
			freeVertexPositions.add(i);
		}
	
		HashSet<Integer> vertsOnEdge = new HashSet<Integer>();
		for (Integer vert : lightFaceVertices) {
			vertsOnEdge.add(vert);
		}
	
		int currentVert = vertsOnEdge.iterator().next();
		edge.clear();
		for (int i = 0; i < vertsOnEdge.size(); i++) {
			edge.add(currentVert);
			ArrayList<Integer> adjs = adjacentsMap.get(currentVert);
			List<Triangle> vertexLightTriangles = lightFaceVerticesToTriangles.get(currentVert);
			for (int j = 0; j < adjs.size(); j++) {
				Integer currAdj = adjs.get(j);
				if (vertsOnEdge.contains(currAdj) && !edge.contains(currAdj)) {
					int tricount = 0;
					for (int k = 0; k < vertexLightTriangles.size() && tricount < 2; k++) {
						Triangle kTri = vertexLightTriangles.get(k);
						if (kTri.a == currAdj || kTri.b == currAdj || kTri.c == currAdj) {
							tricount++;
						}
					}
					if (tricount == 1) {
						currentVert = currAdj;
						break;
					}
				}
			}
		}
	
		int edgesize = edge.size();
		int edgesizeMinusOne = edgesize - 1;
		for (int i = 0; i < edgesize; i++) {
			currentVert = edge.get(i);
			removeAdj.clear();
			for (Integer adj : adjacentsMap.get(currentVert)) {
				if (edge.contains(adj)) {
					int adjIndexOnEdge = edge.indexOf(adj);
					if (Math.abs(i - adjIndexOnEdge) > 1 && !(i == 0 && adjIndexOnEdge == edgesizeMinusOne)
							&& !(i == edgesizeMinusOne && adjIndexOnEdge == 0)) {
						tmppair.set(currentVert, adj);
						Pair<Triangle, Triangle> edgeTriangles = edgesToTriangles.get(tmppair);
					
						if (lastremovedTriangles.contains(edgeTriangles.getFirst())
								&& lastremovedTriangles.contains(edgeTriangles.getSecond())) {
							removeAdj.add(adj);
							edgesToTriangles.remove(edgeTriangles);
						}
					}
				}
			}
			for (Integer removAdjacent : removeAdj) {
				adjacentsMap.get(currentVert).remove(removAdjacent);
			}
		}
	
		newLightFaces.clear();
		ArrayList<Integer> furthestPointNeighbours = new ArrayList<Integer>(edge.size());
		A = vertices.get(edge.get(0));
		Vector3f B = vertices.get(edge.get(1));
		Vector3f C = vertices.get(edge.get(2));
		for (int i = 3; i < edge.size() && !linearIndependent(A, B, C); i++) {
			C = vertices.get(edge.get(i));
		}
		Vector3f normal = VecMath.computeNormal(A, B, C);
		boolean correctOrientation = VecMath.dotproduct(normal, VecMath.subtraction(A, furthestPoint, tmpvec)) < 0;
		int vertIDb = edge.get(0);
		for (int i = 0; i < edge.size(); i++) {
			int vertIDa = vertIDb;
			if (i < edge.size() - 1) {
				vertIDb = edge.get(i + 1);
			} else {
				vertIDb = edge.get(0);
			}
			Vector3f vA = vertices.get(vertIDa);
			Vector3f vB = vertices.get(vertIDb);
			Vector3f norm = VecMath.computeNormal(vA, vB, furthestPoint);
			Triangle stitchTriangle;
			if (correctOrientation) {
				stitchTriangle = new Triangle(vertIDa, vertIDb, furthestPointID, norm);
			} else {
				norm.negate();
				stitchTriangle = new Triangle(vertIDa, furthestPointID, vertIDb, norm);
			}
			faces.add(0, stitchTriangle);
			newLightFaces.add(stitchTriangle);
		
			adjacentsMap.get(vertIDa).add(furthestPointID);
			tmppair.set(vertIDa, vertIDb);
			Pair<Triangle, Triangle> oldEdgeInfo = edgesToTriangles.get(tmppair);
		
			if (lastremovedTriangles.contains(oldEdgeInfo.getFirst())) {
				oldEdgeInfo.setFirst(stitchTriangle);
			} else {
				oldEdgeInfo.setSecond(stitchTriangle);
			}
			tmppair.set(vertIDa, furthestPointID);
			oldEdgeInfo = edgesToTriangles.get(tmppair);
			if (oldEdgeInfo != null) {
				oldEdgeInfo.setSecond(stitchTriangle);
			} else {
			
				edgesToTriangles.put(new Pair<Integer, Integer>(vertIDa, furthestPointID),
						new Pair<Triangle, Triangle>(null, stitchTriangle));
			}
			tmppair.set(vertIDb, furthestPointID);
			oldEdgeInfo = edgesToTriangles.get(tmppair);
			if (oldEdgeInfo != null) {
			
				oldEdgeInfo.setFirst(stitchTriangle);
			} else {
				edgesToTriangles.put(new Pair<Integer, Integer>(vertIDb, furthestPointID),
						new Pair<Triangle, Triangle>(stitchTriangle, null));
			}
			furthestPointNeighbours.add(vertIDa);
		}
	
		adjacentsMap.put(furthestPointID, furthestPointNeighbours);
		for (Triangle tri : newLightFaces) {
			listsOfFacePoints.add(0, getLightPoints(tri, facepoints));
		}
	
		return false;
	}
private static boolean step(int faceindex) { triangle t = faces.get(faceindex); vector3f furthestpoint = null; int furthestpointid = -1; vector3f a = vertices.get(t.a); list<vector3f> facepoints = listsoffacepoints.get(faceindex); float distance = 0; for (int i = 0; i < facepoints.size(); i++) { vector3f p = facepoints.get(i); float dist = vecmath.dotproduct(vecmath.subtraction(p, a, tmpvec), t.normal); if (dist >= distance) { distance = dist; furthestpoint = p; furthestpointid = i; } } if (furthestpointid == -1 || vertices.contains(furthestpoint)) { return true; } facepoints.remove(furthestpointid); vertices.add(furthestpoint); furthestpointid = vertices.size() - 1; lastremovedtriangles.clear(); lastremovedtriangles.add(faces.remove(faceindex)); listsoffacepoints.remove(faceindex); hashset<integer> lightfacevertices = new hashset<integer>(); lightfacevertices.add(t.a); lightfacevertices.add(t.b); lightfacevertices.add(t.c); list<triangle> vertsa = new arraylist<triangle>(); list<triangle> vertsb = new arraylist<triangle>(); list<triangle> vertsc = new arraylist<triangle>(); vertsa.add(t); vertsb.add(t); vertsc.add(t); lightfaceverticestotriangles.clear(); lightfaceverticestotriangles.put(t.a, vertsa); lightfaceverticestotriangles.put(t.b, vertsb); lightfaceverticestotriangles.put(t.c, vertsc); for (int i = faces.size() - 1; i >= 0; i--) { triangle tri = faces.get(i); vector3f tria = vertices.get(tri.a); if (vecmath.dotproduct(tri.normal, vecmath.subtraction(furthestpoint, tria, tmpvec)) > 0) { lastremovedtriangles.add(faces.remove(i)); lightfacevertices.add(tri.a); lightfacevertices.add(tri.b); lightfacevertices.add(tri.c); if ((vertsa = lightfaceverticestotriangles.get(tri.a)) != null) { vertsa.add(tri); } else { vertsa = new arraylist<triangle>(); vertsa.add(tri); lightfaceverticestotriangles.put(tri.a, vertsa); } if ((vertsb = lightfaceverticestotriangles.get(tri.b)) != null) { vertsb.add(tri); } else { vertsb = new arraylist<triangle>(); vertsb.add(tri); lightfaceverticestotriangles.put(tri.b, vertsb); } if ((vertsc = lightfaceverticestotriangles.get(tri.c)) != null) { vertsc.add(tri); } else { vertsc = new arraylist<triangle>(); vertsc.add(tri); lightfaceverticestotriangles.put(tri.c, vertsc); } facepoints.addall(listsoffacepoints.remove(i)); } } iterator<integer> iter = lightfacevertices.iterator(); toremove.clear(); for (int i = 0; i < lightfacevertices.size(); i++) { int vert = iter.next(); if (lightfaceverticestotriangles.get(vert).size() == adjacentsmap.get(vert).size()) { toremove.add(vert); } } for (integer i : toremove) { for (integer adj : adjacentsmap.get(i)) { adjacentsmap.get(adj).remove(i); tmppair.set(i, adj); edgestotriangles.remove(tmppair); } lightfacevertices.remove((int) i); vertices.set((int) i, null); freevertexpositions.add(i); } hashset<integer> vertsonedge = new hashset<integer>(); for (integer vert : lightfacevertices) { vertsonedge.add(vert); } int currentvert = vertsonedge.iterator().next(); edge.clear(); for (int i = 0; i < vertsonedge.size(); i++) { edge.add(currentvert); arraylist<integer> adjs = adjacentsmap.get(currentvert); list<triangle> vertexlighttriangles = lightfaceverticestotriangles.get(currentvert); for (int j = 0; j < adjs.size(); j++) { integer curradj = adjs.get(j); if (vertsonedge.contains(curradj) && !edge.contains(curradj)) { int tricount = 0; for (int k = 0; k < vertexlighttriangles.size() && tricount < 2; k++) { triangle ktri = vertexlighttriangles.get(k); if (ktri.a == curradj || ktri.b == curradj || ktri.c == curradj) { tricount++; } } if (tricount == 1) { currentvert = curradj; break; } } } } int edgesize = edge.size(); int edgesizeminusone = edgesize - 1; for (int i = 0; i < edgesize; i++) { currentvert = edge.get(i); removeadj.clear(); for (integer adj : adjacentsmap.get(currentvert)) { if (edge.contains(adj)) { int adjindexonedge = edge.indexof(adj); if (math.abs(i - adjindexonedge) > 1 && !(i == 0 && adjindexonedge == edgesizeminusone) && !(i == edgesizeminusone && adjindexonedge == 0)) { tmppair.set(currentvert, adj); pair<triangle, triangle> edgetriangles = edgestotriangles.get(tmppair); if (lastremovedtriangles.contains(edgetriangles.getfirst()) && lastremovedtriangles.contains(edgetriangles.getsecond())) { removeadj.add(adj); edgestotriangles.remove(edgetriangles); } } } } for (integer removadjacent : removeadj) { adjacentsmap.get(currentvert).remove(removadjacent); } } newlightfaces.clear(); arraylist<integer> furthestpointneighbours = new arraylist<integer>(edge.size()); a = vertices.get(edge.get(0)); vector3f b = vertices.get(edge.get(1)); vector3f c = vertices.get(edge.get(2)); for (int i = 3; i < edge.size() && !linearindependent(a, b, c); i++) { c = vertices.get(edge.get(i)); } vector3f normal = vecmath.computenormal(a, b, c); boolean correctorientation = vecmath.dotproduct(normal, vecmath.subtraction(a, furthestpoint, tmpvec)) < 0; int vertidb = edge.get(0); for (int i = 0; i < edge.size(); i++) { int vertida = vertidb; if (i < edge.size() - 1) { vertidb = edge.get(i + 1); } else { vertidb = edge.get(0); } vector3f va = vertices.get(vertida); vector3f vb = vertices.get(vertidb); vector3f norm = vecmath.computenormal(va, vb, furthestpoint); triangle stitchtriangle; if (correctorientation) { stitchtriangle = new triangle(vertida, vertidb, furthestpointid, norm); } else { norm.negate(); stitchtriangle = new triangle(vertida, furthestpointid, vertidb, norm); } faces.add(0, stitchtriangle); newlightfaces.add(stitchtriangle); adjacentsmap.get(vertida).add(furthestpointid); tmppair.set(vertida, vertidb); pair<triangle, triangle> oldedgeinfo = edgestotriangles.get(tmppair); if (lastremovedtriangles.contains(oldedgeinfo.getfirst())) { oldedgeinfo.setfirst(stitchtriangle); } else { oldedgeinfo.setsecond(stitchtriangle); } tmppair.set(vertida, furthestpointid); oldedgeinfo = edgestotriangles.get(tmppair); if (oldedgeinfo != null) { oldedgeinfo.setsecond(stitchtriangle); } else { edgestotriangles.put(new pair<integer, integer>(vertida, furthestpointid), new pair<triangle, triangle>(null, stitchtriangle)); } tmppair.set(vertidb, furthestpointid); oldedgeinfo = edgestotriangles.get(tmppair); if (oldedgeinfo != null) { oldedgeinfo.setfirst(stitchtriangle); } else { edgestotriangles.put(new pair<integer, integer>(vertidb, furthestpointid), new pair<triangle, triangle>(stitchtriangle, null)); } furthestpointneighbours.add(vertida); } adjacentsmap.put(furthestpointid, furthestpointneighbours); for (triangle tri : newlightfaces) { listsoffacepoints.add(0, getlightpoints(tri, facepoints)); } return false; }