diff --git a/src/simplnx/Utilities/Math/GeometryMath.cpp b/src/simplnx/Utilities/Math/GeometryMath.cpp index 52881e47ee..ba97701d14 100644 --- a/src/simplnx/Utilities/Math/GeometryMath.cpp +++ b/src/simplnx/Utilities/Math/GeometryMath.cpp @@ -54,9 +54,17 @@ BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfVertices(INodeGeometry0D return {ll, ur}; // should be valid } -BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFace(const detail::GeometryStoreCache& cache, const nx::core::TriangleGeom& triangleGeom, int32 faceId) +BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFace(const detail::GeometryStoreCache& cache, const nx::core::TriangleGeom& triangleGeom, int32 faceId, std::vector& verts) { - std::array points = GeometryMath::detail::GetFaceCoordinates(cache, faceId); + // Unavoidable branch to verify integrity of subsequent function + // specifically because this an exposed function, however, the + // CPU should quickly be able to predict once it has run a few + // iterations of the function making it relatively lightweight + if(verts.size() != cache.NumVertsPerFace) + { + verts = std::vector(cache.NumVertsPerFace); + } + std::array points = GeometryMath::detail::GetFaceCoordinates(cache, faceId, verts); Point3Df ll = points[0]; Point3Df ur = points[0]; @@ -118,9 +126,12 @@ BoundingBox3Df nx::core::GeometryMath::FindBoundingBoxOfFaces(const nx::core::Tr detail::GeometryStoreCache cache(triangleGeom.getVertices()->getDataStoreRef(), triangleGeom.getFaces()->getDataStoreRef(), triangleGeom.getNumberOfVerticesPerFace()); + // initialize temp storage 'verts' vector to avoid expensive + // calls during tight loops below + std::vector verts(cache.NumVertsPerFace); for(const auto& id : faceIds) { - auto bounds = FindBoundingBoxOfFace(cache, triangleGeom, id); + auto bounds = FindBoundingBoxOfFace(cache, triangleGeom, id, verts); Point3Df min = bounds.getMinPoint(); Point3Df max = bounds.getMaxPoint(); diff --git a/src/simplnx/Utilities/Math/GeometryMath.hpp b/src/simplnx/Utilities/Math/GeometryMath.hpp index 45aad0556f..9cd99c9494 100644 --- a/src/simplnx/Utilities/Math/GeometryMath.hpp +++ b/src/simplnx/Utilities/Math/GeometryMath.hpp @@ -43,27 +43,25 @@ template concept FloatType = std::is_floating_point_v; template -std::array, 3> GetFaceCoordinates(const GeometryStoreCache& cache, usize faceId) +std::array, 3> GetFaceCoordinates(const GeometryStoreCache& cache, usize faceId, std::vector& verts) { std::array, 3> points; - std::vector verts(cache.NumVertsPerFace); { const usize offset = faceId * cache.NumVertsPerFace; if(offset + cache.NumVertsPerFace <= cache.FacesStoreRef.getSize()) { for(usize i = 0; i < cache.NumVertsPerFace; i++) { - verts[i] = cache.FacesStoreRef.at(offset + i); + verts[i] = cache.FacesStoreRef[offset + i]; } } } - for(usize index = 0; index < verts.size(); index++) + for(usize index = 0; index < cache.NumVertsPerFace; index++) { const usize offset = verts[index] * 3; - for(usize i = 0; i < 3; i++) - { - points[index][i] = static_cast(cache.VerticesStoreRef.at(offset + i)); - } + points[index][0] = static_cast(cache.VerticesStoreRef.at(offset)); + points[index][1] = static_cast(cache.VerticesStoreRef.at(offset + 1)); + points[index][2] = static_cast(cache.VerticesStoreRef.at(offset + 2)); } return points; } @@ -401,7 +399,7 @@ nx::core::BoundingBox3Df SIMPLNX_EXPORT FindBoundingBoxOfRotatedFace(nx::core::T * @param faceId * @return nx::core::BoundingBox */ -nx::core::BoundingBox3Df FindBoundingBoxOfFace(const detail::GeometryStoreCache& cache, const nx::core::TriangleGeom& triangleGeom, int32 faceId); +nx::core::BoundingBox3Df FindBoundingBoxOfFace(const detail::GeometryStoreCache& cache, const nx::core::TriangleGeom& triangleGeom, int32 faceId, std::vector& verts); /** * @param TriangleGeom* faces @@ -588,6 +586,10 @@ char IsPointInPolyhedron(const nx::core::TriangleGeom& triangleGeomRef, const st detail::GeometryStoreCache cache(triangleGeomRef.getVertices()->getDataStoreRef(), triangleGeomRef.getFaces()->getDataStoreRef(), triangleGeomRef.getNumberOfVerticesPerFace()); + // initialize temp storage 'verts' vector to avoid expensive + // calls during tight loops below + std::vector verts(cache.NumVertsPerFace); + usize numFaces = faceIds.size(); while(iter++ < numFaces) { @@ -617,7 +619,7 @@ char IsPointInPolyhedron(const nx::core::TriangleGeom& triangleGeomRef, const st } else { - std::array, 3> coords = detail::GetFaceCoordinates(cache, faceIds[face]); + std::array, 3> coords = detail::GetFaceCoordinates(cache, faceIds[face], verts); code = RayIntersectsTriangle(ray, coords[0], coords[1], coords[2]); } diff --git a/src/simplnx/Utilities/SampleSurfaceMesh.cpp b/src/simplnx/Utilities/SampleSurfaceMesh.cpp index d85eb1169a..62b7ab311c 100644 --- a/src/simplnx/Utilities/SampleSurfaceMesh.cpp +++ b/src/simplnx/Utilities/SampleSurfaceMesh.cpp @@ -242,6 +242,11 @@ Result<> SampleSurfaceMesh::execute(SampleSurfaceMeshInputValues& inputValues) { // !!! DO NOT USE GeometryStoreCache ELSEWHERE, SPECIAL CASE !!! GeometryMath::detail::GeometryStoreCache cache(triangleGeom.getVertices()->getDataStoreRef(), triangleGeom.getFaces()->getDataStoreRef(), triangleGeom.getNumberOfVerticesPerFace()); + + // initialize temp storage 'verts' vector to avoid expensive + // calls during tight loops below + std::vector verts(cache.NumVertsPerFace); + // traverse data again to get the faces belonging to each feature for(int32 i = 0; i < numFaces; i++) { @@ -256,7 +261,7 @@ Result<> SampleSurfaceMesh::execute(SampleSurfaceMeshInputValues& inputValues) faceLists[g2][(linkLoc[g2])++] = i; } // find bounding box for each face - faceBBs.emplace_back(GeometryMath::FindBoundingBoxOfFace(cache, triangleGeom, i)); + faceBBs.emplace_back(GeometryMath::FindBoundingBoxOfFace(cache, triangleGeom, i, verts)); } }