Radium Engine  1.5.20
Loading...
Searching...
No Matches
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#undef RA_REQUIRE_OPTIONAL
10
11#include <algorithm> // find_if
12
13namespace Ra {
14namespace Core {
15namespace Geometry {
16
30class RA_CORE_API AbstractVolume : public AbstractGeometry
31{
32
33 public:
36 UNKNOWN = 1 << 0,
37 PARAMETRIC = 1 << 1,
38 DISCRETE_DENSE = 1 << 2,
39 DISCRETE_SPARSE = 1 << 3
41 };
42
44 using ValueType = Scalar;
45
46 protected:
47 AbstractVolume( const VolumeStorageType& type );
48
49 public:
50 AbstractVolume( const AbstractVolume& data ) = default;
51 AbstractVolume& operator=( const AbstractVolume& ) = default;
52 ~AbstractVolume() = default;
53
55 inline VolumeStorageType getType() const { return m_type; }
56
57 protected:
59 inline void setType( const VolumeStorageType& type ) { m_type = type; }
60
61 public:
66 virtual Utils::optional<ValueType> getValue( Eigen::Ref<const Vector3> p ) const = 0;
67
71 bool isParametric() const;
73 bool isDiscrete() const;
75 bool isDense() const;
77 bool isSparse() const;
79
81 void displayInfo() const;
82
83 protected:
86};
92class RA_CORE_API AbstractDiscreteVolume : public AbstractVolume
93{
94
95 public:
96 using ValueType = AbstractVolume::ValueType;
97 using IndexType = Vector3i;
98
99 protected:
100 inline AbstractDiscreteVolume( const VolumeStorageType& type ) :
101 AbstractVolume( type ), m_size( IndexType::Zero() ), m_binSize { 1_ra, 1_ra, 1_ra } {}
102
103 public:
104 AbstractDiscreteVolume( const AbstractDiscreteVolume& data ) = default;
105 AbstractDiscreteVolume& operator=( const AbstractDiscreteVolume& ) = default;
106 ~AbstractDiscreteVolume() override = default;
107
109 void clear() override;
110
112 Aabb computeAabb() const override;
113
115 const Vector3i& size() const { return m_size; }
117 void setSize( Eigen::Ref<const Vector3i> size ) {
118 m_size = size;
119 updateStorage();
120 invalidateAabb();
121 }
123 const Vector3& binSize() const { return m_binSize; }
124
126 void setBinSize( Eigen::Ref<const Vector3> binSize ) {
127 CORE_ASSERT( binSize != Vector3::Zero(), "Volume bin size can't be zero." );
128 m_binSize = binSize;
129 invalidateAabb();
130 }
131
133 inline Utils::optional<ValueType> getBinValue( Eigen::Ref<const IndexType> p ) const {
134 if ( auto res = linearIndex( p ) ) return getBinValue( *res );
135 return {};
136 }
137
142 inline Utils::optional<ValueType> getValue( Eigen::Ref<const Vector3> p ) const override final {
143 return getBinValue( ( p.cwiseQuotient( m_binSize ) ).cast<typename IndexType::Scalar>() );
144 }
145
150 inline bool addToBin( const ValueType& value, Eigen::Ref<const IndexType> p ) {
151 if ( auto res = linearIndex( p ) ) {
152 addToBin( value, *res );
153 invalidateAabb();
154 return true;
155 }
156 return false;
157 }
158
159 protected:
161 inline Utils::optional<typename IndexType::Scalar>
162 linearIndex( Eigen::Ref<const IndexType> p ) const {
163 using Integer = typename IndexType::Scalar;
164 if ( ( p.array() >= m_size.array() ).any() ) return {};
165 return p.dot( IndexType( Integer( 1 ), m_size( 0 ), m_size( 0 ) * m_size( 1 ) ) );
166 }
168 virtual Utils::optional<ValueType> getBinValue( typename IndexType::Scalar idx ) const = 0;
170 virtual void addToBin( const ValueType& value, typename IndexType::Scalar idx ) = 0;
171
173 virtual void updateStorage() = 0;
174
175 private:
176 IndexType m_size;
177 Vector3 m_binSize;
178};
179
181class RA_CORE_API VolumeGrid : public AbstractDiscreteVolume
182{
183 public:
184 using ValueType = AbstractDiscreteVolume::ValueType;
185 using IndexType = AbstractDiscreteVolume::IndexType;
186 // Stores the 3 partial derivatives of the density if the 3 first components and the density as
187 // fourth component.
188 using GradientType = Eigen::Matrix<ValueType, 4, 1>;
189
192
193 public:
194 inline VolumeGrid( const ValueType& defaultValue = ValueType( 0. ) ) :
195 AbstractDiscreteVolume( DISCRETE_DENSE ), m_defaultValue( defaultValue ) {}
196 VolumeGrid( const VolumeGrid& data ) = default;
197 VolumeGrid& operator=( const VolumeGrid& ) = default;
198 ~VolumeGrid() override = default;
199
200 using AbstractDiscreteVolume::addToBin;
201 using AbstractDiscreteVolume::getBinValue;
202
204 inline const Container& data() const { return m_data; }
206 inline Container& data() { return m_data; }
207
209 inline void addToAllBins( const ValueType& value ) {
210 for ( auto& v : m_data ) {
211 v += value;
212 }
213 }
214
216 bool hasGradients() const { return m_data.size() == m_gradient.size(); }
217
219 void computeGradients();
220
222 inline const GradientContainer& gradient() const { return m_gradient; }
224 inline GradientContainer& gradient() { return m_gradient; }
225
226 protected:
229 inline Utils::optional<ValueType> getBinValue( typename IndexType::Scalar idx ) const override {
230 return m_data[size_t( idx )];
231 }
232
235 inline void addToBin( const ValueType& value, typename IndexType::Scalar idx ) override {
236 m_data[size_t( idx )] += value;
237 }
238
240 inline void updateStorage() override {
241 m_data.resize( size_t( size().prod() ), m_defaultValue );
242 }
243
244 private:
246 ValueType sample( const IndexType& i );
247
248 ValueType m_defaultValue;
249 Container m_data;
250 GradientContainer m_gradient;
251}; // class VolumeGrid
252
258class RA_CORE_API VolumeSparse : public AbstractDiscreteVolume
259{
260 public:
261 using ValueType = AbstractDiscreteVolume::ValueType;
262 using IndexType = AbstractDiscreteVolume::IndexType;
263 struct SampleType {
264 int index;
265 ValueType value;
266
267 inline SampleType( int idx, const ValueType& v ) : index( idx ), value( v ) {}
268 };
270
271 public:
272 inline VolumeSparse() : AbstractDiscreteVolume( DISCRETE_SPARSE ) {}
273 VolumeSparse( const VolumeSparse& data ) = default;
274 VolumeSparse& operator=( const VolumeSparse& ) = default;
275 ~VolumeSparse() override = default;
276
277 using AbstractDiscreteVolume::addToBin;
278 using AbstractDiscreteVolume::getBinValue;
279
280 protected:
288 inline Utils::optional<ValueType> getBinValue( typename IndexType::Scalar idx ) const override {
289 auto res = findBin( idx );
290 if ( res != std::end( m_data ) ) return res->value;
291 return {};
292 }
293
300 inline void addToBin( const ValueType& value, typename IndexType::Scalar idx ) override {
301 auto res = findBin( idx );
302 if ( res != std::end( m_data ) )
303 res->value += value;
304 else
305 m_data.emplace_back( idx, value );
306 }
307
308 inline void updateStorage() override { m_data.clear(); }
309
310 private:
311 inline Container::iterator findBin( typename IndexType::Scalar idx ) {
312 return std::find_if( std::begin( m_data ),
313 std::end( m_data ),
314 [&idx]( const SampleType& s ) { return s.index == idx; } );
315 }
316 inline Container::const_iterator findBin( typename IndexType::Scalar idx ) const {
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
322 private:
323 Container m_data;
324
325}; // class VolumeSparse
326
327} // namespace Geometry
328} // namespace Core
329} // 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:162
Utils::optional< ValueType > getValue(Eigen::Ref< const Vector3 > p) const override final
Definition Volume.hpp:142
Utils::optional< ValueType > getBinValue(Eigen::Ref< const IndexType > p) const
Get the value of the given bin.
Definition Volume.hpp:133
void setBinSize(Eigen::Ref< const Vector3 > binSize)
Set the bin size.
Definition Volume.hpp:126
const Vector3i & size() const
return the size (number of bins ni each dimension) of the volume
Definition Volume.hpp:115
virtual void updateStorage()=0
Method called when size as been updated.
const Vector3 & binSize() const
return the bin size
Definition Volume.hpp:123
void setSize(Eigen::Ref< const Vector3i > size)
Definition Volume.hpp:117
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:150
Scalar ValueType
Type of value encoded in the volume.
Definition Volume.hpp:44
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:85
void setType(const VolumeStorageType &type)
Set the type of geometry.
Definition Volume.hpp:59
VolumeStorageType getType() const
Return the type of geometry.
Definition Volume.hpp:55
VolumeStorageType
The type of geometry.
Definition Volume.hpp:35
Discrete volume data storing values in a regular grid.
Definition Volume.hpp:182
const GradientContainer & gradient() const
Direct access to the managed gradients.
Definition Volume.hpp:222
const Container & data() const
Direct access to the managed data.
Definition Volume.hpp:204
bool hasGradients() const
Test if gradients are defined.
Definition Volume.hpp:216
GradientContainer & gradient()
Direct access, with modification allowed to the managed gradients.
Definition Volume.hpp:224
void addToAllBins(const ValueType &value)
Add a value to all bins.
Definition Volume.hpp:209
void updateStorage() override
Definition Volume.hpp:240
Container & data()
Direct access, with modification allowed to the managed data.
Definition Volume.hpp:206
void addToBin(const ValueType &value, typename IndexType::Scalar idx) override
Definition Volume.hpp:235
Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const override
Definition Volume.hpp:229
Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const override
Definition Volume.hpp:288
void updateStorage() override
Method called when size as been updated.
Definition Volume.hpp:308
void addToBin(const ValueType &value, typename IndexType::Scalar idx) override
Definition Volume.hpp:300
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:3