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 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; }
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.")); }
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");*/ }