Пример #1
0
    /// <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");
        }
    }
Пример #2
0
    /// <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 раньше");
        }
    }