private List <Vector3> GetHoleLoop(MeshInfo m1, MeshInfo m2, List <Vector3> vertices, ref List <Vector3> usedVertices, ref List <EdgeIntersect> intersections) { List <Vector3> holeLoop = new List <Vector3>(); EdgeInfo e = m1.OuterEdges[intersections[0].edge1]; Vector3 firstV = m1.Vertices[e.v1]; int startIdx = e.v1; int edgeIdx = intersections[0].edge1; if (vertices.Contains(firstV) || usedVertices.Contains(firstV)) { firstV = m1.Vertices[e.v2]; startIdx = e.v2; } holeLoop.Add(firstV); usedVertices.Add(firstV); bool done = false; bool onFirstMesh = true; MeshInfo m = onFirstMesh ? m1 : m2; EdgeInfo lastEdge = m1.OuterEdges.Find(x => x.v1 == startIdx); int lastEdgeIdx = m1.OuterEdges.FindIndex(x => x == lastEdge); while (!done) { Vector3 newV = Vector3.zero; EdgeIntersect intersect = new EdgeIntersect(); if (GetClosestIntersect(holeLoop[holeLoop.Count - 1], intersections, e, m1, m2, onFirstMesh, out intersect, false, true)) { newV = intersect.intersectionPoint; intersections.Remove(intersect); // Flip onFirstMesh = !onFirstMesh; edgeIdx = onFirstMesh ? intersect.edge1 : intersect.edge2; m = onFirstMesh ? m1 : m2; e = m.OuterEdges[edgeIdx]; } else { if (m.Vertices[e.v1] != holeLoop[0]) { newV = m.Vertices[e.v1]; } edgeIdx--; if (edgeIdx < 0) { edgeIdx = m.OuterEdges.Count - 1; } e = m.OuterEdges[edgeIdx]; } holeLoop.Add(newV); usedVertices.Add(newV); if (!done) { done = (e.v2 == startIdx && onFirstMesh && !intersections.Exists(x => x.edge1 == edgeIdx || x.edge1 == lastEdgeIdx)) || (holeLoop.Last() == m1.Vertices[startIdx] && holeLoop.Count != 1); } } return(holeLoop); }
private bool GetClosestIntersect(Vector3 lastPoint, List <EdgeIntersect> intersections, EdgeInfo e, MeshInfo m1, MeshInfo m2, bool onFirstMesh, out EdgeIntersect intersect, bool debug = false, bool reverse = false) { intersect = new EdgeIntersect(); List <EdgeIntersect> intersects = new List <EdgeIntersect>(); MeshInfo m = m1; if (onFirstMesh) { m = m1; intersects = intersections.FindAll(x => m1.OuterEdges[x.edge1] == e); } else { m = m2; intersects = intersections.FindAll(x => m2.OuterEdges[x.edge2] == e); } if (intersects.Count == 0) { return(false); } // Get direction of the edge Vector3 edge_p1 = m.Vertices[e.v1]; Vector3 edge_p2 = m.Vertices[e.v2]; Vector3 edgeDirection = Vector3.zero; if (reverse) { edgeDirection = (edge_p1 - edge_p2).normalized; } else { edgeDirection = (edge_p2 - edge_p1).normalized; } if (debug) { InSceneDebugTool.Instance.DrawPoint(edge_p1, Color.red, .3f); InSceneDebugTool.Instance.DrawPoint(edge_p2, Color.blue, .4f); } float minDist = float.MaxValue; if (intersects.Count == 1) { intersect = intersects[0]; Vector3 newPointDirection = (intersect.intersectionPoint - lastPoint).normalized; // Same direction/not opposite direction if (Vector3.Dot(newPointDirection, edgeDirection) > 0) { return(true); } else { return(false); } } else { foreach (EdgeIntersect eI in intersects) { Vector3 intersectionPoint = new Vector3(); Vector3 p1 = m1.Vertices[m1.OuterEdges[eI.edge1].v1]; Vector3 p2 = m1.Vertices[m1.OuterEdges[eI.edge1].v2]; Vector3 p3 = m2.Vertices[m2.OuterEdges[eI.edge2].v1]; Vector3 p4 = m2.Vertices[m2.OuterEdges[eI.edge2].v2]; Utils.SegmentIntersect(p1, p2, p3, p4, out intersectionPoint); // Check if in correct direction Vector3 newPointDirection = (intersectionPoint - lastPoint).normalized; if (Vector3.Dot(newPointDirection, edgeDirection) > 0) { // Same direction if dot is positive if (Vector3.Distance(intersectionPoint, lastPoint) < minDist) { minDist = Vector3.Distance(intersectionPoint, lastPoint); intersect = eI; } } } } if (minDist == float.MaxValue) { return(false); } return(true); }
private List <Vector3> GetOuterVertices(MeshInfo m1, MeshInfo m2, ref List <EdgeIntersect> intersections, ref Dictionary <MeshInfo, List <int> > sharedPointsDict) { // Find a starting point, only requirement is that it lies outside of m2 int startIndex = 0; while (Utils.PointInPolygon(m1.Vertices[startIndex], m2)) { startIndex++; if (startIndex >= m1.Vertices.Count) { AllMeshes.Remove(m1); return(new List <Vector3>()); } } // Initialiazing variable bool onFirstMesh = true; EdgeInfo edge = m1.OuterEdges.Find(x => x.v1 == startIndex); int edgeIdx = m1.OuterEdges.FindIndex(x => x == edge); List <Vector3> vertices = new List <Vector3>(); // Add first point vertices.Add(m1.Vertices[startIndex]); EdgeInfo lastEdge = m1.OuterEdges.Find(x => x.v2 == startIndex); int lastEdgeIdx = m1.OuterEdges.FindIndex(x => x == lastEdge); MeshInfo m = onFirstMesh ? m1 : m2; // If the first point is a shared point, we need to select the correct edge before entering the while loop if (sharedPointsDict[m1].Contains(startIndex)) { (onFirstMesh, edgeIdx) = ClosestEdgeFromSharedPoint(m1.OuterEdges, m2.OuterEdges, m1.OuterEdges.Find(x => x.v2 == startIndex), m1, m2, onFirstMesh); m = onFirstMesh ? m1 : m2; edge = m.OuterEdges[edgeIdx]; } // Walk over the edges untill an intersection is found, in which case we swap mesh. Keep going till we are back bool done = false; Vector2 prevDir = Vector2.zero; while (!done) { Vector3 newV = Vector3.zero; EdgeIntersect intersect = new EdgeIntersect(); if (sharedPointsDict[m].Contains(edge.v2)) { newV = m.Vertices[edge.v2]; (onFirstMesh, edgeIdx) = ClosestEdgeFromSharedPoint(m1.OuterEdges, m2.OuterEdges, edge, m1, m2, onFirstMesh); m = onFirstMesh ? m1 : m2; edge = m.OuterEdges[edgeIdx]; } else { if (GetClosestIntersect(vertices[vertices.Count - 1], intersections, edge, m1, m2, onFirstMesh, out intersect)) { newV = intersect.intersectionPoint; intersections.Remove(intersect); // Flip onFirstMesh = !onFirstMesh; edgeIdx = onFirstMesh ? intersect.edge1 : intersect.edge2; m = onFirstMesh ? m1 : m2; edge = m.OuterEdges[edgeIdx]; } else { if (m.Vertices[edge.v2] != vertices[0]) { newV = m.Vertices[edge.v2]; } edgeIdx++; if (edgeIdx >= m.OuterEdges.Count) { edgeIdx = 0; } edge = m.OuterEdges[edgeIdx]; } } if (newV != Vector3.zero) { Vector2 sndPoint = Utils.Vector2FromVector3(m.Vertices[edge.v2]); Vector2 newDir = (Utils.Vector2FromVector3(newV) - sndPoint).normalized; if (prevDir == Vector2.zero) { prevDir = (Utils.Vector2FromVector3(vertices.Last()) - Utils.Vector2FromVector3(newV)).normalized; } if (prevDir != newDir) { if (newV != m1.Vertices[startIndex]) { vertices.Add(newV); } else { done = true; } } prevDir = newDir; } if (!done) { done = (edge.v1 == startIndex && onFirstMesh && !intersections.Exists(x => x.edge1 == edgeIdx || x.edge1 == lastEdgeIdx)) || (vertices.Last() == m1.Vertices[startIndex] && vertices.Count != 1); } } return(vertices); }