public void InstantiateLatches(Manifold manifold, FaceHandleController handleController) { var neighbourFaces = manifold.GetAdjacentFaceIdsAndEdgeCenters(handleController.AssociatedFaceID); var edgeCenters = neighbourFaces.edgeCenter; for (int j = 0; j < neighbourFaces.edgeId.Length; j++) { var adjacentFace = neighbourFaces.faceId[j]; int uniqueHalfedgeId = Mathf.Max(manifold.GetOppHalfEdge(neighbourFaces.edgeId[j]), neighbourFaces.edgeId[j]); EdgeHandleController existingEdgeHandle = null; var latchExists = _edgeHandles.TryGetValue(uniqueHalfedgeId, out existingEdgeHandle); if (latchExists) { handleController.AttachLatch(existingEdgeHandle); } else { var newLatch = Instantiate(LatchPrefab, transform, false); //newLatch.transform.localScale = Vector3.Scale(transform.lossyScale, newLatch.transform.localScale); newLatch.transform.SetParent(transform); var edgeCenter = edgeCenters[j]; var edgeHandleController = newLatch.GetComponent <EdgeHandleController>(); var adjacentFaceNormal = manifold.GetFaceNormal(adjacentFace); var normal = manifold.GetFaceNormal(handleController.AssociatedFaceID); edgeHandleController.UpdatePositionAndRotation(edgeCenter, neighbourFaces.edgeNormals[j], adjacentFaceNormal + normal); edgeHandleController.FirstFace = handleController.AssociatedFaceID; edgeHandleController.SecondFace = adjacentFace; // always use max halfedge id - to uniquely identify halfedge edgeHandleController.AssociatedEdgeID = uniqueHalfedgeId; KeyValuePair <int, int> pairToRemove = new KeyValuePair <int, int>(); foreach (var pair in _closedEdgeBackup) { if (edgeHandleController.IsAdjacent(pair.Key, pair.Value)) { pairToRemove = pair; edgeHandleController.Locked = true; break; } } _closedEdgeBackup.Remove(pairToRemove); handleController.AttachLatch(edgeHandleController); _edgeHandles.Add(edgeHandleController.AssociatedEdgeID, edgeHandleController); } } }
public bool ValidateFaceLoop(int halfedgeId1, int halfedgeId2) { Manifold manifold = _extrudableMesh._manifold; //if (manifold.GetIncidentFace(halfedgeId1) == manifold.GetIncidentFace(halfedgeId2)) //{ // return false; //} if (!manifold.IsHalfedgeInUse(halfedgeId1) || !manifold.IsHalfedgeInUse(halfedgeId2)) { return(false); } int f = manifold.GetIncidentFace(halfedgeId1); int h = halfedgeId1; while (true) { int h2 = manifold.GetNextHalfEdge(h); h2 = manifold.GetNextHalfEdge(h2); int h3 = manifold.GetOppHalfEdge(h2); if (h2 == halfedgeId2 || h3 == halfedgeId2) { return(true); } else if (manifold.GetIncidentFace(h3) == f) { return(false); } h = h3; } }
public void DestroyInvalidObjects() { Manifold manifold = Extrudable._manifold; var toDeleteV = new List <int>(_vertexHandles.Keys).FindAll(key => !manifold.IsVertexInUse(key)); foreach (var v in toDeleteV) { var obj = _vertexHandles[v]; _vertexHandles.Remove(v); Destroy(obj.gameObject); } var toDeleteF = new List <int>(_faceHandles.Keys).FindAll(key => !manifold.IsFaceInUse(key)); foreach (var f in toDeleteF) { var obj = _faceHandles[f]; _faceHandles.Remove(f); Destroy(obj.gameObject); } var toDeleteE = new List <int>(_edgeHandles.Keys).FindAll(key => !manifold.IsHalfedgeInUse(key) || key < manifold.GetOppHalfEdge(key)); foreach (var e in toDeleteE) { var obj = _edgeHandles[e]; var faces = new[] { obj.FirstFace, obj.SecondFace }; foreach (var face in faces) { FaceHandleController fhc; if (_faceHandles.TryGetValue(face, out fhc)) { fhc.ConnectedLatches.Remove(obj); } } _edgeHandles.Remove(e); Destroy(obj.gameObject); } // Brute force delete all edge controllers every cleanup, might not be effecient but circumvents bug that doesn't remove all invalid edgecontrollers. int[] ekeys = _edgeHandles.Keys.ToArray(); foreach (int key in ekeys) { var obj = _edgeHandles[key]; if (!obj.Locked) { } _edgeHandles.Remove(key); Destroy(obj.gameObject); } int[] fkeys = _faceHandles.Keys.ToArray(); foreach (int key in fkeys) { var obj = _faceHandles[key]; _faceHandles.Remove(key); Destroy(obj.gameObject); } int[] vkeys = _vertexHandles.Keys.ToArray(); foreach (int key in vkeys) { var obj = _vertexHandles[key]; _vertexHandles.Remove(key); Destroy(obj.gameObject); } }
public bool RefinementTestLoop(int halfedge1, int halfedge2) { if (!ValidateFaceLoop(halfedge1, halfedge2)) { return(false); } ExtrudableMesh _extrudableMesh = modellingObject.GetComponentInChildren <ExtrudableMesh>(); Manifold manifold = _extrudableMesh._manifold; int h = halfedge1; int initital_f = manifold.GetIncidentFace(halfedge1); int f = initital_f; List <int> faceloop = new List <int>(); List <int> edgeloop = new List <int>(); while (true) { if (manifold.IsFaceInUse(f)) { if (manifold.IsHalfedgeInUse(h)) { int h2 = manifold.GetNextHalfEdge(h); h2 = manifold.GetNextHalfEdge(h2); if (manifold.IsHalfedgeInUse(h2)) { int w = manifold.SplitEdge(h); edgeloop.Add(w); faceloop.Add(f); h = manifold.GetOppHalfEdge(h2); f = manifold.GetIncidentFace(h); if (f == initital_f) { int[] farray = faceloop.ToArray(); int[] earray = edgeloop.ToArray(); for (int i = 0; i < farray.Length; i++) { if (i == farray.Length - 1) { int output = manifold.SplitFaceByEdges(farray[i], earray[i], earray[0]); // earray[1]); } else { int output = manifold.SplitFaceByEdges(farray[i], earray[i], earray[i + 1]); } } _extrudableMesh.UpdateMesh(); return(true); } } else { return(false); } } else { return(false); } } else { return(false); } } }