00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 namespace PolyVox
00025 {
00026 template< template<typename> class SrcVolumeType, template<typename> class DestVolumeType, typename VoxelType>
00027 LowPassFilter<SrcVolumeType, DestVolumeType, VoxelType>::LowPassFilter(SrcVolumeType<VoxelType>* pVolSrc, Region regSrc, DestVolumeType<VoxelType>* pVolDst, Region regDst, uint32_t uKernelSize)
00028 :m_pVolSrc(pVolSrc)
00029 ,m_regSrc(regSrc)
00030 ,m_pVolDst(pVolDst)
00031 ,m_regDst(regDst)
00032 ,m_uKernelSize(uKernelSize)
00033 {
00034
00035 assert(m_uKernelSize >= 3);
00036 m_uKernelSize = std::max(m_uKernelSize, static_cast<uint32_t>(3));
00037
00038
00039 assert(m_uKernelSize % 2 == 1);
00040 if(m_uKernelSize % 2 == 0)
00041 {
00042 m_uKernelSize++;
00043 }
00044 }
00045
00046 template< template<typename> class SrcVolumeType, template<typename> class DestVolumeType, typename VoxelType>
00047 void LowPassFilter<SrcVolumeType, DestVolumeType, VoxelType>::execute()
00048 {
00049 int32_t iSrcMinX = m_regSrc.getLowerCorner().getX();
00050 int32_t iSrcMinY = m_regSrc.getLowerCorner().getY();
00051 int32_t iSrcMinZ = m_regSrc.getLowerCorner().getZ();
00052
00053 int32_t iSrcMaxX = m_regSrc.getUpperCorner().getX();
00054 int32_t iSrcMaxY = m_regSrc.getUpperCorner().getY();
00055 int32_t iSrcMaxZ = m_regSrc.getUpperCorner().getZ();
00056
00057 int32_t iDstMinX = m_regDst.getLowerCorner().getX();
00058 int32_t iDstMinY = m_regDst.getLowerCorner().getY();
00059 int32_t iDstMinZ = m_regDst.getLowerCorner().getZ();
00060
00061
00062
00063
00064
00065 typename SrcVolumeType<VoxelType>::Sampler srcSampler(m_pVolSrc);
00066
00067 for(int32_t iSrcZ = iSrcMinZ, iDstZ = iDstMinZ; iSrcZ <= iSrcMaxZ; iSrcZ++, iDstZ++)
00068 {
00069 for(int32_t iSrcY = iSrcMinY, iDstY = iDstMinY; iSrcY <= iSrcMaxY; iSrcY++, iDstY++)
00070 {
00071 for(int32_t iSrcX = iSrcMinX, iDstX = iDstMinX; iSrcX <= iSrcMaxX; iSrcX++, iDstX++)
00072 {
00073
00074 srcSampler.setPosition(iSrcX, iSrcY, iSrcZ);
00075
00076 VoxelType tSrcVoxel = srcSampler.getVoxel();
00077
00078 uint32_t uDensity = 0;
00079 uDensity += srcSampler.peekVoxel1nx1ny1nz().getDensity();
00080 uDensity += srcSampler.peekVoxel1nx1ny0pz().getDensity();
00081 uDensity += srcSampler.peekVoxel1nx1ny1pz().getDensity();
00082 uDensity += srcSampler.peekVoxel1nx0py1nz().getDensity();
00083 uDensity += srcSampler.peekVoxel1nx0py0pz().getDensity();
00084 uDensity += srcSampler.peekVoxel1nx0py1pz().getDensity();
00085 uDensity += srcSampler.peekVoxel1nx1py1nz().getDensity();
00086 uDensity += srcSampler.peekVoxel1nx1py0pz().getDensity();
00087 uDensity += srcSampler.peekVoxel1nx1py1pz().getDensity();
00088
00089 uDensity += srcSampler.peekVoxel0px1ny1nz().getDensity();
00090 uDensity += srcSampler.peekVoxel0px1ny0pz().getDensity();
00091 uDensity += srcSampler.peekVoxel0px1ny1pz().getDensity();
00092 uDensity += srcSampler.peekVoxel0px0py1nz().getDensity();
00093 uDensity += srcSampler.peekVoxel0px0py0pz().getDensity();
00094 uDensity += srcSampler.peekVoxel0px0py1pz().getDensity();
00095 uDensity += srcSampler.peekVoxel0px1py1nz().getDensity();
00096 uDensity += srcSampler.peekVoxel0px1py0pz().getDensity();
00097 uDensity += srcSampler.peekVoxel0px1py1pz().getDensity();
00098
00099 uDensity += srcSampler.peekVoxel1px1ny1nz().getDensity();
00100 uDensity += srcSampler.peekVoxel1px1ny0pz().getDensity();
00101 uDensity += srcSampler.peekVoxel1px1ny1pz().getDensity();
00102 uDensity += srcSampler.peekVoxel1px0py1nz().getDensity();
00103 uDensity += srcSampler.peekVoxel1px0py0pz().getDensity();
00104 uDensity += srcSampler.peekVoxel1px0py1pz().getDensity();
00105 uDensity += srcSampler.peekVoxel1px1py1nz().getDensity();
00106 uDensity += srcSampler.peekVoxel1px1py0pz().getDensity();
00107 uDensity += srcSampler.peekVoxel1px1py1pz().getDensity();
00108
00109 uDensity /= 27;
00110
00111 tSrcVoxel.setDensity(uDensity);
00112 m_pVolDst->setVoxelAt(iSrcX, iSrcY, iSrcZ, tSrcVoxel);
00113 }
00114 }
00115 }
00116 }
00117
00118 template< template<typename> class SrcVolumeType, template<typename> class DestVolumeType, typename VoxelType>
00119 void LowPassFilter<SrcVolumeType, DestVolumeType, VoxelType>::executeSAT()
00120 {
00121 const int border = m_uKernelSize - 1;
00122
00123 Vector3DInt32 satLowerCorner = m_regSrc.getLowerCorner() - Vector3DInt32(border+1, border+1, border+1);
00124 Vector3DInt32 satUpperCorner = m_regSrc.getUpperCorner() + Vector3DInt32(border, border, border);
00125
00126 RawVolume<uint32_t> satVolume(Region(satLowerCorner, satUpperCorner));
00127
00128
00129 for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
00130 {
00131 for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
00132 {
00133 for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
00134 {
00135 satVolume.setVoxelAt(x,y,z,0);
00136 }
00137 }
00138 }
00139
00140 RawVolume<uint32_t>::Sampler satVolumeIter(&satVolume);
00141
00142 IteratorController<RawVolume<uint32_t>::Sampler> satIterCont;
00143 satIterCont.m_regValid = Region(satLowerCorner, satUpperCorner);
00144 satIterCont.m_Iter = &satVolumeIter;
00145 satIterCont.reset();
00146
00147 typename SrcVolumeType<VoxelType>::Sampler srcVolumeIter(m_pVolSrc);
00148
00149 IteratorController<typename SrcVolumeType<VoxelType>::Sampler> srcIterCont;
00150 srcIterCont.m_regValid = Region(satLowerCorner, satUpperCorner);
00151 srcIterCont.m_Iter = &srcVolumeIter;
00152 srcIterCont.reset();
00153
00154 do
00155 {
00156 uint32_t previousSum = satVolumeIter.peekVoxel1nx0py0pz();
00157
00158 uint32_t currentVal = srcVolumeIter.getVoxel().getDensity();
00159
00160 satVolumeIter.setVoxel(previousSum + currentVal);
00161
00162 srcIterCont.moveForward();
00163
00164 }while(satIterCont.moveForward());
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
00182 {
00183 for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
00184 {
00185 for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
00186 {
00187 uint32_t previousSum = satVolume.getVoxelAt(x,y-1,z);
00188 uint32_t currentSum = satVolume.getVoxelAt(x,y,z);
00189
00190 satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
00191 }
00192 }
00193 }
00194
00195 for(int32_t z = satLowerCorner.getZ(); z <= satUpperCorner.getZ(); z++)
00196 {
00197 for(int32_t y = satLowerCorner.getY(); y <= satUpperCorner.getY(); y++)
00198 {
00199 for(int32_t x = satLowerCorner.getX(); x <= satUpperCorner.getX(); x++)
00200 {
00201 uint32_t previousSum = satVolume.getVoxelAt(x,y,z-1);
00202 uint32_t currentSum = satVolume.getVoxelAt(x,y,z);
00203
00204 satVolume.setVoxelAt(x,y,z,previousSum + currentSum);
00205 }
00206 }
00207 }
00208
00209
00210 const Vector3DInt32& v3dDestLowerCorner = m_regDst.getLowerCorner();
00211 const Vector3DInt32& v3dDestUpperCorner = m_regDst.getUpperCorner();
00212
00213 const Vector3DInt32& v3dSrcLowerCorner = m_regSrc.getLowerCorner();
00214 const Vector3DInt32& v3dSrcUpperCorner = m_regSrc.getUpperCorner();
00215
00216 for(int32_t iDstZ = v3dDestLowerCorner.getZ(), iSrcZ = v3dSrcLowerCorner.getZ(); iDstZ <= v3dDestUpperCorner.getZ(); iDstZ++, iSrcZ++)
00217 {
00218 for(int32_t iDstY = v3dDestLowerCorner.getY(), iSrcY = v3dSrcLowerCorner.getY(); iDstY <= v3dDestUpperCorner.getY(); iDstY++, iSrcY++)
00219 {
00220 for(int32_t iDstX = v3dDestLowerCorner.getX(), iSrcX = v3dSrcLowerCorner.getX(); iDstX <= v3dDestUpperCorner.getX(); iDstX++, iSrcX++)
00221 {
00222 int32_t satLowerX = iSrcX - border - 1;
00223 int32_t satLowerY = iSrcY - border - 1;
00224 int32_t satLowerZ = iSrcZ - border - 1;
00225
00226 int32_t satUpperX = iSrcX + border;
00227 int32_t satUpperY = iSrcY + border;
00228 int32_t satUpperZ = iSrcZ + border;
00229
00230 int32_t a = satVolume.getVoxelAt(satLowerX,satLowerY,satLowerZ);
00231 int32_t b = satVolume.getVoxelAt(satUpperX,satLowerY,satLowerZ);
00232 int32_t c = satVolume.getVoxelAt(satLowerX,satUpperY,satLowerZ);
00233 int32_t d = satVolume.getVoxelAt(satUpperX,satUpperY,satLowerZ);
00234 int32_t e = satVolume.getVoxelAt(satLowerX,satLowerY,satUpperZ);
00235 int32_t f = satVolume.getVoxelAt(satUpperX,satLowerY,satUpperZ);
00236 int32_t g = satVolume.getVoxelAt(satLowerX,satUpperY,satUpperZ);
00237 int32_t h = satVolume.getVoxelAt(satUpperX,satUpperY,satUpperZ);
00238
00239 int32_t sum = h+c-d-g-f-a+b+e;
00240
00241 int32_t sideLength = border * 2 + 1;
00242
00243 int32_t average = sum / (sideLength*sideLength*sideLength);
00244
00245 VoxelType voxel = m_pVolSrc->getVoxelAt(iDstX, iDstY, iDstZ);
00246
00247 voxel.setDensity(average);
00248
00249 m_pVolDst->setVoxelAt(iDstX, iDstY, iDstZ, voxel);
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 }
00262 }
00263 }
00264 }
00265 }