EdgeInfo _AddEdge(VertexInfo vertexa, VertexInfo vertexb) { string edgeString = EdgeInfo.GetEdgeString(vertexa.index, vertexb.index); EdgeInfo edge; if (!edges.ContainsKey(edgeString)) { edge = new EdgeInfo(); edge.vertexAIndex = vertexa.index; edge.vertexBIndex = vertexb.index; edge.belongToTriangleIndex = new List <int> (); edge.isConstraintEdge = false; edges [edgeString] = edge; } else { edge = edges[edgeString]; } if (vertexa.belongToEdgeIndex.Contains(edgeString) == false) { vertexa.belongToEdgeIndex.Add(edgeString); } if (vertexb.belongToEdgeIndex.Contains(edgeString) == false) { vertexb.belongToEdgeIndex.Add(edgeString); } return(edge); }
/*EdgeInfo AddEdge(VertexInfo vertexa, VertexInfo vertexb) * { * List<int> vertexaAdjancentVertices = vertexa.belongToEdgeIndex.Select (eIndex => edges [eIndex].GetOtherPoint (vertexa.index)).ToList(); * List<int> vertexbAdjancentVertices = vertexb.belongToEdgeIndex.Select (eIndex => edges [eIndex].GetOtherPoint (vertexb.index)).ToList(); * List<int> commonVertex = vertexaAdjancentVertices.Intersect (vertexbAdjancentVertices).ToList (); * if (commonVertex.Count > 0) { * foreach(int vIndex in commonVertex) * { * VertexInfo[] newTriangle = new VertexInfo[3]{vertexa, vertexb, vertices[vIndex]}; * AddTriangle(newTriangle); * } * return edges[EdgeInfo.GetEdgeString(vertexa.index, vertexb.index)]; * } else { * return _AddEdge(vertexa, vertexb); * } * }*/ string RemoveEdge(VertexInfo vertexa, VertexInfo vertexb) { string edgeString = EdgeInfo.GetEdgeString(vertexa.index, vertexb.index); if (edges.ContainsKey(edgeString)) { EdgeInfo edge = edges[edgeString]; List <int> belongToTriangleIndex = edge.belongToTriangleIndex; edge.belongToTriangleIndex = new List <int> (); for (int i = 0; i < belongToTriangleIndex.Count; i++) { int triangle = belongToTriangleIndex[i]; RemoveTriangle(triangles[triangle]); } vertexa.belongToEdgeIndex.Remove(edgeString); vertexb.belongToEdgeIndex.Remove(edgeString); edges.Remove(edgeString); } return(edgeString); }
public void Cut() { //initialize public variables vertices = new Dictionary <int, VertexInfo> (); edges = new Dictionary <string, EdgeInfo> (StringComparer.Ordinal); triangles = new Dictionary <int, TriangleInfo> (); //Get Cutplane Vector3 planeNormalInSubspace = victim.InverseTransformDirection(transform.forward); Vector3 planePosInSubspace = victim.InverseTransformPoint(transform.position); cutPlane = new Plane(planeNormalInSubspace, planePosInSubspace); //Get Mesh /*GameObject newMeshLeft = (GameObject)Instantiate (newMeshPrefab, victim.position, victim.rotation); * MeshFilter newMeshLeftFilter = newMeshLeft.GetComponent<MeshFilter> (); * List< TriangleInfo> leftTriangles = new List<TriangleInfo>(); * * GameObject newMeshRight = (GameObject)Instantiate (newMeshPrefab, victim.position, victim.rotation); * MeshFilter newMeshRightFilter = newMeshRight.GetComponent<MeshFilter> (); * List< TriangleInfo> rightTriangles = new List<TriangleInfo>();*/ //New Generated Points Dictionary <string, VertexInfo> newGeneratedPoints = new Dictionary <string, VertexInfo> (StringComparer.Ordinal); //Get Mesh Info Mesh _mesh = _meshFilter.mesh; int[] _triangles = _mesh.triangles; Vector3[] _vertices = _mesh.vertices; Vector3[] _normals = _mesh.normals; for (int i = 0; i < _vertices.Count(); i++) { AddVertex(_vertices [i], _normals[i]); } for (int i = 0; i *3 < _triangles.Length; i++) { VertexInfo[] verticesToBeAdd = new VertexInfo [3]; for (int j = 0; j < 3; j++) { verticesToBeAdd[j] = vertices[_triangles[i * 3 + j]]; } AddTriangle(verticesToBeAdd); } //Cut Mesh int triangleNum = triangles.Count; for (int i = 0; i < triangleNum; i++) { int inPositiveHalfSpaceNum = 0; int aPositiveVertexIndex = 0; int aNegativeVertexIndex = 0; TriangleInfo triangle = triangles[i]; for (int j = 0; j < 3; j++) { VertexInfo avertex = vertices[triangle.vertices[j]]; float distanceToPlane = cutPlane.GetDistanceToPoint(avertex.vertex); if (distanceToPlane > 0) { aPositiveVertexIndex = j; inPositiveHalfSpaceNum++; } else { aNegativeVertexIndex = j; } } if (inPositiveHalfSpaceNum == 3) { //leftTriangles.Add (triangle); } else if (inPositiveHalfSpaceNum == 2) { List <EdgeInfo> crossEdge = new List <EdgeInfo>(); for (int k = 0; k < 2; k++) { string edgeString = EdgeInfo.GetEdgeString(triangle.vertices[aNegativeVertexIndex], triangle.vertices[(aNegativeVertexIndex + 1 + k) % 3]); EdgeInfo edge = edges[edgeString]; if (!newGeneratedPoints.ContainsKey(edgeString)) { Vector3 breakPoint; Vector3 normal; FindContactPointAndNormalOnEdge(vertices[edge.vertexAIndex], vertices[edge.vertexBIndex], cutPlane, out breakPoint, out normal); VertexInfo vertex = AddVertex(breakPoint, normal); newGeneratedPoints[edgeString] = vertex; } crossEdge.Add(edge); } /*VertexInfo[] triangleA = new VertexInfo[3]{newGeneratedPoints[crossEdge[0].GetSelfEdgeString()], * vertices[crossEdge[0].GetOtherPoint(triangle.vertices[aNegativeVertexIndex])], * vertices[crossEdge[1].GetOtherPoint(triangle.vertices[aNegativeVertexIndex])]}; * * VertexInfo[] triangleB = new VertexInfo[3]{newGeneratedPoints[crossEdge[0].GetSelfEdgeString()], * vertices[crossEdge[1].GetOtherPoint(triangle.vertices[aNegativeVertexIndex])], * newGeneratedPoints[crossEdge[1].GetSelfEdgeString()]}; * * VertexInfo[] triangleC = new VertexInfo[3]{vertices[triangle.vertices[aNegativeVertexIndex]], * newGeneratedPoints[crossEdge[0].GetSelfEdgeString()], * newGeneratedPoints[crossEdge[1].GetSelfEdgeString()]}; * * leftTriangles.Add (AddTriangle(triangleA)); * leftTriangles.Add (AddTriangle(triangleB)); * rightTriangles.Add (AddTriangle(triangleC));*/ } else if (inPositiveHalfSpaceNum == 1) { List <EdgeInfo> crossEdge = new List <EdgeInfo>(); for (int k = 0; k < 2; k++) { string edgeString = EdgeInfo.GetEdgeString(triangle.vertices[aPositiveVertexIndex], triangle.vertices[(aPositiveVertexIndex + 1 + k) % 3]); EdgeInfo edge = edges[edgeString]; if (!newGeneratedPoints.ContainsKey(edgeString)) { Vector3 breakPoint; Vector3 normal; FindContactPointAndNormalOnEdge(vertices[edge.vertexAIndex], vertices[edge.vertexBIndex], cutPlane, out breakPoint, out normal); VertexInfo vertex = AddVertex(breakPoint, normal); newGeneratedPoints[edgeString] = vertex; } crossEdge.Add(edge); } /*VertexInfo[] triangleA = new VertexInfo[3]{newGeneratedPoints[crossEdge[0].GetSelfEdgeString()], * vertices[crossEdge[0].GetOtherPoint(triangle.vertices[aPositiveVertexIndex])], * vertices[crossEdge[1].GetOtherPoint(triangle.vertices[aPositiveVertexIndex])]}; * * VertexInfo[] triangleB = new VertexInfo[3]{newGeneratedPoints[crossEdge[0].GetSelfEdgeString()], * vertices[crossEdge[1].GetOtherPoint(triangle.vertices[aPositiveVertexIndex])], * newGeneratedPoints[crossEdge[1].GetSelfEdgeString()]}; * * * VertexInfo[] triangleC = new VertexInfo[3]{vertices[triangle.vertices[aPositiveVertexIndex]], * newGeneratedPoints[crossEdge[0].GetSelfEdgeString()], * newGeneratedPoints[crossEdge[1].GetSelfEdgeString()]}; * * rightTriangles.Add (AddTriangle(triangleA)); * rightTriangles.Add (AddTriangle(triangleB)); * leftTriangles.Add (AddTriangle(triangleC));*/ } else if (inPositiveHalfSpaceNum == 0) { //Whole triangle is culled by plane, just ignore this situation //rightTriangles.Add (triangle); } } //Cut mesh end //Add new face /*List<VertexInfo> newGenerateFaceContour = FindContourVertex (newGeneratedPoints.Values.ToList()); * for(int i = 0; i<newGenerateFaceContour.Count; i++) * { * Debug.DrawLine(newGenerateFaceContour[i].vertex, newGenerateFaceContour[(i+1)%(newGenerateFaceContour.Count)].vertex, Color.red, 1000); * }*/ FindContourMeshDelaunay(newGeneratedPoints.Values.ToList()); /* * List<VertexInfo> newGenerateFaceLeft = new List<VertexInfo> (); * List<VertexInfo> newGenerateFaceRight = new List<VertexInfo> (); * foreach (VertexInfo avertex in newGenerateFaceContour) { * newGenerateFaceLeft.Add (AddVertex (avertex.vertex, cutPlane.normal)); * newGenerateFaceRight.Add (AddVertex (avertex.vertex, -1*cutPlane.normal)); * } * if (newGenerateFaceContour.Count > 2) { * for(int i = 1; i<newGenerateFaceContour.Count -1; i++) * { * VertexInfo[] triangleLeft = new VertexInfo[3]{newGenerateFaceLeft[0], * newGenerateFaceLeft[i], * newGenerateFaceLeft[i+1]}; * * VertexInfo[] triangleRight = new VertexInfo[3]{newGenerateFaceRight[0], * newGenerateFaceRight[i+1], * newGenerateFaceRight[i]}; * * leftTriangles.Add (AddTriangle(triangleLeft)); * rightTriangles.Add (AddTriangle(triangleRight)); * } * } * * //Add new face end * * //re-assemble mesh * List<Vector3> leftVertices = new List<Vector3> (); * List<Vector3> leftNormals = new List<Vector3> (); * Dictionary<int, int> verticeIndexCorrespondingDict = new Dictionary<int, int> (); * List<int> leftTriangleIndex = new List<int> (); * for (int i = 0; i < leftTriangles.Count; i++) { * TriangleInfo triangle = leftTriangles[i]; * foreach(int vIndex in triangle.vertices) * { * VertexInfo vertexInfo = vertices[vIndex]; * if(!verticeIndexCorrespondingDict.ContainsKey(vertexInfo.index)) * { * verticeIndexCorrespondingDict.Add(vertexInfo.index, leftVertices.Count); * leftVertices.Add (vertexInfo.vertex); * leftNormals.Add (vertexInfo.normal); * } * leftTriangleIndex.Add (verticeIndexCorrespondingDict[vertexInfo.index]); * } * } * * newMeshLeftFilter.mesh.vertices = leftVertices.ToArray(); * newMeshLeftFilter.mesh.normals = leftNormals.ToArray (); * newMeshLeftFilter.mesh.triangles = leftTriangleIndex.ToArray(); * newMeshLeftFilter.mesh.RecalculateNormals (); * newMeshLeftFilter.mesh.RecalculateBounds (); * * verticeIndexCorrespondingDict.Clear (); * List<Vector3> rightVertices = new List<Vector3> (); * List<Vector3> rightNormals = new List<Vector3> (); * List<int> rightTriangleIndex = new List<int> (); * for (int i = 0; i < rightTriangles.Count; i++) { * TriangleInfo triangle = rightTriangles[i]; * foreach(int vIndex in triangle.vertices) * { * VertexInfo vertexInfo = vertices[vIndex]; * if(!verticeIndexCorrespondingDict.ContainsKey(vertexInfo.index)) * { * verticeIndexCorrespondingDict.Add(vertexInfo.index, rightVertices.Count); * rightVertices.Add (vertexInfo.vertex); * rightNormals.Add (vertexInfo.normal); * } * rightTriangleIndex.Add (verticeIndexCorrespondingDict[vertexInfo.index]); * } * } * * newMeshRightFilter.mesh.vertices = rightVertices.ToArray(); * newMeshRightFilter.mesh.normals = rightNormals.ToArray (); * newMeshRightFilter.mesh.triangles = rightTriangleIndex.ToArray(); * newMeshRightFilter.mesh.RecalculateNormals (); * newMeshRightFilter.mesh.RecalculateBounds ();*/ Destroy(victim.gameObject); }