Voxel
 All Classes Namespaces Files Functions Typedefs Enumerations Enumerator Macros Pages
renderer_detail_normal_mrf.h
1 #pragma once
2 
3 #ifndef RENDERER_DETAIL_NORMAL_MRF_H
4 #define RENDERER_DETAIL_NORMAL_MRF_H
5 
6 
7 
8 
9 #include "vector.h"
10 
11 #include <boost/shared_array.hpp>
12 
13 #include <array>
14 #include <memory>
15 
16 
17 
18 
19 namespace Renderer {
20 
21 
22 namespace detail {
23 
24 
25 
26 
27 /*==============================================================================
28  NormalMRF class
29 ==============================================================================*/
30 
31 
32 struct NormalMRF {
33 
34  inline NormalMRF(
35  boost::shared_array< float > const& depths,
36  Vector< unsigned int, 2 > const dimension, // width, height
37  double const spread,
38  double const voxelSize,
39  double const observationPrecision,
40  double const gradientPrecision,
41  double const minimumEdgeDelta,
42  double const maximumEdgeDelta,
43  unsigned int const coarseness = 0
44  );
45 
46 
47  inline Vector< unsigned int, 2 > const& Dimension() const;
48 
49 
50  inline void Refine(); // decrements coarseness
51 
52  inline void SmoothGlobal(); // smooth horizontally and vertically across the screen
53  inline void SmoothLocal(); // smooth in a "checkboard" pattern
54 
55  inline unsigned int Coarseness() const;
56 
57 
58  void CalculateNormals(
59  Vector< float, 3 >* const normals, // destination buffer
60  Vector< double, 2 > const fieldOfView, // horizontal, vertical size of image plane, with 1 = 90 degrees
61  Vector< double, 3 > const xx, // first column of camera matrix (assumed normalized)
62  Vector< double, 3 > const yy, // second column of camera matrix (assumed normalized)
63  Vector< double, 3 > const zz // third column of camera matrix (assumed normalized)
64  );
65 
66 
67 private:
68 
69  typedef std::pair< double, Vector< double, 2 > > State;
70 
71 
72  void SmoothHorizontal( bool const odd, bool const decreasing );
73  void SmoothVertical( bool const odd, bool const decreasing );
74  void SmoothCardinalCheckerboard( bool const odd );
75  void SmoothDiagonalCheckerboard( bool const odd );
76 
77  void InitializeStates();
78 
79 
80  Vector< unsigned int, 2 > m_dimension;
81 
82  double m_spread;
83  double m_voxelSize;
84  double m_observationPrecision;
85  double m_gradientPrecision;
86  double m_minimumEdgeDelta;
87  double m_maximumEdgeDelta;
88  unsigned int m_coarseness;
89 
90  boost::shared_array< float > m_depths;
91  std::unique_ptr< State[] > m_states;
92 };
93 
94 
95 
96 
97 /*==============================================================================
98  NormalMRF methods
99 ==============================================================================*/
100 
101 
102 NormalMRF::NormalMRF(
103  boost::shared_array< float > const& depths,
104  Vector< unsigned int, 2 > const dimension,
105  double const spread,
106  double const voxelSize,
107  double const observationPrecision,
108  double const gradientPrecision,
109  double const minimumEdgeDelta,
110  double const maximumEdgeDelta,
111  unsigned int const coarseness
112 ) :
113  m_dimension( dimension ),
114  m_spread( spread ),
115  m_voxelSize( voxelSize ),
116  m_observationPrecision( observationPrecision * Square( spread ) ), // scale the observation precision by the spread, so that the parameters are independent of the screen resolution
117  m_gradientPrecision( gradientPrecision ),
118  m_minimumEdgeDelta( minimumEdgeDelta ),
119  m_maximumEdgeDelta( maximumEdgeDelta ),
120  m_coarseness( coarseness ),
121  m_depths( depths ),
122  m_states( new State[ m_dimension.Product() ] )
123 {
124  assert( ( m_dimension[ 0 ] > 0 ) && ( m_dimension[ 1 ] > 0 ) );
125 
126  assert( m_spread > 0 );
127  assert( m_voxelSize > 0 );
128  assert( m_observationPrecision > 0 );
129  assert( m_gradientPrecision > 0 );
130  assert( ( m_minimumEdgeDelta >= 0 ) && ( m_maximumEdgeDelta > m_minimumEdgeDelta ) );
131 
132  // make sure that the coarsest level is at least a 2x2 grid
133  for ( ; ( m_coarseness > 0 ) && ( ( 1u << m_coarseness ) >= dimension.Minimum() ); --m_coarseness );
134 
135  InitializeStates();
136 }
137 
138 
139 Vector< unsigned int, 2 > const& NormalMRF::Dimension() const {
140 
141  return m_dimension;
142 }
143 
144 
145 void NormalMRF::Refine() {
146 
147  assert( m_coarseness > 0 );
148  --m_coarseness;
149 
150  SmoothDiagonalCheckerboard( true );
151  SmoothCardinalCheckerboard( true );
152 }
153 
154 
155 void NormalMRF::SmoothGlobal() {
156 
157  SmoothHorizontal( false, false );
158  SmoothHorizontal( true, true );
159  SmoothVertical( false, false );
160  SmoothVertical( true, true );
161  SmoothHorizontal( false, true );
162  SmoothHorizontal( true, false );
163  SmoothVertical( false, true );
164  SmoothVertical( true, false );
165 }
166 
167 
168 void NormalMRF::SmoothLocal() {
169 
170  SmoothCardinalCheckerboard( false );
171  SmoothCardinalCheckerboard( true );
172 }
173 
174 
175 unsigned int NormalMRF::Coarseness() const {
176 
177  return m_coarseness;
178 }
179 
180 
181 
182 
183 } // namespace detail
184 
185 
186 } // namespace Renderer
187 
188 
189 
190 
191 #endif // RENDERER_DETAIL_NORMAL_MRF_H