3 #include <Core/Geometry/AbstractGeometry.hpp>
4 #include <Core/RaCore.hpp>
7 #define RA_REQUIRE_OPTIONAL
8 #include <Core/Utils/StdOptional.hpp>
9 #undef RA_REQUIRE_OPTIONAL
38 DISCRETE_DENSE = 1 << 2,
39 DISCRETE_SPARSE = 1 << 3
66 virtual Utils::optional<ValueType>
getValue( Eigen::Ref<const Vector3> p )
const = 0;
71 bool isParametric()
const;
73 bool isDiscrete()
const;
77 bool isSparse()
const;
81 void displayInfo()
const;
97 using IndexType = Vector3i;
101 AbstractVolume( type ), m_size( IndexType::Zero() ), m_binSize { 1_ra, 1_ra, 1_ra } {}
109 void clear()
override;
112 Aabb computeAabb()
const override;
115 const Vector3i&
size()
const {
return m_size; }
117 void setSize( Eigen::Ref<const Vector3i> size ) {
123 const Vector3&
binSize()
const {
return m_binSize; }
127 CORE_ASSERT( binSize != Vector3::Zero(),
"Volume bin size can't be zero." );
133 inline Utils::optional<ValueType>
getBinValue( Eigen::Ref<const IndexType> p )
const {
134 if (
auto res = linearIndex( p ) )
return getBinValue( *res );
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>() );
151 if (
auto res = linearIndex( p ) ) {
152 addToBin( value, *res );
161 inline Utils::optional<typename IndexType::Scalar>
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 ) ) );
168 virtual Utils::optional<ValueType>
getBinValue(
typename IndexType::Scalar idx )
const = 0;
184 using ValueType = AbstractDiscreteVolume::ValueType;
185 using IndexType = AbstractDiscreteVolume::IndexType;
188 using GradientType = Eigen::Matrix<ValueType, 4, 1>;
190 using Container = std::vector<ValueType>;
191 using GradientContainer = std::vector<GradientType>;
204 inline const Container&
data()
const {
return m_data; }
206 inline Container&
data() {
return m_data; }
210 for (
auto& v : m_data ) {
216 bool hasGradients()
const {
return m_data.size() == m_gradient.size(); }
219 void computeGradients();
222 inline const GradientContainer&
gradient()
const {
return m_gradient; }
224 inline GradientContainer&
gradient() {
return m_gradient; }
229 inline Utils::optional<ValueType>
getBinValue(
typename IndexType::Scalar idx )
const override {
230 return m_data[size_t( idx )];
236 m_data[size_t( idx )] += value;
241 m_data.resize(
size_t( size().prod() ), m_defaultValue );
246 ValueType sample(
const IndexType& i );
248 ValueType m_defaultValue;
250 GradientContainer m_gradient;
261 using ValueType = AbstractDiscreteVolume::ValueType;
262 using IndexType = AbstractDiscreteVolume::IndexType;
267 inline SampleType(
int idx,
const ValueType& v ) : index( idx ), value( v ) {}
269 using Container = std::vector<SampleType>;
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;
301 auto res = findBin( idx );
302 if ( res != std::end( m_data ) )
305 m_data.emplace_back( idx, value );
311 inline Container::iterator findBin(
typename IndexType::Scalar idx ) {
312 return std::find_if( std::begin( m_data ),
314 [&idx](
const SampleType& s ) {
return s.index == idx; } );
316 inline Container::const_iterator findBin(
typename IndexType::Scalar idx )
const {
317 return std::find_if( std::begin( m_data ),
319 [&idx](
const SampleType& s ) {
return s.index == idx; } );
virtual Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const =0
Get the bin value.
Utils::optional< ValueType > getBinValue(Eigen::Ref< const IndexType > p) const
Get the value of the given bin.
void setBinSize(Eigen::Ref< const Vector3 > binSize)
Set the bin size.
Utils::optional< typename IndexType::Scalar > linearIndex(Eigen::Ref< const IndexType > p) const
Convert the 3D position into a linear index on the bin set.
virtual void updateStorage()=0
Method called when size as been updated.
void setSize(Eigen::Ref< const Vector3i > size)
virtual void addToBin(const ValueType &value, typename IndexType::Scalar idx)=0
Add a value to the bin.
const Vector3i & size() const
return the size (number of bins ni each dimension) of the volume
Utils::optional< ValueType > getValue(Eigen::Ref< const Vector3 > p) const override final
const Vector3 & binSize() const
return the bin size
bool addToBin(const ValueType &value, Eigen::Ref< const IndexType > p)
Scalar ValueType
Type of value encoded in the volume.
virtual Utils::optional< ValueType > getValue(Eigen::Ref< const Vector3 > p) const =0
VolumeStorageType m_type
The type of geometry for the object.
void setType(const VolumeStorageType &type)
Set the type of geometry.
VolumeStorageType getType() const
Return the type of geometry.
VolumeStorageType
The type of geometry.
Discrete volume data storing values in a regular grid.
const GradientContainer & gradient() const
Direct access to the managed gradients.
const Container & data() const
Direct access to the managed data.
bool hasGradients() const
Test if gradients are defined.
Container & data()
Direct access, with modification allowed to the managed data.
void addToAllBins(const ValueType &value)
Add a value to all bins.
void updateStorage() override
Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const override
void addToBin(const ValueType &value, typename IndexType::Scalar idx) override
GradientContainer & gradient()
Direct access, with modification allowed to the managed gradients.
Utils::optional< ValueType > getBinValue(typename IndexType::Scalar idx) const override
void updateStorage() override
Method called when size as been updated.
void addToBin(const ValueType &value, typename IndexType::Scalar idx) override