/// <summary> /// Slice a mesh by the slice plane. /// We assume the plane is already in the mesh's local coordinate frame /// Returns posMesh and negMesh, which are the resuling meshes on both sides of the plane /// (posMesh on the same side as the plane's normal, negMesh on the opposite side) /// </summary> public bool SliceMesh(Mesh mesh, ref Plane slice) { // Let's always fill the vertices array so that we can access it even if the mesh didn't intersect mesh.GetVertices(ogVertices); // 1. Verify if the bounds intersect first if (!Intersections.BoundPlaneIntersect(mesh, ref slice)) { return(false); } mesh.GetTriangles(ogTriangles, 0); mesh.GetNormals(ogNormals); mesh.GetUVs(0, ogUvs); PositiveMesh.Clear(); NegativeMesh.Clear(); addedPairs.Clear(); // 2. Separate old vertices in new meshes for (int i = 0; i < ogVertices.Count; ++i) { if (slice.GetDistanceToPoint(ogVertices[i]) >= 0) { PositiveMesh.AddVertex(ogVertices, ogNormals, ogUvs, i); } else { NegativeMesh.AddVertex(ogVertices, ogNormals, ogUvs, i); } } // 2.5 : If one of the mesh has no vertices, then it doesn't intersect if (NegativeMesh.vertices.Count == 0 || PositiveMesh.vertices.Count == 0) { return(false); } // 3. Separate triangles and cut those that intersect the plane for (int i = 0; i < ogTriangles.Count; i += 3) { if (intersect.TrianglePlaneIntersect(ogVertices, ogUvs, ogTriangles, i, ref slice, PositiveMesh, NegativeMesh, intersectPair)) { addedPairs.AddRange(intersectPair); } } if (addedPairs.Count > 0) { //FillBoundaryGeneral(addedPairs); FillBoundaryFace(addedPairs); return(true); } else { throw new UnityException("Error: if added pairs is empty, we should have returned false earlier"); } }
/// <summary> /// Разрезание меша по плоскости разреза. /// Мы предполагаем, что плоскость уже находится в локальной системе координат меша /// Возвращает posMesh и negMesh, которые являются мешами по разные стороны от плоскости разреза /// (posMesh на стороне нормали плоскости разреза, negMesh на противоположной стороне) /// </summary> public bool SliceMesh(Mesh mesh, ref Plane slice) { // Заполняем массив вершин, чтобы мы могли получить к нему доступ, даже если не было пересечения mesh.GetVertices(ogVertices); if (!Intersections.BoundPlaneIntersect(mesh, ref slice)) { return(false); } mesh.GetTriangles(ogTriangles, 0); mesh.GetNormals(ogNormals); mesh.GetUVs(0, ogUvs); PositiveMesh.Clear(); NegativeMesh.Clear(); addedPairs.Clear(); // Распределение старых вершин в новых мешах for (int i = 0; i < ogVertices.Count; ++i) { if (slice.GetDistanceToPoint(ogVertices[i]) >= 0) { PositiveMesh.AddVertex(ogVertices, ogNormals, ogUvs, i); } else { NegativeMesh.AddVertex(ogVertices, ogNormals, ogUvs, i); } } // Если у одной из мешей нет вершин, то не пересекается if (NegativeMesh.vertices.Count == 0 || PositiveMesh.vertices.Count == 0) { return(false); } // Разделяй треугольники и разрезай те, которые пересекают плоскость for (int i = 0; i < ogTriangles.Count; i += 3) { if (intersect.TrianglePlaneIntersect(ogVertices, ogUvs, ogTriangles, i, ref slice, PositiveMesh, NegativeMesh, intersectPair)) { addedPairs.AddRange(intersectPair); } } if (addedPairs.Count > 0) { FillBoundaryFace(addedPairs); return(true); } else { throw new UnityException("Ошибка: если добавленные пары пустые, мы должны были вернуть false раньше"); } }