Merge branch 'feature/extractor-refactor' into develop

This commit is contained in:
David Williams 2014-05-12 21:13:26 +02:00
commit 1e0b8e97eb
9 changed files with 91 additions and 40 deletions

View File

@ -76,16 +76,10 @@ int main(int argc, char *argv[])
//Create an empty volume and then place a sphere in it
SimpleVolume<uint8_t> 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<PositionMaterial> mesh;
//Create a surface extractor. Comment out one of the following two lines to decide which type gets created.
CubicSurfaceExtractor< SimpleVolume<uint8_t> > surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
//MarchingCubesSurfaceExtractor< SimpleVolume<uint8_t> > 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);

View File

@ -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<PositionMaterialNormal> mesh;
CubicSurfaceExtractorWithNormals< LargeVolume<MaterialDensityPair44> > surfaceExtractor(&volData, reg, &mesh);
//MarchingCubesSurfaceExtractor< LargeVolume<MaterialDensityPair44> > surfaceExtractor(&volData, reg, &mesh);
//CubicSurfaceExtractorWithNormals<MaterialDensityPair44> 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

View File

@ -90,15 +90,11 @@ int main(int argc, char *argv[])
volumeResampler.execute();
//Extract the surface
SurfaceMesh<PositionMaterialNormal> meshLowLOD;
MarchingCubesSurfaceExtractor< RawVolume<uint8_t> > 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<PositionMaterialNormal> meshHighLOD;
MarchingCubesSurfaceExtractor< SimpleVolume<uint8_t> > 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

View File

@ -157,6 +157,28 @@ namespace PolyVox
WrapMode m_eWrapMode;
typename VolumeType::VoxelType m_tBorderValue;
};
template<typename VolumeType, typename IsQuadNeeded>
SurfaceMesh<PositionMaterial> extractCubicSurface(VolumeType* volData, Region region, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, bool bMergeQuads, IsQuadNeeded isQuadNeeded)
{
SurfaceMesh<PositionMaterial> result;
CubicSurfaceExtractor<VolumeType, IsQuadNeeded> extractor(volData, region, &result, eWrapMode, tBorderValue, bMergeQuads, isQuadNeeded);
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<PositionMaterial> extractCubicSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType(), bool bMergeQuads = true)
#else
SurfaceMesh<PositionMaterial> extractCubicSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType(), bool bMergeQuads = true)
#endif
{
DefaultIsQuadNeeded<typename VolumeType::VoxelType> isQuadNeeded;
return extractCubicSurface<VolumeType, DefaultIsQuadNeeded<typename VolumeType::VoxelType> >(volData, region, eWrapMode, tBorderValue, bMergeQuads, isQuadNeeded);
}
}
#include "PolyVoxCore/CubicSurfaceExtractor.inl"

View File

@ -63,6 +63,28 @@ namespace PolyVox
WrapMode m_eWrapMode;
typename VolumeType::VoxelType m_tBorderValue;
};
template<typename VolumeType, typename IsQuadNeeded>
SurfaceMesh<PositionMaterialNormal> extractCubicSurfaceWithNormals(VolumeType* volData, Region region, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, IsQuadNeeded isQuadNeeded)
{
SurfaceMesh<PositionMaterialNormal> result;
CubicSurfaceExtractorWithNormals<VolumeType, IsQuadNeeded> extractor(volData, region, &result, eWrapMode, tBorderValue, isQuadNeeded);
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<PositionMaterialNormal> extractCubicSurfaceWithNormals(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType())
#else
SurfaceMesh<PositionMaterialNormal> extractCubicSurfaceWithNormals(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType())
#endif
{
DefaultIsQuadNeeded<typename VolumeType::VoxelType> isQuadNeeded;
return extractCubicSurfaceWithNormals<VolumeType, DefaultIsQuadNeeded<typename VolumeType::VoxelType> >(volData, region, eWrapMode, tBorderValue, isQuadNeeded);
}
}
#include "PolyVoxCore/CubicSurfaceExtractorWithNormals.inl"

View File

@ -210,6 +210,28 @@ namespace PolyVox
//Our threshold value
typename Controller::DensityType m_tThreshold;
};
template< typename VolumeType, typename Controller>
SurfaceMesh<PositionMaterialNormal> extractMarchingCubesSurface(VolumeType* volData, Region region, WrapMode eWrapMode, typename VolumeType::VoxelType tBorderValue, Controller controller)
{
SurfaceMesh<PositionMaterialNormal> result;
MarchingCubesSurfaceExtractor<VolumeType, Controller> 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<PositionMaterialNormal> extractMarchingCubesSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = VolumeType::VoxelType())
#else
SurfaceMesh<PositionMaterialNormal> extractMarchingCubesSurface(VolumeType* volData, Region region, WrapMode eWrapMode = WrapModes::Border, typename VolumeType::VoxelType tBorderValue = typename VolumeType::VoxelType())
#endif
{
DefaultMarchingCubesController<typename VolumeType::VoxelType> controller;
return extractMarchingCubesSurface(volData, region, eWrapMode, tBorderValue, controller);
}
}
#include "PolyVoxCore/MarchingCubesSurfaceExtractor.inl"

View File

@ -106,10 +106,9 @@ uint32_t testForType(void)
{
for (int32_t x = 0; x < uVolumeSideLength; x += uRegionSideLength)
{
SurfaceMesh<PositionMaterial> result;
Region regionToExtract(x, y, z, x + uRegionSideLength - 1, y + uRegionSideLength - 1, z + uRegionSideLength - 1);
CubicSurfaceExtractor< SimpleVolume<VoxelType> > extractor(&volData, regionToExtract, &result);
extractor.execute();
auto result = extractCubicSurface(&volData, regionToExtract);
uTotalVertices += result.getNoOfVertices();
uTotalIndices += result.getNoOfIndices();

View File

@ -102,7 +102,7 @@ void writeMaterialValueToVoxel(int valueToWrite, MaterialDensityPair88& voxel)
// Runs the surface extractor for a given type.
template <typename VoxelType>
void testForType(SurfaceMesh<PositionMaterialNormal>& result)
SurfaceMesh<PositionMaterialNormal> 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<PositionMaterialNormal>& result)
DefaultMarchingCubesController<VoxelType> controller;
controller.setThreshold(50);
MarchingCubesSurfaceExtractor< SimpleVolume<VoxelType> > 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<PositionMaterialNormal>& result)
@ -167,53 +169,53 @@ void TestSurfaceExtractor::testExecute()
//Run the test for various voxel types.
QBENCHMARK {
testForType<int8_t>(mesh);
mesh = testForType<int8_t>();
}
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint8_t>(mesh);
mesh = testForType<uint8_t>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<int16_t>(mesh);
mesh = testForType<int16_t>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint16_t>(mesh);
mesh = testForType<uint16_t>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<int32_t>(mesh);
mesh = testForType<int32_t>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<uint32_t>(mesh);
mesh = testForType<uint32_t>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<float>(mesh);
mesh = testForType<float>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<double>(mesh);
mesh = testForType<double>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<Density8>(mesh);
mesh = testForType<Density8>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fNoMaterial);
testForType<MaterialDensityPair88>(mesh);
mesh = testForType<MaterialDensityPair88>();
QCOMPARE(mesh.getNoOfVertices(), uExpectedVertices);
QCOMPARE(mesh.getNoOfIndices(), uExpectedIndices);
QCOMPARE(mesh.getVertices()[uMaterialToCheck].getMaterial(), fExpectedMaterial);

View File

@ -184,9 +184,7 @@ void TestVolumeSubclass::testExtractSurface()
}
}
SurfaceMesh<PositionMaterial> result;
CubicSurfaceExtractor< VolumeSubclass<Material8> > cubicSurfaceExtractor(&volumeSubclass, volumeSubclass.getEnclosingRegion(), &result);
cubicSurfaceExtractor.execute();
auto result = extractCubicSurface(&volumeSubclass, volumeSubclass.getEnclosingRegion());
QCOMPARE(result.getNoOfVertices(), static_cast<uint32_t>(8));
}