PolyVox  0.2.1
Open source voxel management library
VolumeResampler.inl
Go to the documentation of this file.
1 /*******************************************************************************
2 Copyright (c) 2005-2009 David Williams
3 
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7 
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11 
12  1. The origin of this software must not be misrepresented; you must not
13  claim that you wrote the original software. If you use this software
14  in a product, an acknowledgment in the product documentation would be
15  appreciated but is not required.
16 
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19 
20  3. This notice may not be removed or altered from any source
21  distribution.
22 *******************************************************************************/
23 
25 
26 namespace PolyVox
27 {
34  template< typename SrcVolumeType, typename DstVolumeType>
35  VolumeResampler<SrcVolumeType, DstVolumeType>::VolumeResampler(SrcVolumeType* pVolSrc, Region regSrc, DstVolumeType* pVolDst, Region regDst)
36  :m_pVolSrc(pVolSrc)
37  ,m_regSrc(regSrc)
38  ,m_pVolDst(pVolDst)
39  ,m_regDst(regDst)
40  {
41  }
42 
43  template< typename SrcVolumeType, typename DstVolumeType>
45  {
46  int32_t uSrcWidth = m_regSrc.getUpperCorner().getX() - m_regSrc.getLowerCorner().getX() + 1;
47  int32_t uSrcHeight = m_regSrc.getUpperCorner().getY() - m_regSrc.getLowerCorner().getY() + 1;
48  int32_t uSrcDepth = m_regSrc.getUpperCorner().getZ() - m_regSrc.getLowerCorner().getZ() + 1;
49 
50  int32_t uDstWidth = m_regDst.getUpperCorner().getX() - m_regDst.getLowerCorner().getX() + 1;
51  int32_t uDstHeight = m_regDst.getUpperCorner().getY() - m_regDst.getLowerCorner().getY() + 1;
52  int32_t uDstDepth = m_regDst.getUpperCorner().getZ() - m_regDst.getLowerCorner().getZ() + 1;
53 
54  if((uSrcWidth == uDstWidth) && (uSrcHeight == uDstHeight) && (uSrcDepth == uDstDepth))
55  {
56  resampleSameSize();
57  }
58  else
59  {
60  resampleArbitrary();
61  }
62  }
63 
64  template< typename SrcVolumeType, typename DstVolumeType>
66  {
67  for(int32_t sz = m_regSrc.getLowerCorner().getZ(), dz = m_regDst.getLowerCorner().getZ(); dz <= m_regDst.getUpperCorner().getZ(); sz++, dz++)
68  {
69  for(int32_t sy = m_regSrc.getLowerCorner().getY(), dy = m_regDst.getLowerCorner().getY(); dy <= m_regDst.getUpperCorner().getY(); sy++, dy++)
70  {
71  for(int32_t sx = m_regSrc.getLowerCorner().getX(), dx = m_regDst.getLowerCorner().getX(); dx <= m_regDst.getUpperCorner().getX(); sx++,dx++)
72  {
73  const typename SrcVolumeType::VoxelType& tSrcVoxel = m_pVolSrc->getVoxelAt(sx,sy,sz);
74  const typename DstVolumeType::VoxelType& tDstVoxel = static_cast<typename DstVolumeType::VoxelType>(tSrcVoxel);
75  m_pVolDst->setVoxelAt(dx,dy,dz,tDstVoxel);
76  }
77  }
78  }
79  }
80 
81  template< typename SrcVolumeType, typename DstVolumeType>
82  void VolumeResampler<SrcVolumeType, DstVolumeType>::resampleArbitrary()
83  {
84  float srcWidth = m_regSrc.getUpperCorner().getX() - m_regSrc.getLowerCorner().getX();
85  float srcHeight = m_regSrc.getUpperCorner().getY() - m_regSrc.getLowerCorner().getY();
86  float srcDepth = m_regSrc.getUpperCorner().getZ() - m_regSrc.getLowerCorner().getZ();
87 
88  float dstWidth = m_regDst.getUpperCorner().getX() - m_regDst.getLowerCorner().getX();
89  float dstHeight = m_regDst.getUpperCorner().getY() - m_regDst.getLowerCorner().getY();
90  float dstDepth = m_regDst.getUpperCorner().getZ() - m_regDst.getLowerCorner().getZ();
91 
92  float fScaleX = srcWidth / dstWidth;
93  float fScaleY = srcHeight / dstHeight;
94  float fScaleZ = srcDepth / dstDepth;
95 
96  typename SrcVolumeType::Sampler sampler(m_pVolSrc);
97 
98  for(int32_t dz = m_regDst.getLowerCorner().getZ(); dz <= m_regDst.getUpperCorner().getZ(); dz++)
99  {
100  for(int32_t dy = m_regDst.getLowerCorner().getY(); dy <= m_regDst.getUpperCorner().getY(); dy++)
101  {
102  for(int32_t dx = m_regDst.getLowerCorner().getX(); dx <= m_regDst.getUpperCorner().getX(); dx++)
103  {
104  float sx = (dx - m_regDst.getLowerCorner().getX()) * fScaleX;
105  float sy = (dy - m_regDst.getLowerCorner().getY()) * fScaleY;
106  float sz = (dz - m_regDst.getLowerCorner().getZ()) * fScaleZ;
107 
108  sx += m_regSrc.getLowerCorner().getX();
109  sy += m_regSrc.getLowerCorner().getY();
110  sz += m_regSrc.getLowerCorner().getZ();
111 
112  sampler.setPosition(sx,sy,sz);
113  const typename SrcVolumeType::VoxelType& voxel000 = sampler.peekVoxel0px0py0pz();
114  const typename SrcVolumeType::VoxelType& voxel001 = sampler.peekVoxel0px0py1pz();
115  const typename SrcVolumeType::VoxelType& voxel010 = sampler.peekVoxel0px1py0pz();
116  const typename SrcVolumeType::VoxelType& voxel011 = sampler.peekVoxel0px1py1pz();
117  const typename SrcVolumeType::VoxelType& voxel100 = sampler.peekVoxel1px0py0pz();
118  const typename SrcVolumeType::VoxelType& voxel101 = sampler.peekVoxel1px0py1pz();
119  const typename SrcVolumeType::VoxelType& voxel110 = sampler.peekVoxel1px1py0pz();
120  const typename SrcVolumeType::VoxelType& voxel111 = sampler.peekVoxel1px1py1pz();
121 
122  //FIXME - should accept all float parameters, but GCC complains?
123  double dummy;
124  sx = modf(sx, &dummy);
125  sy = modf(sy, &dummy);
126  sz = modf(sz, &dummy);
127 
128  typename SrcVolumeType::VoxelType tInterpolatedValue = trilerp<float>(voxel000,voxel100,voxel010,voxel110,voxel001,voxel101,voxel011,voxel111,sx,sy,sz);
129 
130  typename DstVolumeType::VoxelType result = static_cast<typename DstVolumeType::VoxelType>(tInterpolatedValue);
131  m_pVolDst->setVoxelAt(dx,dy,dz,result);
132  }
133  }
134  }
135  }
136 }