Changed interface to SurfaceExtractor.

This commit is contained in:
David Williams 2010-08-21 20:14:40 +00:00
parent 854c8b6fa4
commit 85e5a27457
5 changed files with 27 additions and 23 deletions

View File

@ -82,17 +82,18 @@ Now that we have built our volume we need to convert it into a triangle mesh for
.. code-block:: c++
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(volData);
SurfaceMesh mesh;
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
Again, note thiat this class is templatised on the voxel type. It also takes a reference to the Volume on which the surface extraction will be performed.
The SurfaceExtractor takes a pointer to the volume data, and also it needs to be told which Region of the Volume the extraction should be performed on (in more advanced application this is useful for extracting only those parts of the volume which have been modified since the last extraction). For our purposes the Volume class provides a convienient Volume::getEnclosingRegion() function which returns a Region representing the whole volume. The constructor also takes a pointer to a SurfaceMesh object whiere it will store the result, so we need to create one of these before we can construct the SurfaceExtractor.
The actual extraction happens in the SurfaceExtractor::extractSurfaceForRegion() function. This function needs to be told which Region of the Volume the extraction should be performed on (in more advanced application this is useful for extracting only those parts of the volume which have been modified since the last extraction), but for our purposes the Volume class provides a convienient Volume::getEnclosingRegion() function which returns a Region representing the whole volume.
The actual extraction happens in the SurfaceExtractor::execute() function. This means you can set up your SurfaceExtractor with the required parameters and then actually execute it later (on a different thread, perhaps). For this example we just call it straight away.
.. code-block:: c++
shared_ptr<SurfaceMesh> surface = surfaceExtractor.extractSurfaceForRegion(volData.getEnclosingRegion());
surfaceExtractor.execute();
The result is a SurfaceMesh object, which basically contains an index and vertex buffer representing the desired triangle mesh. This is returned via a shared_ptr, meaning it will automatically be deleted once there are no remaining references to it.
This fills in our SurfaceMesh object, which basically contains an index and vertex buffer representing the desired triangle mesh.
Rendering the surface
=====================

View File

@ -82,11 +82,12 @@ int main(int argc, char *argv[])
createSphereInVolume(volData, 30);
//Extract the surface
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(volData);
shared_ptr<SurfaceMesh> surface = surfaceExtractor.extractSurfaceForRegion(volData.getEnclosingRegion());
SurfaceMesh mesh;
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(&volData, volData.getEnclosingRegion(), &mesh);
surfaceExtractor.execute();
//Pass the surface to the OpenGL window
openGLWidget.setSurfaceMeshToRender(*surface);
openGLWidget.setSurfaceMeshToRender(mesh);
//Run the message pump.
return app.exec();

View File

@ -63,8 +63,6 @@ void OpenGLWidget::setVolume(PolyVox::Volume<MaterialDensityPair44>* volData)
m_uVolumeHeightInRegions = volData->getHeight() / m_uRegionSideLength;
m_uVolumeDepthInRegions = volData->getDepth() / m_uRegionSideLength;
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(*volData);
//Our volume is broken down into cuboid regions, and we create one mesh for each region.
//This three-level for loop iterates over each region.
for(uint16_t uRegionZ = 0; uRegionZ < m_uVolumeDepthInRegions; ++uRegionZ)
@ -90,7 +88,10 @@ void OpenGLWidget::setVolume(PolyVox::Volume<MaterialDensityPair44>* volData)
//Extract the surface for this region
//extractSurface(m_volData, 0, PolyVox::Region(regLowerCorner, regUpperCorner), meshCurrent);
shared_ptr<SurfaceMesh> mesh = surfaceExtractor.extractSurfaceForRegion(PolyVox::Region(regLowerCorner, regUpperCorner));
shared_ptr<SurfaceMesh> mesh(new SurfaceMesh);
SurfaceExtractor<MaterialDensityPair44> surfaceExtractor(volData, PolyVox::Region(regLowerCorner, regUpperCorner), mesh.get());
surfaceExtractor.execute();
//computeNormalsForVertices(m_volData, *(mesh.get()), SOBEL_SMOOTHED);
//*meshCurrent = getSmoothedSurface(*meshCurrent);

View File

@ -39,9 +39,9 @@ namespace PolyVox
class SurfaceExtractor
{
public:
SurfaceExtractor(Volume<VoxelType>& volData);
SurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh* result);
std::shared_ptr<SurfaceMesh> extractSurfaceForRegion(Region region);
void execute();
private:
//Compute the cell bitmask for a particular slice in z.
@ -71,7 +71,7 @@ namespace PolyVox
const Array2DInt32& m_pCurrentVertexIndicesZ);
//The volume data and a sampler to access it.
Volume<VoxelType> m_volData;
Volume<VoxelType>* m_volData;
VolumeSampler<VoxelType> m_sampVolume;
//Holds a position in volume space.
@ -91,6 +91,7 @@ namespace PolyVox
SurfaceMesh* m_meshCurrent;
//Information about the region we are currently processing
Region m_regInput;
Region m_regInputCropped;
Region m_regInputUncropped;
Region m_regVolumeCropped;

View File

@ -32,27 +32,29 @@ using namespace std;
namespace PolyVox
{
template <typename VoxelType>
SurfaceExtractor<VoxelType>::SurfaceExtractor(Volume<VoxelType>& volData)
SurfaceExtractor<VoxelType>::SurfaceExtractor(Volume<VoxelType>* volData, Region region, SurfaceMesh* result)
:m_volData(volData)
,m_sampVolume(&volData)
,m_sampVolume(volData)
,m_regInput(region)
,m_meshCurrent(result)
{
}
template <typename VoxelType>
shared_ptr<SurfaceMesh> SurfaceExtractor<VoxelType>::extractSurfaceForRegion(Region region)
void SurfaceExtractor<VoxelType>::execute()
{
m_regInputUncropped = region;
m_regInputUncropped = m_regInput;
//When generating the mesh for a region we actually look outside it in the
// back, bottom, right direction. Protect against access violations by cropping region here
m_regVolumeCropped = m_volData.getEnclosingRegion();
m_regVolumeCropped = m_volData->getEnclosingRegion();
m_regInputUncropped.cropTo(m_regVolumeCropped);
m_regVolumeCropped.setUpperCorner(m_regVolumeCropped.getUpperCorner() - Vector3DInt16(1,1,1));
m_regInputCropped = region;
m_regInputCropped = m_regInput;
m_regInputCropped.cropTo(m_regVolumeCropped);
m_meshCurrent = new SurfaceMesh();
//m_meshCurrent = new SurfaceMesh();
m_uRegionWidth = m_regInputCropped.width();
m_uRegionHeight = m_regInputCropped.height();
@ -147,8 +149,6 @@ namespace PolyVox
lodRecord.beginIndex = 0;
lodRecord.endIndex = m_meshCurrent->getNoOfIndices();
m_meshCurrent->m_vecLodRecords.push_back(lodRecord);
return shared_ptr<SurfaceMesh>(m_meshCurrent);
}
template<typename VoxelType>