00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __PolyVox_SurfaceExtractor_H__
00025 #define __PolyVox_SurfaceExtractor_H__
00026
00027 #include "PolyVoxImpl/MarchingCubesTables.h"
00028 #include "PolyVoxImpl/TypeDef.h"
00029
00030 #include "PolyVoxCore/Array.h"
00031 #include "PolyVoxCore/SurfaceMesh.h"
00032
00033 namespace PolyVox
00034 {
00035 template< template<typename> class VolumeType, typename VoxelType>
00036 class SurfaceExtractor
00037 {
00038 public:
00039 SurfaceExtractor(VolumeType<VoxelType>* volData, Region region, SurfaceMesh<PositionMaterialNormal>* result);
00040
00041 void execute();
00042
00043 private:
00044
00045 template<bool isPrevZAvail>
00046 uint32_t computeBitmaskForSlice(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask);
00047
00048
00049 template<bool isPrevXAvail, bool isPrevYAvail, bool isPrevZAvail>
00050 void computeBitmaskForCell(const Array2DUint8& pPreviousBitmask, Array2DUint8& pCurrentBitmask);
00051
00052
00053 void generateVerticesForSlice(const Array2DUint8& pCurrentBitmask,
00054 Array2DInt32& m_pCurrentVertexIndicesX,
00055 Array2DInt32& m_pCurrentVertexIndicesY,
00056 Array2DInt32& m_pCurrentVertexIndicesZ);
00057
00059
00060
00062 Vector3DFloat computeCentralDifferenceGradient(const typename VolumeType<VoxelType>::Sampler& volIter)
00063 {
00064
00065
00066
00067 float voxel1nx = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity());
00068 float voxel1px = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity());
00069
00070 float voxel1ny = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity());
00071 float voxel1py = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity());
00072
00073 float voxel1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity());
00074 float voxel1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity());
00075
00076 return Vector3DFloat
00077 (
00078 voxel1nx - voxel1px,
00079 voxel1ny - voxel1py,
00080 voxel1nz - voxel1pz
00081 );
00082 }
00083
00084 Vector3DFloat computeSobelGradient(const typename VolumeType<VoxelType>::Sampler& volIter)
00085 {
00086 static const int weights[3][3][3] = { { {2,3,2}, {3,6,3}, {2,3,2} }, {
00087 {3,6,3}, {6,0,6}, {3,6,3} }, { {2,3,2}, {3,6,3}, {2,3,2} } };
00088
00089
00090
00091
00092 const float pVoxel1nx1ny1nz = static_cast<float>(volIter.peekVoxel1nx1ny1nz().getDensity());
00093 const float pVoxel1nx1ny0pz = static_cast<float>(volIter.peekVoxel1nx1ny0pz().getDensity());
00094 const float pVoxel1nx1ny1pz = static_cast<float>(volIter.peekVoxel1nx1ny1pz().getDensity());
00095 const float pVoxel1nx0py1nz = static_cast<float>(volIter.peekVoxel1nx0py1nz().getDensity());
00096 const float pVoxel1nx0py0pz = static_cast<float>(volIter.peekVoxel1nx0py0pz().getDensity());
00097 const float pVoxel1nx0py1pz = static_cast<float>(volIter.peekVoxel1nx0py1pz().getDensity());
00098 const float pVoxel1nx1py1nz = static_cast<float>(volIter.peekVoxel1nx1py1nz().getDensity());
00099 const float pVoxel1nx1py0pz = static_cast<float>(volIter.peekVoxel1nx1py0pz().getDensity());
00100 const float pVoxel1nx1py1pz = static_cast<float>(volIter.peekVoxel1nx1py1pz().getDensity());
00101
00102 const float pVoxel0px1ny1nz = static_cast<float>(volIter.peekVoxel0px1ny1nz().getDensity());
00103 const float pVoxel0px1ny0pz = static_cast<float>(volIter.peekVoxel0px1ny0pz().getDensity());
00104 const float pVoxel0px1ny1pz = static_cast<float>(volIter.peekVoxel0px1ny1pz().getDensity());
00105 const float pVoxel0px0py1nz = static_cast<float>(volIter.peekVoxel0px0py1nz().getDensity());
00106
00107 const float pVoxel0px0py1pz = static_cast<float>(volIter.peekVoxel0px0py1pz().getDensity());
00108 const float pVoxel0px1py1nz = static_cast<float>(volIter.peekVoxel0px1py1nz().getDensity());
00109 const float pVoxel0px1py0pz = static_cast<float>(volIter.peekVoxel0px1py0pz().getDensity());
00110 const float pVoxel0px1py1pz = static_cast<float>(volIter.peekVoxel0px1py1pz().getDensity());
00111
00112 const float pVoxel1px1ny1nz = static_cast<float>(volIter.peekVoxel1px1ny1nz().getDensity());
00113 const float pVoxel1px1ny0pz = static_cast<float>(volIter.peekVoxel1px1ny0pz().getDensity());
00114 const float pVoxel1px1ny1pz = static_cast<float>(volIter.peekVoxel1px1ny1pz().getDensity());
00115 const float pVoxel1px0py1nz = static_cast<float>(volIter.peekVoxel1px0py1nz().getDensity());
00116 const float pVoxel1px0py0pz = static_cast<float>(volIter.peekVoxel1px0py0pz().getDensity());
00117 const float pVoxel1px0py1pz = static_cast<float>(volIter.peekVoxel1px0py1pz().getDensity());
00118 const float pVoxel1px1py1nz = static_cast<float>(volIter.peekVoxel1px1py1nz().getDensity());
00119 const float pVoxel1px1py0pz = static_cast<float>(volIter.peekVoxel1px1py0pz().getDensity());
00120 const float pVoxel1px1py1pz = static_cast<float>(volIter.peekVoxel1px1py1pz().getDensity());
00121
00122 const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
00123 weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
00124 pVoxel1nx1ny1pz - weights[0][1][0] * pVoxel1nx0py1nz -
00125 weights[1][1][0] * pVoxel1nx0py0pz - weights[2][1][0] *
00126 pVoxel1nx0py1pz - weights[0][2][0] * pVoxel1nx1py1nz -
00127 weights[1][2][0] * pVoxel1nx1py0pz - weights[2][2][0] *
00128 pVoxel1nx1py1pz + weights[0][0][2] * pVoxel1px1ny1nz +
00129 weights[1][0][2] * pVoxel1px1ny0pz + weights[2][0][2] *
00130 pVoxel1px1ny1pz + weights[0][1][2] * pVoxel1px0py1nz +
00131 weights[1][1][2] * pVoxel1px0py0pz + weights[2][1][2] *
00132 pVoxel1px0py1pz + weights[0][2][2] * pVoxel1px1py1nz +
00133 weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
00134 pVoxel1px1py1pz);
00135
00136 const float yGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
00137 weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
00138 pVoxel1nx1ny1pz + weights[0][2][0] * pVoxel1nx1py1nz +
00139 weights[1][2][0] * pVoxel1nx1py0pz + weights[2][2][0] *
00140 pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz -
00141 weights[1][0][1] * pVoxel0px1ny0pz - weights[2][0][1] *
00142 pVoxel0px1ny1pz + weights[0][2][1] * pVoxel0px1py1nz +
00143 weights[1][2][1] * pVoxel0px1py0pz + weights[2][2][1] *
00144 pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz -
00145 weights[1][0][2] * pVoxel1px1ny0pz - weights[2][0][2] *
00146 pVoxel1px1ny1pz + weights[0][2][2] * pVoxel1px1py1nz +
00147 weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
00148 pVoxel1px1py1pz);
00149
00150 const float zGrad(- weights[0][0][0] * pVoxel1nx1ny1nz +
00151 weights[2][0][0] * pVoxel1nx1ny1pz - weights[0][1][0] *
00152 pVoxel1nx0py1nz + weights[2][1][0] * pVoxel1nx0py1pz -
00153 weights[0][2][0] * pVoxel1nx1py1nz + weights[2][2][0] *
00154 pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz +
00155 weights[2][0][1] * pVoxel0px1ny1pz - weights[0][1][1] *
00156 pVoxel0px0py1nz + weights[2][1][1] * pVoxel0px0py1pz -
00157 weights[0][2][1] * pVoxel0px1py1nz + weights[2][2][1] *
00158 pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz +
00159 weights[2][0][2] * pVoxel1px1ny1pz - weights[0][1][2] *
00160 pVoxel1px0py1nz + weights[2][1][2] * pVoxel1px0py1pz -
00161 weights[0][2][2] * pVoxel1px1py1nz + weights[2][2][2] *
00162 pVoxel1px1py1pz);
00163
00164
00165
00166 return Vector3DFloat(-xGrad,-yGrad,-zGrad);
00167 }
00169
00171
00172
00173 void generateIndicesForSlice(const Array2DUint8& pPreviousBitmask,
00174 const Array2DInt32& m_pPreviousVertexIndicesX,
00175 const Array2DInt32& m_pPreviousVertexIndicesY,
00176 const Array2DInt32& m_pPreviousVertexIndicesZ,
00177 const Array2DInt32& m_pCurrentVertexIndicesX,
00178 const Array2DInt32& m_pCurrentVertexIndicesY);
00179
00180
00181 VolumeType<VoxelType>* m_volData;
00182 typename VolumeType<VoxelType>::Sampler m_sampVolume;
00183
00184
00185 int32_t iXVolSpace;
00186 int32_t iYVolSpace;
00187 int32_t iZVolSpace;
00188
00189
00190 uint32_t uXRegSpace;
00191 uint32_t uYRegSpace;
00192 uint32_t uZRegSpace;
00193
00194
00195 uint32_t m_uNoOfOccupiedCells;
00196
00197
00198 SurfaceMesh<PositionMaterialNormal>* m_meshCurrent;
00199
00200
00201 Region m_regSizeInVoxels;
00202 Region m_regSizeInCells;
00203
00204
00205
00206 Region m_regSlicePrevious;
00207 Region m_regSliceCurrent;
00208 };
00209 }
00210
00211 #include "PolyVoxCore/SurfaceExtractor.inl"
00212
00213 #endif