Voxel
 All Classes Namespaces Files Functions Typedefs Enumerations Enumerator Macros Pages
renderer_detail_normal_mrf.cpp
1 #include "renderer_detail_normal_mrf.h"
2 #include "renderer_detail_normal_mrf_helpers.h"
3 
4 #include <limits>
5 #include <cmath>
6 
7 
8 
9 
10 namespace Renderer {
11 
12 
13 namespace detail {
14 
15 
16 
17 
18 /*==============================================================================
19  NormalMRF methods
20 ==============================================================================*/
21 
22 
23 void NormalMRF::CalculateNormals(
24  Vector< float, 3 >* const normals,
25  Vector< double, 2 > const fieldOfView,
26  Vector< double, 3 > const xx,
27  Vector< double, 3 > const yy,
28  Vector< double, 3 > const zz
29 )
30 {
31  assert( m_coarseness == 0 );
32 
33  Vector< double, 2 > const spread = 2 * fieldOfView / m_dimension;
34  Vector< double, 3 > const spreadX = spread[ 0 ] * xx;
35  Vector< double, 3 > const spreadY = spread[ 1 ] * yy;
36 
37  #pragma omp parallel for
38  for ( int ii = 0; ii < static_cast< int >( m_dimension[ 1 ] ); ++ii ) {
39 
40  Vector< double, 3 > ray = (
41  ( 0.5 - 0.5 * m_dimension[ 0 ] ) * spreadX -
42  ( ii + 0.5 - 0.5 * m_dimension[ 1 ] ) * spreadY -
43  zz
44  );
45 
46  unsigned int const offset = ii * m_dimension[ 0 ];
47  for ( int jj = 0; jj < static_cast< int >( m_dimension[ 0 ] ); ++jj ) {
48 
49  Vector< double, 3 > normal = { { 0, 0, 0 } };
50 
51  double const reciprocalDepth = m_states[ offset + jj ].first;
52  if ( reciprocalDepth > 0 ) {
53 
54  double const depth = 1 / reciprocalDepth;
55  Vector< double, 2 > const gradient = -Square( depth ) * m_states[ offset + jj ].second;
56 
57  Vector< double, 3 > horizontalDifference = gradient[ 0 ] * ray + ( gradient[ 0 ] + depth ) * spreadX;
58  Vector< double, 3 > verticalDifference = gradient[ 1 ] * ray - ( gradient[ 1 ] + depth ) * spreadY;
59 
60  normal = Cross( horizontalDifference, -verticalDifference );
61  normal /= normal.Norm();
62  }
63  normals[ offset + jj ] = normal;
64 
65  ray += spreadX;
66  }
67  }
68 }
69 
70 
71 void NormalMRF::SmoothHorizontal( bool const odd, bool const decreasing ) {
72 
73  unsigned int const size = ( 1u << m_coarseness );
74 
75  int jjBegin = 0;
76  int jjEnd = ( ( m_dimension[ 0 ] - 1 ) & ~( size - 1 ) );
77  int jjDelta = size;
78  if ( decreasing ) {
79 
80  std::swap( jjBegin, jjEnd );
81  jjDelta = -jjDelta;
82  }
83  jjEnd += jjDelta;
84 
85  #pragma omp parallel for
86  for ( int ii = ( odd ? size : 0 ); ii < static_cast< int >( m_dimension[ 1 ] ); ii += size * 2 ) {
87 
88  for ( int jj = jjBegin; jj != jjEnd; jj += jjDelta ) {
89 
90  assert( ( jj >= 0 ) && ( jj < m_dimension[ 0 ] ) );
91  Vector< unsigned int, 2 > const coordinates = { { jj, ii } };
92  SolveCardinal(
93  m_depths.get(),
94  m_states.get(),
95  m_dimension,
96  coordinates,
97  size,
98  size,
99  m_spread,
100  m_voxelSize,
101  Square( size ) * m_observationPrecision,
102  m_gradientPrecision,
103  m_minimumEdgeDelta,
104  m_maximumEdgeDelta
105  );
106  }
107  }
108 }
109 
110 
111 void NormalMRF::SmoothVertical( bool const odd, bool const decreasing ) {
112 
113  unsigned int const size = ( 1u << m_coarseness );
114 
115  int jjBegin = 0;
116  int jjEnd = ( ( m_dimension[ 1 ] - 1 ) & ~( size - 1 ) );
117  int jjDelta = size;
118  if ( decreasing ) {
119 
120  std::swap( jjBegin, jjEnd );
121  jjDelta = -jjDelta;
122  }
123  jjEnd += jjDelta;
124 
125  #pragma omp parallel for
126  for ( int ii = ( odd ? size : 0 ); ii < static_cast< int >( m_dimension[ 0 ] ); ii += size * 2 ) {
127 
128  for ( int jj = jjBegin; jj != jjEnd; jj += jjDelta ) {
129 
130  assert( ( jj >= 0 ) && ( jj < m_dimension[ 1 ] ) );
131  Vector< unsigned int, 2 > const coordinates = { { ii, jj } };
132  SolveCardinal(
133  m_depths.get(),
134  m_states.get(),
135  m_dimension,
136  coordinates,
137  size,
138  size,
139  m_spread,
140  m_voxelSize,
141  Square( size ) * m_observationPrecision,
142  m_gradientPrecision,
143  m_minimumEdgeDelta,
144  m_maximumEdgeDelta
145  );
146  }
147  }
148 }
149 
150 
151 void NormalMRF::SmoothCardinalCheckerboard( bool const odd ) {
152 
153  unsigned int const size = ( 1u << m_coarseness );
154 
155  #pragma omp parallel for
156  for ( int ii = 0; ii < static_cast< int >( m_dimension[ 1 ] ); ii += size ) {
157 
158  for ( int jj = ( ( ( ii & size ) != 0 ) == odd ) ? 0 : size; jj < static_cast< int >( m_dimension[ 0 ] ); jj += size * 2 ) {
159 
160  Vector< unsigned int, 2 > const coordinates = { { jj, ii } };
161  SolveCardinal(
162  m_depths.get(),
163  m_states.get(),
164  m_dimension,
165  coordinates,
166  size,
167  size,
168  m_spread,
169  m_voxelSize,
170  Square( size ) * m_observationPrecision,
171  m_gradientPrecision,
172  m_minimumEdgeDelta,
173  m_maximumEdgeDelta
174  );
175  }
176  }
177 }
178 
179 
180 void NormalMRF::SmoothDiagonalCheckerboard( bool const odd ) {
181 
182  unsigned int const size = ( 1u << m_coarseness );
183  double const scale = size * std::sqrt( 2 );
184 
185  #pragma omp parallel for
186  for ( int ii = odd ? size : 0; ii < static_cast< int >( m_dimension[ 1 ] ); ii += size * 2 ) {
187 
188  for ( int jj = odd ? size : 0; jj < static_cast< int >( m_dimension[ 0 ] ); jj += size * 2 ) {
189 
190  Vector< unsigned int, 2 > const coordinates = { { jj, ii } };
191  SolveDiagonal(
192  m_depths.get(),
193  m_states.get(),
194  m_dimension,
195  coordinates,
196  size,
197  scale,
198  m_spread,
199  m_voxelSize,
200  Square( scale ) * m_observationPrecision,
201  m_gradientPrecision,
202  m_minimumEdgeDelta,
203  m_maximumEdgeDelta
204  );
205  }
206  }
207 }
208 
209 
210 void NormalMRF::InitializeStates() {
211 
212  unsigned int const size = ( 1u << m_coarseness );
213 
214  Vector< double, 2 > const gradient0 = { { 0, 0 } };
215 
216  #pragma omp parallel for
217  for ( int ii = 0; ii < static_cast< int >( m_dimension[ 1 ] ); ii += size ) {
218 
219  unsigned int const offset = ii * m_dimension[ 0 ];
220  for ( int jj = 0; jj < static_cast< int >( m_dimension[ 0 ] ); jj += size ) {
221 
222  double const reciprocalDepth = 1 / m_depths[ offset + jj ];
223 
224  m_states[ offset + jj ].first = reciprocalDepth;
225  m_states[ offset + jj ].second = gradient0;
226  }
227  }
228 }
229 
230 
231 
232 
233 } // namespace detail
234 
235 
236 } // namespace Renderer