From 0ccc268b1618af41738c43e1b0349fafd50181d2 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sat, 16 Aug 2014 09:55:08 +0200 Subject: [PATCH] Avoided ambiguous functions through the (possibly too clever) use of SFINAE. --- .../include/PolyVoxCore/MarchingCubesSurfaceExtractor.h | 9 ++++++--- tests/TestSurfaceExtractor.cpp | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h index 5e820c5c..4db8218c 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h @@ -331,19 +331,22 @@ namespace PolyVox // Note: This function is called 'extractMarchingCubesCustomMesh' rather than 'extractMarchingCubesMesh' to avoid ambiguity when only three parameters // are provided (would the third parameter be a controller or a mesh?). It seems this can be fixed by using enable_if/static_assert to emulate concepts, // but this is relatively complex and I haven't done it yet. Could always add it later as another overload. + // + // Note: the last parameter is a dummy, which is used to avoid ambiguities between which version of the function to call by using SFINAE. template< typename VolumeType, typename MeshType, typename Controller = DefaultMarchingCubesController > - void extractMarchingCubesCustomMesh(VolumeType* volData, Region region, MeshType* result, Controller controller = Controller(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()) + void extractMarchingCubesMesh(VolumeType* volData, Region region, MeshType* result, Controller controller = Controller(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), typename MeshType::VertexType doNotUseThisParameter = typename MeshType::VertexType()) { MarchingCubesSurfaceExtractor extractor(volData, region, result, controller, eWrapMode, tBorderValue); extractor.execute(); } // This version of the function is easier to use - it automatically creates and returns a mesh of the appropriate type so the user doesn't have to worry about it. + // Note: the last parameter is a dummy, which is used to avoid ambiguities between which version of the function to call by using SFINAE. template< typename VolumeType, typename Controller = DefaultMarchingCubesController > - Mesh > extractMarchingCubesMesh(VolumeType* volData, Region region, Controller controller = Controller(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()) + Mesh > extractMarchingCubesMesh(VolumeType* volData, Region region, Controller controller = Controller(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), typename Controller::DensityType doNotUseThisParameter = typename Controller::DensityType()) { Mesh, DefaultIndexType > result; - extractMarchingCubesCustomMesh, DefaultIndexType > >(volData, region, &result, controller, eWrapMode, tBorderValue); + extractMarchingCubesMesh, DefaultIndexType > >(volData, region, &result, controller, eWrapMode, tBorderValue); return result; } } diff --git a/tests/TestSurfaceExtractor.cpp b/tests/TestSurfaceExtractor.cpp index 8ab93f35..6c665372 100644 --- a/tests/TestSurfaceExtractor.cpp +++ b/tests/TestSurfaceExtractor.cpp @@ -142,7 +142,7 @@ void TestSurfaceExtractor::testExecute() // This test makes use of a custom controller auto floatVol = createAndFillVolume(); CustomMarchingCubesController floatCustomController; - auto floatMesh = extractMarchingCubesMesh(floatVol, floatVol->getEnclosingRegion(), floatCustomController, WrapModes::Border, float(0)); + auto floatMesh = extractMarchingCubesMesh(floatVol, floatVol->getEnclosingRegion(), floatCustomController); QCOMPARE(floatMesh.getNoOfVertices(), uint32_t(16113)); // Verifies size of mesh and that we have 32-bit indices QCOMPARE(floatMesh.getNoOfIndices(), uint32_t(22053)); // Verifies size of mesh QCOMPARE(floatMesh.getIndex(100), uint32_t(26)); // Verifies that we have 32-bit indices @@ -152,7 +152,7 @@ void TestSurfaceExtractor::testExecute() // use a default for the second-to-last parameter but noot use a default for the last parameter. auto intVol = createAndFillVolume(); Mesh< MarchingCubesVertex< int8_t >, uint16_t > intMesh; - extractMarchingCubesCustomMesh(intVol, intVol->getEnclosingRegion(), &intMesh); + extractMarchingCubesMesh(intVol, intVol->getEnclosingRegion(), &intMesh); QCOMPARE(intMesh.getNoOfVertices(), uint16_t(11718)); // Verifies size of mesh and that we have 16-bit indices QCOMPARE(intMesh.getNoOfIndices(), uint32_t(34041)); // Verifies size of mesh QCOMPARE(intMesh.getIndex(100), uint16_t(29)); // Verifies that we have 16-bit indices @@ -162,7 +162,7 @@ void TestSurfaceExtractor::testExecute() auto doubleVol = createAndFillVolume(); CustomMarchingCubesController doubleCustomController; Mesh< MarchingCubesVertex< double >, uint16_t > doubleMesh; - extractMarchingCubesCustomMesh(doubleVol, doubleVol->getEnclosingRegion(), &doubleMesh, doubleCustomController, WrapModes::Border, double(0)); + extractMarchingCubesMesh(doubleVol, doubleVol->getEnclosingRegion(), &doubleMesh, doubleCustomController); QCOMPARE(doubleMesh.getNoOfVertices(), uint16_t(16113)); // Verifies size of mesh and that we have 32-bit indices QCOMPARE(doubleMesh.getNoOfIndices(), uint32_t(22053)); // Verifies size of mesh QCOMPARE(doubleMesh.getIndex(100), uint16_t(26)); // Verifies that we have 32-bit indices