Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.28
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Volume.hpp
1#pragma once
2
3#include <Core/Geometry/AbstractGeometry.hpp>
4#include <Core/RaCore.hpp>
5#include <Core/Types.hpp>
6
7#define RA_REQUIRE_OPTIONAL
8#include <Core/Utils/StdOptional.hpp> // trigger an error if optional is not found
9
10#undef RA_REQUIRE_OPTIONAL
11
12#include <Eigen/Core>
13#include <algorithm> // find_if
14#include <iterator>
15#include <optional>
16#include <vector>
17
18namespace Ra {
19namespace Core {
20namespace Geometry {
21
35class RA_CORE_API AbstractVolume : public AbstractGeometry
36{
37
38 public:
41 UNKNOWN = 1 << 0,
42 PARAMETRIC = 1 << 1,
43 DISCRETE_DENSE = 1 << 2,
44 DISCRETE_SPARSE = 1 << 3
46 };
47
49 using ValueType = Scalar;
50
51 protected:
52 AbstractVolume( const VolumeStorageType& type );
53
54 public:
55 AbstractVolume( const AbstractVolume& data ) = default;
56 AbstractVolume& operator=( const AbstractVolume& ) = default;
57 ~AbstractVolume() = default;
58
60 inline VolumeStorageType getType() const { return m_type; }
61
62 protected:
64 inline void setType( const VolumeStorageType& type ) { m_type = type; }
65
66 public:
71 virtual Utils::optional<ValueType> getValue( Eigen::Ref<const Vector3> p ) const = 0;
72
76 bool isParametric() const;
78 bool isDiscrete() const;
80 bool isDense() const;
82 bool isSparse() const;
84
86 void displayInfo() const;
87
88 protected:
91};
97class RA_CORE_API AbstractDiscreteVolume : public AbstractVolume
98{
99
100 public:
101 using ValueType = AbstractVolume::ValueType;
102 using IndexType = Vector3i;
103
104 protected:
105 inline AbstractDiscreteVolume( const VolumeStorageType& type ) :
106 AbstractVolume( type ), m_size( IndexType::Zero() ), m_binSize { 1_ra, 1_ra, 1_ra } {}
107
108 public:
109 AbstractDiscreteVolume( const AbstractDiscreteVolume& data ) = default;
110 AbstractDiscreteVolume& operator=( const AbstractDiscreteVolume& ) = default;
111 ~AbstractDiscreteVolume() override = default;
112
114 void clear() override;
115
117 Aabb computeAabb() const override;
118
120 const Vector3i& size() const { return m_size; }
122 void setSize( Eigen::Ref<const Vector3i> size ) {
123 m_size = size;
124 updateStorage();
125 invalidateAabb();
126 }
128 const Vector3& binSize() const { return m_binSize; }
129
131 void setBinSize( Eigen::Ref<const Vector3> binSize ) {
132 CORE_ASSERT( binSize != Vector3::Zero(), "Volume bin size can't be zero." );
133 m_binSize = binSize;
134 invalidateAabb();
135 }
136
138 inline Utils::optional<ValueType> getBinValue( Eigen::Ref<const IndexType> p ) const {
139 if ( auto res = linearIndex( p ) ) return getBinValue( *res );
140 return {};
141 }
142
147 inline Utils::optional<ValueType> getValue( Eigen::Ref<const Vector3> p ) const override final {
148 return getBinValue( ( p.cwiseQuotient( m_binSize ) ).cast<typename IndexType::Scalar>() );
149 }
150
155 inline bool addToBin( const ValueType& value, Eigen::Ref<const IndexType> p ) {
156 if ( auto res = linearIndex( p ) ) {
157 addToBin( value, *res );
158 invalidateAabb();
159 return true;
160 }
161 return false;
162 }
163
164 protected:
166 inline Utils::optional<typename IndexType::Scalar>
167 linearIndex( Eigen::Ref<const IndexType> p ) const {
168 using Integer = typename IndexType::Scalar;
169 if ( ( p.array() >= m_size.array() ).any() ) return {};
170 return p.dot( IndexType( Integer( 1 ), m_size( 0 ), m_size( 0 ) * m_size( 1 ) ) );
171 }
173 virtual Utils::optional<ValueType> getBinValue( typename IndexType::Scalar idx ) const = 0;
175 virtual void addToBin( const ValueType& value, typename IndexType::Scalar idx ) = 0;
176
178 virtual void updateStorage() = 0;
179
180 private:
181 IndexType m_size;
182 Vector3 m_binSize;
183};
184
186class RA_CORE_API VolumeGrid : public AbstractDiscreteVolume
187{
188 public:
189 using ValueType = AbstractDiscreteVolume::ValueType;
190 using IndexType = AbstractDiscreteVolume::IndexType;
191 // Stores the 3 partial derivatives of the density if the 3 first components and the density as
192 // fourth component.
193 using GradientType = Eigen::Matrix<ValueType, 4, 1>;
194
197
198 public:
199 inline VolumeGrid( const ValueType& defaultValue = ValueType( 0. ) ) :
200 AbstractDiscreteVolume( DISCRETE_DENSE ), m_defaultValue( defaultValue ) {}
201 VolumeGrid( const VolumeGrid& data ) = default;
202 VolumeGrid& operator=( const VolumeGrid& ) = default;
203 ~VolumeGrid() override = default;
204
205 using AbstractDiscreteVolume::addToBin;
206 using AbstractDiscreteVolume::getBinValue;
207
209 inline const Container& data() const { return m_data; }
211 inline Container& data() { return m_data; }
212
214 inline void addToAllBins( const ValueType& value ) {
215 for ( auto& v : m_data ) {
216 v += value;
217 }
218 }
219
221 bool hasGradients() const { return m_data.size() == m_gradient.size(); }
222
224 void computeGradients();
225
227 inline const GradientContainer& gradient() const { return m_gradient; }
229 inline GradientContainer& gradient() { return m_gradient; }
230
231 protected:
234 inline Utils::optional<ValueType> getBinValue( typename IndexType::Scalar idx ) const override {
235 return m_data[size_t( idx )];
236 }
237
240 inline void addToBin( const ValueType& value, typename IndexType::Scalar idx ) override {
241 m_data[size_t( idx )] += value;
242 }
243
245 inline void updateStorage() override {
246 m_data.resize( size_t( size().prod() ), m_defaultValue );
247 }
248
249 private:
251 ValueType sample( const IndexType& i );
252
253 ValueType m_defaultValue;
254 Container m_data;
255 GradientContainer m_gradient;
256}; // class VolumeGrid
257
263class RA_CORE_API VolumeSparse : public AbstractDiscreteVolume
264{
265 public:
266 using ValueType = AbstractDiscreteVolume::ValueType;
267 using IndexType = AbstractDiscreteVolume::IndexType;
268 struct SampleType {
269 int index;
270 ValueType value;
271
272 inline SampleType( int idx, const ValueType& v ) : index( idx ), value( v ) {}
273 };
275
276 public:
277 inline VolumeSparse() : AbstractDiscreteVolume( DISCRETE_SPARSE ) {}
278 VolumeSparse( const VolumeSparse& data ) = default;
279 VolumeSparse& operator=( const VolumeSparse& ) = default;
280 ~VolumeSparse() override = default;
281
282 using AbstractDiscreteVolume::addToBin;
283 using AbstractDiscreteVolume::getBinValue;
284
285 protected:
293 inline Utils::optional<ValueType> getBinValue( typename IndexType::Scalar idx ) const override {
294 auto res = findBin( idx );
295 if ( res != std::end( m_data ) ) return res->value;
296 return {};
297 }
298
305 inline void addToBin( const ValueType& value, typename IndexType::Scalar idx ) override {
306 auto res = findBin( idx );
307 if ( res != std::end( m_data ) )
308 res->value += value;
309 else
310 m_data.emplace_back( idx, value );
311 }
312
313 inline void updateStorage() override { m_data.clear(); }
314
315 private:
316 inline Container::iterator findBin( typename IndexType::Scalar idx ) {
317 return std::find_if( std::begin( m_data ),
318 std::end( m_data ),
319 [&idx]( const SampleType& s ) { return s.index == idx; } );
320 }
321 inline Container::const_iterator findBin( typename IndexType::Scalar idx ) const {
322 return std::find_if( std::begin( m_data ),
323 std::end( m_data ),
324 [&idx]( const SampleType& s ) { return s.index == idx; } );
325 }
326
327 private:
328 Container m_data;
329
330}; // class VolumeSparse
331
332} // namespace Geometry
333} // namespace Core
334} // namespace Ra
T begin(T... args)
Utils::optional< typename IndexType::Scalar > linearIndex(Eigen::Ref< const IndexType > p) const
Convert the 3D position into a linear index on the bin set.
Definition Volume.hpp:167
Utils::optional< ValueType > getValue(Eigen::Ref< const Vector3 > p) const override final
Definition Volume.hpp:147
Utils::optional< ValueType > getBinValue(Eigen::Ref< const IndexType > p) const
Get the value of the given bin.
Definition Volume.hpp:138
void setBinSize(Eigen::Ref< const Vector3 > binSize)
Set the bin size.
Definition Volume.hpp:131
const Vector3i & size() const
return the size (number of bins ni each dimension) of the volume
Definition Volume.hpp:120
virtual void updateStorage()=0
Method called when size as been updated.
const Vector3 & binSize() const
return the bin size
Definition Volume.hpp:128
void setSize(Eigen::Ref< const Vector3i > size)
Definition Volume.hpp:122
virtual void addToBin(const ValueType &value, typename IndexType::Scalar idx)=0
Add a value to the bin.
virtual Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const =0
Get the bin value.
bool addToBin(const ValueType &value, Eigen::Ref< const IndexType > p)
Definition Volume.hpp:155
Scalar ValueType
Type of value encoded in the volume.
Definition Volume.hpp:49
virtual Utils::optional< ValueType > getValue(Eigen::Ref< const Vector3 > p) const =0
VolumeStorageType m_type
The type of geometry for the object.
Definition Volume.hpp:90
void setType(const VolumeStorageType &type)
Set the type of geometry.
Definition Volume.hpp:64
VolumeStorageType getType() const
Return the type of geometry.
Definition Volume.hpp:60
VolumeStorageType
The type of geometry.
Definition Volume.hpp:40
Discrete volume data storing values in a regular grid.
Definition Volume.hpp:187
const GradientContainer & gradient() const
Direct access to the managed gradients.
Definition Volume.hpp:227
const Container & data() const
Direct access to the managed data.
Definition Volume.hpp:209
bool hasGradients() const
Test if gradients are defined.
Definition Volume.hpp:221
GradientContainer & gradient()
Direct access, with modification allowed to the managed gradients.
Definition Volume.hpp:229
void addToAllBins(const ValueType &value)
Add a value to all bins.
Definition Volume.hpp:214
void updateStorage() override
Definition Volume.hpp:245
Container & data()
Direct access, with modification allowed to the managed data.
Definition Volume.hpp:211
void addToBin(const ValueType &value, typename IndexType::Scalar idx) override
Definition Volume.hpp:240
Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const override
Definition Volume.hpp:234
Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const override
Definition Volume.hpp:293
void updateStorage() override
Method called when size as been updated.
Definition Volume.hpp:313
void addToBin(const ValueType &value, typename IndexType::Scalar idx) override
Definition Volume.hpp:305
T end(T... args)
T find_if(T... args)
@ Geometry
"Geometry" render objects are those loaded using Radium::IO and generated by GeometrySystem
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4