Avoided ambiguous functions through the (possibly too clever) use of SFINAE.

This commit is contained in:
David Williams 2014-08-16 09:55:08 +02:00
parent aa4591d206
commit 0ccc268b16
2 changed files with 9 additions and 6 deletions

View File

@ -331,19 +331,22 @@ namespace PolyVox
// Note: This function is called 'extractMarchingCubesCustomMesh' rather than 'extractMarchingCubesMesh' to avoid ambiguity when only three parameters // 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, // 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. // 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<typename VolumeType::VoxelType> > template< typename VolumeType, typename MeshType, typename Controller = DefaultMarchingCubesController<typename VolumeType::VoxelType> >
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<VolumeType, MeshType, Controller> extractor(volData, region, result, controller, eWrapMode, tBorderValue); MarchingCubesSurfaceExtractor<VolumeType, MeshType, Controller> extractor(volData, region, result, controller, eWrapMode, tBorderValue);
extractor.execute(); 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. // 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<typename VolumeType::VoxelType> > template< typename VolumeType, typename Controller = DefaultMarchingCubesController<typename VolumeType::VoxelType> >
Mesh<MarchingCubesVertex<typename VolumeType::VoxelType> > extractMarchingCubesMesh(VolumeType* volData, Region region, Controller controller = Controller(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()) Mesh<MarchingCubesVertex<typename VolumeType::VoxelType> > 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<MarchingCubesVertex<typename VolumeType::VoxelType>, DefaultIndexType > result; Mesh<MarchingCubesVertex<typename VolumeType::VoxelType>, DefaultIndexType > result;
extractMarchingCubesCustomMesh<VolumeType, Mesh<MarchingCubesVertex<typename VolumeType::VoxelType>, DefaultIndexType > >(volData, region, &result, controller, eWrapMode, tBorderValue); extractMarchingCubesMesh<VolumeType, Mesh<MarchingCubesVertex<typename VolumeType::VoxelType>, DefaultIndexType > >(volData, region, &result, controller, eWrapMode, tBorderValue);
return result; return result;
} }
} }

View File

@ -142,7 +142,7 @@ void TestSurfaceExtractor::testExecute()
// This test makes use of a custom controller // This test makes use of a custom controller
auto floatVol = createAndFillVolume<float>(); auto floatVol = createAndFillVolume<float>();
CustomMarchingCubesController floatCustomController; 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.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.getNoOfIndices(), uint32_t(22053)); // Verifies size of mesh
QCOMPARE(floatMesh.getIndex(100), uint32_t(26)); // Verifies that we have 32-bit indices 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. // use a default for the second-to-last parameter but noot use a default for the last parameter.
auto intVol = createAndFillVolume<int8_t>(); auto intVol = createAndFillVolume<int8_t>();
Mesh< MarchingCubesVertex< int8_t >, uint16_t > intMesh; 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.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.getNoOfIndices(), uint32_t(34041)); // Verifies size of mesh
QCOMPARE(intMesh.getIndex(100), uint16_t(29)); // Verifies that we have 16-bit indices QCOMPARE(intMesh.getIndex(100), uint16_t(29)); // Verifies that we have 16-bit indices
@ -162,7 +162,7 @@ void TestSurfaceExtractor::testExecute()
auto doubleVol = createAndFillVolume<double>(); auto doubleVol = createAndFillVolume<double>();
CustomMarchingCubesController doubleCustomController; CustomMarchingCubesController doubleCustomController;
Mesh< MarchingCubesVertex< double >, uint16_t > doubleMesh; 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.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.getNoOfIndices(), uint32_t(22053)); // Verifies size of mesh
QCOMPARE(doubleMesh.getIndex(100), uint16_t(26)); // Verifies that we have 32-bit indices QCOMPARE(doubleMesh.getIndex(100), uint16_t(26)); // Verifies that we have 32-bit indices