24 #ifndef __PolyVox_SurfaceExtractor_H__
25 #define __PolyVox_SurfaceExtractor_H__
36 template<
typename VolumeType,
typename Controller = DefaultMarchingCubesController<
typename VolumeType::VoxelType> >
46 template<
bool isPrevZAvail>
50 template<
bool isPrevXAvail,
bool isPrevYAvail,
bool isPrevZAvail>
51 void computeBitmaskForCell(
const Array2DUint8& pPreviousBitmask,
Array2DUint8& pCurrentBitmask, uint32_t uXRegSpace, uint32_t uYRegSpace);
54 void generateVerticesForSlice(
const Array2DUint8& pCurrentBitmask,
63 Vector3DFloat computeCentralDifferenceGradient(
const typename VolumeType::Sampler& volIter)
68 float voxel1nx =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py0pz()));
69 float voxel1px =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py0pz()));
71 float voxel1ny =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny0pz()));
72 float voxel1py =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py0pz()));
74 float voxel1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1nz()));
75 float voxel1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1pz()));
85 Vector3DFloat computeSobelGradient(
const typename VolumeType::Sampler& volIter)
87 static const int weights[3][3][3] = { { {2,3,2}, {3,6,3}, {2,3,2} }, {
88 {3,6,3}, {6,0,6}, {3,6,3} }, { {2,3,2}, {3,6,3}, {2,3,2} } };
93 const float pVoxel1nx1ny1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1ny1nz()));
94 const float pVoxel1nx1ny0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1ny0pz()));
95 const float pVoxel1nx1ny1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1ny1pz()));
96 const float pVoxel1nx0py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py1nz()));
97 const float pVoxel1nx0py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py0pz()));
98 const float pVoxel1nx0py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py1pz()));
99 const float pVoxel1nx1py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1py1nz()));
100 const float pVoxel1nx1py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1py0pz()));
101 const float pVoxel1nx1py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1py1pz()));
103 const float pVoxel0px1ny1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny1nz()));
104 const float pVoxel0px1ny0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny0pz()));
105 const float pVoxel0px1ny1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny1pz()));
106 const float pVoxel0px0py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1nz()));
108 const float pVoxel0px0py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1pz()));
109 const float pVoxel0px1py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py1nz()));
110 const float pVoxel0px1py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py0pz()));
111 const float pVoxel0px1py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py1pz()));
113 const float pVoxel1px1ny1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1ny1nz()));
114 const float pVoxel1px1ny0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1ny0pz()));
115 const float pVoxel1px1ny1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1ny1pz()));
116 const float pVoxel1px0py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py1nz()));
117 const float pVoxel1px0py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py0pz()));
118 const float pVoxel1px0py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py1pz()));
119 const float pVoxel1px1py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1py1nz()));
120 const float pVoxel1px1py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1py0pz()));
121 const float pVoxel1px1py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1py1pz()));
123 const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
124 weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
125 pVoxel1nx1ny1pz - weights[0][1][0] * pVoxel1nx0py1nz -
126 weights[1][1][0] * pVoxel1nx0py0pz - weights[2][1][0] *
127 pVoxel1nx0py1pz - weights[0][2][0] * pVoxel1nx1py1nz -
128 weights[1][2][0] * pVoxel1nx1py0pz - weights[2][2][0] *
129 pVoxel1nx1py1pz + weights[0][0][2] * pVoxel1px1ny1nz +
130 weights[1][0][2] * pVoxel1px1ny0pz + weights[2][0][2] *
131 pVoxel1px1ny1pz + weights[0][1][2] * pVoxel1px0py1nz +
132 weights[1][1][2] * pVoxel1px0py0pz + weights[2][1][2] *
133 pVoxel1px0py1pz + weights[0][2][2] * pVoxel1px1py1nz +
134 weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
137 const float yGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
138 weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
139 pVoxel1nx1ny1pz + weights[0][2][0] * pVoxel1nx1py1nz +
140 weights[1][2][0] * pVoxel1nx1py0pz + weights[2][2][0] *
141 pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz -
142 weights[1][0][1] * pVoxel0px1ny0pz - weights[2][0][1] *
143 pVoxel0px1ny1pz + weights[0][2][1] * pVoxel0px1py1nz +
144 weights[1][2][1] * pVoxel0px1py0pz + weights[2][2][1] *
145 pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz -
146 weights[1][0][2] * pVoxel1px1ny0pz - weights[2][0][2] *
147 pVoxel1px1ny1pz + weights[0][2][2] * pVoxel1px1py1nz +
148 weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
151 const float zGrad(- weights[0][0][0] * pVoxel1nx1ny1nz +
152 weights[2][0][0] * pVoxel1nx1ny1pz - weights[0][1][0] *
153 pVoxel1nx0py1nz + weights[2][1][0] * pVoxel1nx0py1pz -
154 weights[0][2][0] * pVoxel1nx1py1nz + weights[2][2][0] *
155 pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz +
156 weights[2][0][1] * pVoxel0px1ny1pz - weights[0][1][1] *
157 pVoxel0px0py1nz + weights[2][1][1] * pVoxel0px0py1pz -
158 weights[0][2][1] * pVoxel0px1py1nz + weights[2][2][1] *
159 pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz +
160 weights[2][0][2] * pVoxel1px1ny1pz - weights[0][1][2] *
161 pVoxel1px0py1nz + weights[2][1][2] * pVoxel1px0py1pz -
162 weights[0][2][2] * pVoxel1px1py1nz + weights[2][2][2] *
174 void generateIndicesForSlice(
const Array2DUint8& pPreviousBitmask,
182 VolumeType* m_volData;
183 typename VolumeType::Sampler m_sampVolume;
186 uint32_t m_uNoOfOccupiedCells;
197 Region m_regSlicePrevious;
201 typename Controller::DensityType m_tThreshold;
204 Controller m_controller;