Beispiel #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");
        }
    }
Beispiel #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 раньше");
        }
    }
Beispiel #3
0
    /// <summary>Cut mesh along bisector line and keep only the half containing the center point.</summary>
    public static TempMesh Cut(Mesh mesh, Line bisector, Vector2 center)
    {
        var      initialArraySize = 256;
        TempMesh tempMesh         = new TempMesh(initialArraySize);
        TempMesh trashMesh        = new TempMesh(initialArraySize);
        var      intersect        = new Intersections();

        var addedPairs    = new List <Vector3>(initialArraySize);
        var ogVertices    = new List <Vector3>(initialArraySize);
        var ogNormals     = new List <Vector3>(initialArraySize);
        var ogUvs         = new List <Vector2>(initialArraySize);
        var ogTriangles   = new List <int>(initialArraySize * 3);
        var intersectPair = new Vector3[2];

        var tempTriangle = new Vector3[3];

        // Let's always fill the vertices array so that we can access it even if the mesh didn't intersect
        mesh.GetVertices(ogVertices);
        mesh.GetTriangles(ogTriangles, 0);
        mesh.GetNormals(ogNormals);
        mesh.GetUVs(0, ogUvs);

        tempMesh.Clear();
        trashMesh.Clear();

        for (int i = 0; i < ogVertices.Count; ++i)
        {
            var test = bisector.isLeft(ogVertices[i]);
            // Debug.Log(test);
            if (test)
            {
                tempMesh.AddVertex(ogVertices, ogNormals, ogUvs, i);
            }
            else
            {
                trashMesh.AddVertex(ogVertices, ogNormals, ogUvs, i);
            }
        }

        Plane slice = bisector.GetPlane();

        // 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, tempMesh, trashMesh, intersectPair))
            {
                addedPairs.AddRange(intersectPair);
            }
        }

        if (addedPairs.Count > 0)
        {
            //FillBoundaryGeneral(addedPairs);
            MeshTools.FillBoundaryFace(tempMesh, addedPairs, ref tempTriangle);
            return(tempMesh);
        }
        else
        {
            throw new UnityException("Error: if added pairs is empty, we should have returned false earlier");
        }

        return(tempMesh);
    }