diff --git a/examples/Basic/main.cpp b/examples/Basic/main.cpp index 9a3dac94..b51df61d 100644 --- a/examples/Basic/main.cpp +++ b/examples/Basic/main.cpp @@ -76,16 +76,10 @@ int main(int argc, char *argv[]) //Create an empty volume and then place a sphere in it SimpleVolume volData(PolyVox::Region(Vector3DInt32(0,0,0), Vector3DInt32(63, 63, 63))); createSphereInVolume(volData, 30); - - //A mesh object to hold the result of surface extraction - SurfaceMesh mesh; - - //Create a surface extractor. Comment out one of the following two lines to decide which type gets created. - CubicSurfaceExtractor< SimpleVolume > surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); - //MarchingCubesSurfaceExtractor< SimpleVolume > surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh); - - //Execute the surface extractor. - surfaceExtractor.execute(); + + // Extract the surface for the specified region of the volume. Uncomment the line for the kind of surface extraction you want to see. + auto mesh = extractCubicSurface(&volData, volData.getEnclosingRegion()); + //auto mesh = extractMarchingCubesSurface(&volData, volData.getEnclosingRegion()); //Pass the surface to the OpenGL window openGLWidget.setSurfaceMeshToRender(mesh); diff --git a/examples/Paging/main.cpp b/examples/Paging/main.cpp index 27236afd..64b2e9c6 100644 --- a/examples/Paging/main.cpp +++ b/examples/Paging/main.cpp @@ -186,11 +186,7 @@ int main(int argc, char *argv[]) std::cout << "Compression ratio: 1 to " << (1.0/(volData.calculateCompressionRatio())) << std::endl; //Extract the surface - SurfaceMesh mesh; - CubicSurfaceExtractorWithNormals< LargeVolume > surfaceExtractor(&volData, reg, &mesh); - //MarchingCubesSurfaceExtractor< LargeVolume > surfaceExtractor(&volData, reg, &mesh); - //CubicSurfaceExtractorWithNormals surfaceExtractor(&volData, reg, &mesh); - surfaceExtractor.execute(); + auto mesh = extractMarchingCubesSurface(&volData, reg); std::cout << "#vertices: " << mesh.getNoOfVertices() << std::endl; //Pass the surface to the OpenGL window diff --git a/examples/SmoothLOD/main.cpp b/examples/SmoothLOD/main.cpp index 9b8f6f78..ba6a9f03 100644 --- a/examples/SmoothLOD/main.cpp +++ b/examples/SmoothLOD/main.cpp @@ -90,15 +90,11 @@ int main(int argc, char *argv[]) volumeResampler.execute(); //Extract the surface - SurfaceMesh meshLowLOD; - MarchingCubesSurfaceExtractor< RawVolume > surfaceExtractor(&volDataLowLOD, volDataLowLOD.getEnclosingRegion(), &meshLowLOD); - surfaceExtractor.execute(); + auto meshLowLOD = extractMarchingCubesSurface(&volDataLowLOD, volDataLowLOD.getEnclosingRegion()); meshLowLOD.scaleVertices(/*2.0f*/63.0f / 31.0f); //Extract the surface - SurfaceMesh meshHighLOD; - MarchingCubesSurfaceExtractor< SimpleVolume > surfaceExtractorHigh(&volData, PolyVox::Region(Vector3DInt32(30,0,0), Vector3DInt32(63, 63, 63)), &meshHighLOD); - surfaceExtractorHigh.execute(); + auto meshHighLOD = extractMarchingCubesSurface(&volData, PolyVox::Region(Vector3DInt32(30, 0, 0), Vector3DInt32(63, 63, 63))); meshHighLOD.translateVertices(Vector3DFloat(30, 0, 0)); //Pass the surface to the OpenGL window diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h index a225a3b5..443a2984 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h @@ -157,6 +157,28 @@ namespace PolyVox WrapMode m_eWrapMode; typename VolumeType::VoxelType m_tBorderValue; }; + + template + SurfaceMesh extractCubicSurface(VolumeType* volData, Region region, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded) + { + SurfaceMesh result; + CubicSurfaceExtractor extractor(volData, region, &result, eWrapMode, tBorderValue, bMergeQuads, isQuadNeeded); + extractor.execute(); + return result; + } + + template + // This is a bit ugly - it seems that the C++03 syntax is different from the C++11 syntax? See this thread: http://stackoverflow.com/questions/6076015/typename-outside-of-template + // Long term we should probably come back to this and if the #ifdef is still needed then maybe it should check for C++11 mode instead of MSVC? +#if defined(_MSC_VER) + SurfaceMesh extractCubicSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType(), bool bMergeQuads = true) +#else + SurfaceMesh extractCubicSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true) +#endif + { + DefaultIsQuadNeeded isQuadNeeded; + return extractCubicSurface >(volData, region, eWrapMode, tBorderValue, bMergeQuads, isQuadNeeded); + } } #include "PolyVoxCore/CubicSurfaceExtractor.inl" diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h index 211734f0..2162b450 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h @@ -63,6 +63,28 @@ namespace PolyVox WrapMode m_eWrapMode; typename VolumeType::VoxelType m_tBorderValue; }; + + template + SurfaceMesh extractCubicSurfaceWithNormals(VolumeType* volData, Region region, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, IsQuadNeeded isQuadNeeded) + { + SurfaceMesh result; + CubicSurfaceExtractorWithNormals extractor(volData, region, &result, eWrapMode, tBorderValue, isQuadNeeded); + extractor.execute(); + return result; + } + + template + // This is a bit ugly - it seems that the C++03 syntax is different from the C++11 syntax? See this thread: http://stackoverflow.com/questions/6076015/typename-outside-of-template + // Long term we should probably come back to this and if the #ifdef is still needed then maybe it should check for C++11 mode instead of MSVC? +#if defined(_MSC_VER) + SurfaceMesh extractCubicSurfaceWithNormals(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType()) +#else + SurfaceMesh extractCubicSurfaceWithNormals(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()) +#endif + { + DefaultIsQuadNeeded isQuadNeeded; + return extractCubicSurfaceWithNormals >(volData, region, eWrapMode, tBorderValue, isQuadNeeded); + } } #include "PolyVoxCore/CubicSurfaceExtractorWithNormals.inl" diff --git a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h index 31803437..513b02e0 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/MarchingCubesSurfaceExtractor.h @@ -210,6 +210,28 @@ namespace PolyVox //Our threshold value typename Controller::DensityType m_tThreshold; }; + + template< typename VolumeType, typename Controller> + SurfaceMesh extractMarchingCubesSurface(VolumeType* volData, Region region, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, Controller controller) + { + SurfaceMesh result; + MarchingCubesSurfaceExtractor extractor(volData, region, &result, eWrapMode, tBorderValue, controller); + extractor.execute(); + return result; + } + + template< typename VolumeType> + // This is a bit ugly - it seems that the C++03 syntax is different from the C++11 syntax? See this thread: http://stackoverflow.com/questions/6076015/typename-outside-of-template + // Long term we should probably come back to this and if the #ifdef is still needed then maybe it should check for C++11 mode instead of MSVC? +#if defined(_MSC_VER) + SurfaceMesh extractMarchingCubesSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType()) +#else + SurfaceMesh extractMarchingCubesSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType()) +#endif + { + DefaultMarchingCubesController controller; + return extractMarchingCubesSurface(volData, region, eWrapMode, tBorderValue, controller); + } } #include "PolyVoxCore/MarchingCubesSurfaceExtractor.inl" diff --git a/tests/TestCubicSurfaceExtractor.cpp b/tests/TestCubicSurfaceExtractor.cpp index 45919e85..319816d9 100644 --- a/tests/TestCubicSurfaceExtractor.cpp +++ b/tests/TestCubicSurfaceExtractor.cpp @@ -106,10 +106,9 @@ uint32_t testForType(void) { for (int32_t x = 0; x < uVolumeSideLength; x += uRegionSideLength) { - SurfaceMesh result; Region regionToExtract(x, y, z, x + uRegionSideLength - 1, y + uRegionSideLength - 1, z + uRegionSideLength - 1); - CubicSurfaceExtractor< SimpleVolume > extractor(&volData, regionToExtract, &result); - extractor.execute(); + + auto result = extractCubicSurface(&volData, regionToExtract); uTotalVertices += result.getNoOfVertices(); uTotalIndices += result.getNoOfIndices(); diff --git a/tests/TestSurfaceExtractor.cpp b/tests/TestSurfaceExtractor.cpp index 796f3b2c..ac146751 100644 --- a/tests/TestSurfaceExtractor.cpp +++ b/tests/TestSurfaceExtractor.cpp @@ -102,7 +102,7 @@ void writeMaterialValueToVoxel(int valueToWrite, MaterialDensityPair88& voxel) // Runs the surface extractor for a given type. template -void testForType(SurfaceMesh& result) +SurfaceMesh testForType(void) //I think we could avoid specifying this return type by using auto/decltype? { const int32_t uVolumeSideLength = 32; @@ -127,8 +127,10 @@ void testForType(SurfaceMesh& result) DefaultMarchingCubesController controller; controller.setThreshold(50); - MarchingCubesSurfaceExtractor< SimpleVolume > extractor(&volData, volData.getEnclosingRegion(), &result, WrapModes::Border, VoxelType(), controller); - extractor.execute(); + + auto result = extractMarchingCubesSurface(&volData, volData.getEnclosingRegion(), WrapModes::Border, VoxelType(), controller); + + return result; } void testCustomController(SurfaceMesh& result) @@ -167,53 +169,53 @@ void TestSurfaceExtractor::testExecute() //Run the test for various voxel types. QBENCHMARK { - testForType(mesh); + mesh = testForType(); } QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial); - testForType(mesh); + mesh = testForType(); QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices); QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices); QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fExpectedMaterial); diff --git a/tests/TestVolumeSubclass.cpp b/tests/TestVolumeSubclass.cpp index 91a619b4..d4f20825 100644 --- a/tests/TestVolumeSubclass.cpp +++ b/tests/TestVolumeSubclass.cpp @@ -184,9 +184,7 @@ void TestVolumeSubclass::testExtractSurface() } } - SurfaceMesh result; - CubicSurfaceExtractor< VolumeSubclass > cubicSurfaceExtractor(&volumeSubclass, volumeSubclass.getEnclosingRegion(), &result); - cubicSurfaceExtractor.execute(); + auto result = extractCubicSurface(&volumeSubclass, volumeSubclass.getEnclosingRegion()); QCOMPARE(result.getNoOfVertices(), static_cast(8)); }