24 #ifndef __PolyVox_SurfaceExtractor_H__
25 #define __PolyVox_SurfaceExtractor_H__
37 template<
typename VolumeType,
typename Controller = DefaultMarchingCubesController<
typename VolumeType::VoxelType> >
53 template<
bool isPrevZAvail>
57 template<
bool isPrevXAvail,
bool isPrevYAvail,
bool isPrevZAvail>
61 void generateVerticesForSlice(
const Array2DUint8& pCurrentBitmask,
70 Vector3DFloat computeCentralDifferenceGradient(
const typename VolumeType::Sampler& volIter)
75 float voxel1nx =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py0pz()));
76 float voxel1px =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py0pz()));
78 float voxel1ny =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny0pz()));
79 float voxel1py =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py0pz()));
81 float voxel1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1nz()));
82 float voxel1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1pz()));
92 Vector3DFloat computeSobelGradient(
const typename VolumeType::Sampler& volIter)
94 static const int weights[3][3][3] = { { {2,3,2}, {3,6,3}, {2,3,2} }, {
95 {3,6,3}, {6,0,6}, {3,6,3} }, { {2,3,2}, {3,6,3}, {2,3,2} } };
100 const float pVoxel1nx1ny1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1ny1nz()));
101 const float pVoxel1nx1ny0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1ny0pz()));
102 const float pVoxel1nx1ny1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1ny1pz()));
103 const float pVoxel1nx0py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py1nz()));
104 const float pVoxel1nx0py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py0pz()));
105 const float pVoxel1nx0py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx0py1pz()));
106 const float pVoxel1nx1py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1py1nz()));
107 const float pVoxel1nx1py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1py0pz()));
108 const float pVoxel1nx1py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1nx1py1pz()));
110 const float pVoxel0px1ny1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny1nz()));
111 const float pVoxel0px1ny0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny0pz()));
112 const float pVoxel0px1ny1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1ny1pz()));
113 const float pVoxel0px0py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1nz()));
115 const float pVoxel0px0py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px0py1pz()));
116 const float pVoxel0px1py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py1nz()));
117 const float pVoxel0px1py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py0pz()));
118 const float pVoxel0px1py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel0px1py1pz()));
120 const float pVoxel1px1ny1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1ny1nz()));
121 const float pVoxel1px1ny0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1ny0pz()));
122 const float pVoxel1px1ny1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1ny1pz()));
123 const float pVoxel1px0py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py1nz()));
124 const float pVoxel1px0py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py0pz()));
125 const float pVoxel1px0py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px0py1pz()));
126 const float pVoxel1px1py1nz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1py1nz()));
127 const float pVoxel1px1py0pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1py0pz()));
128 const float pVoxel1px1py1pz =
static_cast<float>(m_controller.convertToDensity(volIter.peekVoxel1px1py1pz()));
130 const float xGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
131 weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
132 pVoxel1nx1ny1pz - weights[0][1][0] * pVoxel1nx0py1nz -
133 weights[1][1][0] * pVoxel1nx0py0pz - weights[2][1][0] *
134 pVoxel1nx0py1pz - weights[0][2][0] * pVoxel1nx1py1nz -
135 weights[1][2][0] * pVoxel1nx1py0pz - weights[2][2][0] *
136 pVoxel1nx1py1pz + weights[0][0][2] * pVoxel1px1ny1nz +
137 weights[1][0][2] * pVoxel1px1ny0pz + weights[2][0][2] *
138 pVoxel1px1ny1pz + weights[0][1][2] * pVoxel1px0py1nz +
139 weights[1][1][2] * pVoxel1px0py0pz + weights[2][1][2] *
140 pVoxel1px0py1pz + weights[0][2][2] * pVoxel1px1py1nz +
141 weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
144 const float yGrad(- weights[0][0][0] * pVoxel1nx1ny1nz -
145 weights[1][0][0] * pVoxel1nx1ny0pz - weights[2][0][0] *
146 pVoxel1nx1ny1pz + weights[0][2][0] * pVoxel1nx1py1nz +
147 weights[1][2][0] * pVoxel1nx1py0pz + weights[2][2][0] *
148 pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz -
149 weights[1][0][1] * pVoxel0px1ny0pz - weights[2][0][1] *
150 pVoxel0px1ny1pz + weights[0][2][1] * pVoxel0px1py1nz +
151 weights[1][2][1] * pVoxel0px1py0pz + weights[2][2][1] *
152 pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz -
153 weights[1][0][2] * pVoxel1px1ny0pz - weights[2][0][2] *
154 pVoxel1px1ny1pz + weights[0][2][2] * pVoxel1px1py1nz +
155 weights[1][2][2] * pVoxel1px1py0pz + weights[2][2][2] *
158 const float zGrad(- weights[0][0][0] * pVoxel1nx1ny1nz +
159 weights[2][0][0] * pVoxel1nx1ny1pz - weights[0][1][0] *
160 pVoxel1nx0py1nz + weights[2][1][0] * pVoxel1nx0py1pz -
161 weights[0][2][0] * pVoxel1nx1py1nz + weights[2][2][0] *
162 pVoxel1nx1py1pz - weights[0][0][1] * pVoxel0px1ny1nz +
163 weights[2][0][1] * pVoxel0px1ny1pz - weights[0][1][1] *
164 pVoxel0px0py1nz + weights[2][1][1] * pVoxel0px0py1pz -
165 weights[0][2][1] * pVoxel0px1py1nz + weights[2][2][1] *
166 pVoxel0px1py1pz - weights[0][0][2] * pVoxel1px1ny1nz +
167 weights[2][0][2] * pVoxel1px1ny1pz - weights[0][1][2] *
168 pVoxel1px0py1nz + weights[2][1][2] * pVoxel1px0py1pz -
169 weights[0][2][2] * pVoxel1px1py1nz + weights[2][2][2] *
181 void generateIndicesForSlice(
const Array2DUint8& pPreviousBitmask,
189 VolumeType* m_volData;
190 typename VolumeType::Sampler m_sampVolume;
204 Region m_regSlicePrevious;
208 Controller m_controller;
211 typename Controller::DensityType m_tThreshold;