Exemple #1
0
void BaseMesh::AppendVertices(const BaseMesh &O)
{
    int vc = VertexCount(), ic = IndexCount();
    MeshVertex *V = Vertices(), *OldV = new MeshVertex[vc];
    DWORD *I = Indices(), *OldI = new DWORD[ic];

    memcpy(OldV, V, vc * sizeof(MeshVertex));
    memcpy(OldI, I, ic * sizeof(DWORD));            //store all the old vertices/indices

    Allocate(vc + O.VertexCount(), ic/3 + O.FaceCount());    //allocate space for the current vertices/indices and o's vertices/indices

    V = Vertices();
    I = Indices();

    memcpy(V, OldV, vc * sizeof(MeshVertex));
    memcpy(I, OldI, ic * sizeof(DWORD));        //copy the old vertices/indices back into the mesh,

    memcpy(&(V[vc]), O.Vertices(), O.VertexCount() * sizeof(MeshVertex));    //copy the new vertices after the current ones,

    UINT oic = O.IndexCount();
    const DWORD *oI = O.Indices();
    for(UINT i = 0; i < oic; i++)
    {
        I[ic+i] = oI[i] + vc;    //copy o's indices as well, except increasing the index by vc (since o's vertices start at vc, not 0)
    }

    delete[] OldV;
    delete[] OldI;
}
Exemple #2
0
void MeshBVH::InitSingleMesh(const BaseMesh &M, UINT triangleCountCutoff)
{
	FreeMemory();

    const MeshVertex *vertices = M.Vertices();
    const UINT vertexCount = M.VertexCount();

    const DWORD *indices = M.Indices();
    const UINT triCount = M.FaceCount();

    if(MeshBVHDebugging) Console::WriteLine("Making BVH, triCount=" + String(triCount));

    _triInfo.Allocate(triCount);
    Vector<MeshBVHTriangleInfo*> dataPointers(triCount);
    for(UINT triIndex = 0; triIndex < triCount; triIndex++)
    {
        MeshBVHTriangleInfo &curTriInfo = _triInfo[triIndex];
        dataPointers[triIndex] = &curTriInfo;

        curTriInfo.v[0] = vertices[ indices[ triIndex * 3 + 0 ] ].Pos;
        curTriInfo.v[1] = vertices[ indices[ triIndex * 3 + 1 ] ].Pos;
        curTriInfo.v[2] = vertices[ indices[ triIndex * 3 + 2 ] ].Pos;
    }

    _storage.Allocate(triCount);

    MeshBVHNodeConstructorInfo info;
    info.storage = _storage.CArray();
    info.storageIndex = 0;
    info.triangleCountCutoff = triangleCountCutoff;

    _root = new MeshBVHNode(dataPointers.CArray(), dataPointers.Length(), info, 0);
}
void RayIntersectorKDTree::Init(const BaseMesh &M)
{
    Console::WriteString("Building RayIntersectorKDTree...");
    FreeMemory();

    _VertexCount = M.VertexCount();
    _TriangleCount = M.FaceCount();

    Console::WriteString(String(_TriangleCount) + String(" base triangles, "));
    

    _Vertices = new Vec3f[_VertexCount];
    _Indices = new UINT[_TriangleCount * 3];
    
    const MeshVertex *MeshVertices = M.Vertices();
    const DWORD *MeshIndices = M.Indices();
    
    for(UINT VertexIndex = 0; VertexIndex < _VertexCount; VertexIndex++)
    {
        _Vertices[VertexIndex] = MeshVertices[VertexIndex].Pos;
    }

    for(UINT IndexIndex = 0; IndexIndex < _TriangleCount * 3; IndexIndex++)
    {
        _Indices[IndexIndex] = MeshIndices[IndexIndex];
    }

    Vector<UINT> TriangleIndices(_TriangleCount);
    for(UINT TriangleIndex = 0; TriangleIndex < _TriangleCount; TriangleIndex++)
    {
        TriangleIndices[TriangleIndex] = TriangleIndex;
    }
    
    Vector<UINT> LeafTrianglesVector;
    _Root = new RayIntersectorKDTreeNode(TriangleIndices, *this, 0, LeafTrianglesVector);
    _LeafTriangleCount = LeafTrianglesVector.Length();
    _LeafTriangles = new UINT[_LeafTriangleCount];
    memcpy(_LeafTriangles, LeafTrianglesVector.CArray(), sizeof(UINT) * _LeafTriangleCount);
    Console::WriteLine(String(_LeafTriangleCount) + String(" leaf triangles."));
}
Exemple #4
0
void BaseMesh::Split(float (*PositionFunction) (Vec3f &), BaseMesh &M1, BaseMesh &M2)
{
    int i,vc=VertexCount(),ic=IndexCount();
    MeshVertex *V = Vertices();
    DWORD *I = Indices();

    Vector<MeshVertex> NV1,NV2;
    Vector<TriMeshFace> NT1,NT2;

    SplitVMapper *VMap = new SplitVMapper[vc];
    float Value;

    for(i=0;i<vc;i++)
    {
        Value = PositionFunction(V[i].Pos);
        if(Value < 0.0f)
        {
            VMap[i].Side = 0;
            VMap[i].NVMap1 = NV1.Length();
            VMap[i].NVMap2 = -1;
            NV1.PushEnd(V[i]);
        } else {
            VMap[i].Side = 1;
            VMap[i].NVMap1 = -1;
            VMap[i].NVMap2 = NV2.Length();
            NV2.PushEnd(V[i]);
        }
    }

    int TSide[3];
    TriMeshFace Tri;
    int Oddball,State;

    for(i=0;i<ic;i+=3)
    {
        TSide[0] = VMap[I[i]].Side;
        TSide[1] = VMap[I[i+1]].Side;
        TSide[2] = VMap[I[i+2]].Side;

        if(TSide[0] && TSide[1] && TSide[2]) //all O2
        {            
            Tri.I[0] = VMap[I[i]].NVMap2;
            Tri.I[1] = VMap[I[i+1]].NVMap2;
            Tri.I[2] = VMap[I[i+2]].NVMap2;
            NT2.PushEnd(Tri);
        } else if(!(TSide[0] || TSide[1] || TSide[2])) //all O1
        {
            Tri.I[0] = VMap[I[i]].NVMap1;
            Tri.I[1] = VMap[I[i+1]].NVMap1;
            Tri.I[2] = VMap[I[i+2]].NVMap1;
            NT1.PushEnd(Tri);
        } else {
            if(TSide[0] && TSide[1]) {Oddball = 2; State = 1;}
            if(TSide[0] && TSide[2]) {Oddball = 1; State = 1;}
            if(TSide[1] && TSide[2]) {Oddball = 0; State = 1;}
            if(!(TSide[0] || TSide[1])) {Oddball = 2; State = 2;}
            if(!(TSide[0] || TSide[2])) {Oddball = 1; State = 2;}
            if(!(TSide[1] || TSide[2])) {Oddball = 0; State = 2;}

            if(State == 1)    //Add to Obj2
            {
                if(VMap[I[i+Oddball]].NVMap2 == -1)
                {
                    VMap[I[i+Oddball]].NVMap2 = NV2.Length();
                    NV2.PushEnd(V[I[i+Oddball]]);
                }
                Tri.I[0] = VMap[I[i]].NVMap2;
                Tri.I[1] = VMap[I[i+1]].NVMap2;
                Tri.I[2] = VMap[I[i+2]].NVMap2;
                NT2.PushEnd(Tri);
            } else {        //Add to Obj1
                if(VMap[I[i+Oddball]].NVMap1 == -1)
                {
                    VMap[I[i+Oddball]].NVMap1 = NV1.Length();
                    NV1.PushEnd(V[I[i+Oddball]]);
                }
                Tri.I[0] = VMap[I[i]].NVMap1;
                Tri.I[1] = VMap[I[i+1]].NVMap1;
                Tri.I[2] = VMap[I[i+2]].NVMap1;
                NT1.PushEnd(Tri);
            }
        }
    }

    delete[] VMap;

    M1.Allocate(NV1.Length(),NT1.Length());
    M2.Allocate(NV2.Length(),NT2.Length());
    
    memcpy(M1.Vertices(), NV1.CArray(), M1.VertexCount() * sizeof(MeshVertex));
    memcpy(M2.Vertices(), NV2.CArray(), M2.VertexCount() * sizeof(MeshVertex));
    memcpy(M1.Indices(), NT1.CArray(), M1.IndexCount() * sizeof(DWORD));
    memcpy(M2.Indices(), NT2.CArray(), M2.IndexCount() * sizeof(DWORD));
}
Exemple #5
0
void ComplexMesh::Load(const BaseMesh &Mesh)
{
    FreeMemory();
    
    _Vertices.Allocate(Mesh.VertexCount());
    _Triangles.Allocate(Mesh.FaceCount());
    _HalfEdges.Allocate(Mesh.FaceCount() * 3);
    _FullEdges.FreeMemory();

    for(UINT i = 0; i < _Vertices.Length(); i++)
    {
        _Vertices[i].Pos() = Mesh.Vertices()[i].Pos;
        _Vertices[i].TexCoords() = Mesh.Vertices()[i].TexCoord;
        _Vertices[i].Boundary() = false;
        _Vertices[i]._Index = i;
    }

    InitHashTable(_Vertices.Length());

    for(UINT TriangleIndex = 0; TriangleIndex < _Triangles.Length(); TriangleIndex++)
    {
        Triangle &CurTriangle = _Triangles[TriangleIndex];
        UINT LocalIndices[3];
        LocalIndices[0] = Mesh.Indices()[TriangleIndex * 3 + 0];
        LocalIndices[1] = Mesh.Indices()[TriangleIndex * 3 + 1];
        LocalIndices[2] = Mesh.Indices()[TriangleIndex * 3 + 2];
        CurTriangle._Index = TriangleIndex;
        for(UINT LocalEdgeIndex = 0; LocalEdgeIndex < 3; LocalEdgeIndex++)
        {
            Vertex *SearchV[2];

            CurTriangle._HalfEdges[LocalEdgeIndex] = &_HalfEdges[TriangleIndex * 3 + LocalEdgeIndex];
            CurTriangle._Vertices[LocalEdgeIndex] = &_Vertices[LocalIndices[LocalEdgeIndex]];
            _HalfEdges[TriangleIndex * 3 + LocalEdgeIndex]._NextEdge = &_HalfEdges[TriangleIndex * 3 + (LocalEdgeIndex + 1) % 3];

            SearchV[0] = &_Vertices[LocalIndices[(LocalEdgeIndex + 1) % 3]];
            SearchV[1] = &_Vertices[LocalIndices[(LocalEdgeIndex + 2) % 3]];
            if(SearchV[0]->Index() > SearchV[1]->Index())
            {
                Utility::Swap(SearchV[0], SearchV[1]);
            }
            FullEdge &Target = FindFullEdge(SearchV);
            if(Target != FullEdge::NotFound)
            {
                PersistentAssert(Target.GetTriangle(1) == Triangle::Boundary, "Duplicate edge; 2-manifold criterion violated.");
                //PersistentAssert(Target.GetTriangle(1) == Triangle::Boundary,
                //                 String("Duplicate edge; 2-manifold criterion violated: ") + String(SearchV[0]->Index()) + String(", ") + String(SearchV[1]->Index()));

                _HalfEdges[TriangleIndex * 3 + LocalEdgeIndex]._AcrossEdge = &Target;
                Target._Triangles[1] = &CurTriangle;
            }
            else
            {
                FullEdge *NewEdge = new FullEdge;
                Assert(NewEdge != NULL, "Out of memory");
                NewEdge->_Index = _FullEdges.Length();
                NewEdge->_Triangles[0] = &CurTriangle;
                NewEdge->_Triangles[1] = &Triangle::Boundary;
                NewEdge->_Vertices[0] = SearchV[0];
                NewEdge->_Vertices[1] = SearchV[1];
                _HalfEdges[TriangleIndex * 3 + LocalEdgeIndex]._AcrossEdge = NewEdge;

                _FullEdges.PushEnd(NewEdge);
                HashEdge(*NewEdge);
            }
        }
    }

    for(UINT TriangleIndex = 0; TriangleIndex < _Triangles.Length(); TriangleIndex++)
    {
        Triangle &CurTriangle = _Triangles[TriangleIndex];
        for(UINT AdjacentTriangleIndex = 0; AdjacentTriangleIndex < 3; AdjacentTriangleIndex++)
        {
            Triangle &AdjTriangle = CurTriangle.GetNeighboringTriangle(AdjacentTriangleIndex);
        }
    }

    ClearHashTable();
    
    for(UINT i = 0; i < _FullEdges.Length(); i++)
    {
        if(_FullEdges[i]->Boundary())
        {
            _FullEdges[i]->GetVertex(0).Boundary() = true;
            _FullEdges[i]->GetVertex(1).Boundary() = true;
            _FullEdges[i]->OrientMatchingBoundary();
        }
    }

    PrepareTopology();

    /*if(!Oriented())
    {
        Orient();
    }
    PersistentAssert(Oriented(), "Mesh not oriented");*/

}