Exemple #1
0
float BaseMesh::SidedSurfaceArea(const Plane &P)
{
    float Result = 0.0f;
    DWORD *MyIndices = Indices();
    MeshVertex *MyVertices = Vertices();
    UINT TriangleCount = FaceCount();
    for(UINT TriangleIndex = 0; TriangleIndex < TriangleCount; TriangleIndex++)
    {
        Vec3f LocalTriangle[6];
        UINT TSide[3];
        for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++)
        {
            LocalTriangle[LocalVertexIndex] = MyVertices[MyIndices[TriangleIndex * 3 + LocalVertexIndex]].Pos;
            if(Plane::DotCoord(P, LocalTriangle[LocalVertexIndex]) < 0.0f)
            {
                TSide[LocalVertexIndex] = 0;
            }
            else
            {
                TSide[LocalVertexIndex] = 1;
            }
        }
        UINT TriangleType = TSide[0] * 4 + TSide[1] * 2 + TSide[2] * 1;

        for(UINT EdgeIndex = 0; EdgeIndex < 3; EdgeIndex++)
        {
            if(PerfectEdges[TriangleType][EdgeIndex])
            {
                Vec3f Vtx1 = MyVertices[MyIndices[TriangleIndex * 3 + PerfectEdgeList[EdgeIndex][0]]].Pos;
                Vec3f Vtx2 = MyVertices[MyIndices[TriangleIndex * 3 + PerfectEdgeList[EdgeIndex][1]]].Pos;
                Vec3f VtxIntersect = P.IntersectLine(Vtx1, Vtx2);
                if(!Vec3f::WithinRect(VtxIntersect, Rectangle3f::ConstructFromTwoPoints(Vtx1, Vtx2)))
                {
                    VtxIntersect = (Vtx1 + Vtx2) * 0.5f;
                }
                
                LocalTriangle[3 + EdgeIndex] = VtxIntersect;
            }
        }

        for(UINT LocalTriangleIndex = 0; LocalTriangleIndex < 6; LocalTriangleIndex += 3)
        {
            if(M1Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                Vec3f V[3];
                V[0] = LocalTriangle[M1Indices[TriangleType][LocalTriangleIndex + 0]];
                V[1] = LocalTriangle[M1Indices[TriangleType][LocalTriangleIndex + 1]];
                V[2] = LocalTriangle[M1Indices[TriangleType][LocalTriangleIndex + 2]];
                Result += Math::TriangleArea(V[0], V[1], V[2]);
            }
        }
    }
    return Result;
}
Exemple #2
0
void BaseMesh::ClosedPlaneSplit(const Plane &P, BaseMesh &M1, BaseMesh &M2)
{
    UINT VC = VertexCount(), IC = IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<Vec3f> NewVertices[2];
    Vector<TriMeshFace> NewFaces[2];
    Vector<Vec2f> BoundaryVertices;
    Vector<UINT> BoundaryIndices[2];

    Vec3f OrthogonalBasis1, OrthogonalBasis2;
    Vec3f::CompleteOrthonormalBasis(P.Normal(), OrthogonalBasis1, OrthogonalBasis2);

    PerfectSplitVMapper *VMap = new PerfectSplitVMapper[VC];
    
    for(UINT VertexIndex = 0; VertexIndex < VC; VertexIndex++)
    {
        Vec3f Pos = V[VertexIndex].Pos;
        float Value = Plane::DotCoord(P, Pos);
        if(Value < 0.0f)
        {
            VMap[VertexIndex].Side = 0;
            VMap[VertexIndex].NVMap = NewVertices[0].Length();
            NewVertices[0].PushEnd(Pos);
        }
        else
        {
            VMap[VertexIndex].Side = 1;
            VMap[VertexIndex].NVMap = NewVertices[1].Length();
            NewVertices[1].PushEnd(Pos);
        }
    }

    for(UINT IndexIndex = 0; IndexIndex < IC; IndexIndex += 3)
    {
        int TSide[3];
        TSide[0] = VMap[I[IndexIndex + 0]].Side;
        TSide[1] = VMap[I[IndexIndex + 1]].Side;
        TSide[2] = VMap[I[IndexIndex + 2]].Side;

        DWORD LocalTriangleM1[6], LocalTriangleM2[6];
        LocalTriangleM2[0] = LocalTriangleM1[0] = VMap[I[IndexIndex + 0]].NVMap;
        LocalTriangleM2[1] = LocalTriangleM1[1] = VMap[I[IndexIndex + 1]].NVMap;
        LocalTriangleM2[2] = LocalTriangleM1[2] = VMap[I[IndexIndex + 2]].NVMap;

        UINT TriangleType = TSide[0] * 4 + TSide[1] * 2 + TSide[2] * 1;

        for(UINT EdgeIndex = 0; EdgeIndex < 3; EdgeIndex++)
        {
            if(PerfectEdges[TriangleType][EdgeIndex])
            {
                Vec3f Vtx1 = V[I[IndexIndex + PerfectEdgeList[EdgeIndex][0]]].Pos;
                Vec3f Vtx2 = V[I[IndexIndex + PerfectEdgeList[EdgeIndex][1]]].Pos;
                Vec3f VtxIntersect = P.IntersectLine(Vtx1, Vtx2);
                
                if(!Vec3f::WithinRect(VtxIntersect, Rectangle3f::ConstructFromTwoPoints(Vtx1, Vtx2)))
                {
                    VtxIntersect = (Vtx1 + Vtx2) * 0.5f;
                }
                
                BoundaryVertices.PushEnd(Vec2f(Vec3f::Dot(VtxIntersect, OrthogonalBasis1), Vec3f::Dot(VtxIntersect, OrthogonalBasis2)));

                LocalTriangleM1[3 + EdgeIndex] = NewVertices[0].Length();
                BoundaryIndices[0].PushEnd(NewVertices[0].Length());
                NewVertices[0].PushEnd(VtxIntersect);

                LocalTriangleM2[3 + EdgeIndex] = NewVertices[1].Length();
                BoundaryIndices[1].PushEnd(NewVertices[1].Length());
                NewVertices[1].PushEnd(VtxIntersect);
            }
        }

        for(UINT LocalTriangleIndex = 0; LocalTriangleIndex < 6; LocalTriangleIndex += 3)
        {
            if(M1Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                TriMeshFace Tri;
                Tri.I[0] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 0]];
                Tri.I[1] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 1]];
                Tri.I[2] = LocalTriangleM1[M1Indices[TriangleType][LocalTriangleIndex + 2]];
                NewFaces[0].PushEnd(Tri);
            }
            if(M2Indices[TriangleType][LocalTriangleIndex] != -1)
            {
                TriMeshFace Tri;
                Tri.I[0] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 0]];
                Tri.I[1] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 1]];
                Tri.I[2] = LocalTriangleM2[M2Indices[TriangleType][LocalTriangleIndex + 2]];
                NewFaces[1].PushEnd(Tri);
            }
        }
    }

#ifdef DELAUNAY_TRIANGULATOR
    if(BoundaryVertices.Length() > 0)
    {
        Vector<DWORD> BoundaryTriangulation;
        DelaunayTriangulator::Triangulate(BoundaryVertices, BoundaryTriangulation);
        for(UINT TriangleIndex = 0; TriangleIndex < BoundaryTriangulation.Length() / 3; TriangleIndex++)
        {
            for(UINT MeshIndex = 0; MeshIndex < 2; MeshIndex++)
            {
                TriMeshFace Tri;
                Vec3f V[3];
                for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++)
                {
                    Tri.I[LocalVertexIndex] = BoundaryIndices[MeshIndex][UINT(BoundaryTriangulation[TriangleIndex * 3 + LocalVertexIndex])];
                    V[LocalVertexIndex] = NewVertices[MeshIndex][UINT(Tri.I[LocalVertexIndex])];
                }
                //Utility::Swap(Tri.I[0], Tri.I[1]);
                //if(Math::TriangleArea(V[0], V[1], V[2]) > 1e-5f)
                {
                    NewFaces[MeshIndex].PushEnd(Tri);
                }
            }
        }
    }
#endif

    delete[] VMap;

    M1.SetGD(GetGD());
    M2.SetGD(GetGD());
    M1.Allocate(NewVertices[0].Length(), NewFaces[0].Length());
    M2.Allocate(NewVertices[1].Length(), NewFaces[1].Length());
    
    for(UINT VertexIndex = 0; VertexIndex < NewVertices[0].Length(); VertexIndex++)
    {
        M1.Vertices()[VertexIndex].Pos = NewVertices[0][VertexIndex];
    }
    for(UINT VertexIndex = 0; VertexIndex < NewVertices[1].Length(); VertexIndex++)
    {
        M2.Vertices()[VertexIndex].Pos = NewVertices[1][VertexIndex];
    }
    
    if(NewFaces[0].Length() > 0)
    {
        memcpy(M1.Indices(), NewFaces[0].CArray(), M1.IndexCount() * sizeof(DWORD));
    }
    if(NewFaces[1].Length() > 0)
    {
        memcpy(M2.Indices(), NewFaces[1].CArray(), M2.IndexCount() * sizeof(DWORD));
    }
}