diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h index 4996d79d..586f85d3 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.h @@ -147,7 +147,7 @@ namespace PolyVox }; public: - CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true, IsQuadNeeded isQuadNeeded = IsQuadNeeded()); + CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true); void execute(); @@ -189,17 +189,17 @@ namespace PolyVox }; template > - void extractCubicMesh(VolumeType* volData, Region region, MeshType* result, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true, IsQuadNeeded isQuadNeeded = IsQuadNeeded()) + void extractCubicProvidedMesh(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true) { - CubicSurfaceExtractor extractor(volData, region, result, eWrapMode, tBorderValue, bMergeQuads, isQuadNeeded); + CubicSurfaceExtractor extractor(volData, region, result, isQuadNeeded, eWrapMode, tBorderValue, bMergeQuads); extractor.execute(); } template > - Mesh > extractCubicMesh(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true, IsQuadNeeded isQuadNeeded = IsQuadNeeded()) + Mesh > extractCubicMesh(VolumeType* volData, Region region, IsQuadNeeded isQuadNeeded = IsQuadNeeded(), WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true) { Mesh< CubicVertex > result; - extractCubicMesh(volData, region, &result, eWrapMode, tBorderValue, bMergeQuads, isQuadNeeded); + extractCubicProvidedMesh(volData, region, &result, isQuadNeeded, eWrapMode, tBorderValue, bMergeQuads); return result; } } diff --git a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl index 6ebec5ef..edf8ea7a 100644 --- a/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl +++ b/library/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractor.inl @@ -36,7 +36,7 @@ namespace PolyVox const uint32_t CubicSurfaceExtractor::MaxVerticesPerPosition = 8; template - CubicSurfaceExtractor::CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded) + CubicSurfaceExtractor::CubicSurfaceExtractor(VolumeType* volData, Region region, MeshType* result, IsQuadNeeded isQuadNeeded, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads) :m_volData(volData) ,m_regSizeInVoxels(region) ,m_meshCurrent(result) diff --git a/tests/TestCubicSurfaceExtractor.cpp b/tests/TestCubicSurfaceExtractor.cpp index 77fffbb1..9f8027bf 100644 --- a/tests/TestCubicSurfaceExtractor.cpp +++ b/tests/TestCubicSurfaceExtractor.cpp @@ -33,6 +33,26 @@ freely, subject to the following restrictions: using namespace PolyVox; +template +class CustomIsQuadNeeded +{ +public: + typedef _VoxelType VoxelType; + + bool operator()(VoxelType back, VoxelType front, VoxelType& materialToUse) + { + if ((back > 0) && (front == 0)) + { + materialToUse = static_cast(back); + return true; + } + else + { + return false; + } + } +}; + // These 'writeDensityValueToVoxel' functions provide a unified interface for writting densities to primative and class voxel types. // They are conceptually the inverse of the 'convertToDensity' function used by the MarchingCubesSurfaceExtractor. They probably shouldn't be part @@ -123,12 +143,12 @@ uint32_t testForType(void) // Runs the surface extractor for a given type. template -SimpleVolume* createAndFillVolumeWithNoise(VoxelType maxVoxelValue) +SimpleVolume* createAndFillVolumeWithNoise(VoxelType minValue, VoxelType maxValue) { - const int32_t uVolumeSideLength = 64; + const int32_t uVolumeSideLength = 32; //Create empty volume - SimpleVolume* volData = new SimpleVolume(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)), 32); + SimpleVolume* volData = new SimpleVolume(Region(Vector3DInt32(0, 0, 0), Vector3DInt32(uVolumeSideLength - 1, uVolumeSideLength - 1, uVolumeSideLength - 1)), 16); srand(12345); @@ -139,16 +159,15 @@ SimpleVolume* createAndFillVolumeWithNoise(VoxelType maxVoxelValue) { for (int32_t x = 0; x < uVolumeSideLength; x++) { - if (maxVoxelValue == 0) + if (minValue == maxValue) { - // This test case is currently only dealing with unsigned voxel, so if - // the max requested voxel value is zero then every voxel should be zero - volData->setVoxelAt(x, y, z, VoxelType(0)); + // In this case we are filling the whole volume with a single value. + volData->setVoxelAt(x, y, z, minValue); } else { // Otherwise we write random voxel values between zero and the requested maximum - int voxelValue = rand() % (maxVoxelValue + 1); + int voxelValue = (rand() % (maxValue - minValue + 1)) + minValue; volData->setVoxelAt(x, y, z, static_cast(voxelValue)); } } @@ -222,10 +241,27 @@ void TestCubicSurfaceExtractor::testExecute() } QCOMPARE(result, uExpectedSumOfVerticesAndIndices); - auto volData = createAndFillVolumeWithNoise(2); - auto mesh = extractCubicMesh(volData, volData->getEnclosingRegion()); - QCOMPARE(mesh.getNoOfVertices(), uint32_t(451651)); - QCOMPARE(mesh.getNoOfIndices(), uint32_t(1715934)); + auto uint8Vol = createAndFillVolumeWithNoise(0, 2); + auto uint8Mesh = extractCubicMesh(uint8Vol, uint8Vol->getEnclosingRegion()); + QCOMPARE(uint8Mesh.getNoOfVertices(), uint32_t(57687)); + QCOMPARE(uint8Mesh.getNoOfIndices(), uint32_t(216234)); + + auto int8Vol = createAndFillVolumeWithNoise(0, 2); + auto int8Mesh = extractCubicMesh(int8Vol, int8Vol->getEnclosingRegion(), DefaultIsQuadNeeded()); + QCOMPARE(int8Mesh.getNoOfVertices(), uint32_t(57687)); + QCOMPARE(int8Mesh.getNoOfIndices(), uint32_t(216234)); + + auto uint32Vol = createAndFillVolumeWithNoise(0, 2); + Mesh< CubicVertex< uint32_t >, uint16_t > uint32Mesh; + extractCubicProvidedMesh(uint32Vol, uint32Vol->getEnclosingRegion(), &uint32Mesh); + QCOMPARE(uint32Mesh.getNoOfVertices(), uint16_t(57687)); + QCOMPARE(uint32Mesh.getNoOfIndices(), uint32_t(216234)); + + auto int32Vol = createAndFillVolumeWithNoise(0, 2); + Mesh< CubicVertex< int32_t >, uint16_t > int32Mesh; + extractCubicProvidedMesh(int32Vol, int32Vol->getEnclosingRegion(), &int32Mesh, DefaultIsQuadNeeded()); + QCOMPARE(int32Mesh.getNoOfVertices(), uint16_t(57687)); + QCOMPARE(int32Mesh.getNoOfIndices(), uint32_t(216234)); }