19 #include <nori/block.h>
20 #include <nori/bitmap.h>
21 #include <nori/rfilter.h>
22 #include <nori/bbox.h>
57 m_borderSize = (int) std::ceil(m_filterRadius - 0.5f);
58 m_filter =
new float[NORI_FILTER_RESOLUTION + 1];
59 for (
int i=0; i<NORI_FILTER_RESOLUTION; ++i) {
60 float pos = (m_filterRadius * i) / NORI_FILTER_RESOLUTION;
61 m_filter[i] = filter->
eval(pos);
63 m_filter[NORI_FILTER_RESOLUTION] = 0.0f;
64 m_lookupFactor = NORI_FILTER_RESOLUTION / m_filterRadius;
65 int weightSize = (int) std::ceil(2*m_filterRadius) + 1;
66 m_weightsX =
new float[weightSize];
67 m_weightsY =
new float[weightSize];
68 memset(m_weightsX, 0,
sizeof(
float) * weightSize);
69 memset(m_weightsY, 0,
sizeof(
float) * weightSize);
73 resize(size.y() + 2*m_borderSize, size.x() + 2*m_borderSize);
78 for (
int y=0; y<m_size.y(); ++y)
79 for (
int x=0; x<m_size.x(); ++x)
80 result->coeffRef(y, x) = coeff(y + m_borderSize, x + m_borderSize).divideByFilterWeight();
85 if (bitmap.cols() != cols() || bitmap.rows() != rows())
88 for (
int y=0; y<m_size.y(); ++y)
89 for (
int x=0; x<m_size.x(); ++x)
90 coeffRef(y, x) << bitmap.coeff(y, x), 1;
96 cerr <<
"Integrator: computed an invalid radiance value: " << value.
toString() << endl;
102 _pos.x() - 0.5f - (m_offset.x() - m_borderSize),
103 _pos.y() - 0.5f - (m_offset.y() - m_borderSize)
108 Point2i((
int) std::ceil(pos.x() - m_filterRadius), (
int) std::ceil(pos.y() - m_filterRadius)),
109 Point2i((
int) std::floor(pos.x() + m_filterRadius), (
int) std::floor(pos.y() + m_filterRadius))
114 for (
int x=bbox.
min.x(), idx = 0; x<=bbox.
max.x(); ++x)
115 m_weightsX[idx++] = m_filter[(int) (std::abs(x-pos.x()) * m_lookupFactor)];
116 for (
int y=bbox.
min.y(), idx = 0; y<=bbox.
max.y(); ++y)
117 m_weightsY[idx++] = m_filter[(
int) (std::abs(y-pos.y()) * m_lookupFactor)];
119 for (
int y=bbox.
min.y(), yr=0; y<=bbox.
max.y(); ++y, ++yr)
120 for (
int x=bbox.
min.x(), xr=0; x<=bbox.
max.x(); ++x, ++xr)
121 coeffRef(y, x) +=
Color4f(value) * m_weightsX[xr] * m_weightsY[yr];
129 tbb::mutex::scoped_lock
lock(m_mutex);
131 block(offset.y(), offset.x(), size.y(), size.x())
132 += b.topLeftCorner(size.y(), size.x());
136 return tfm::format(
"ImageBlock[offset=%s, size=%s]]",
141 : m_size(size), m_blockSize(blockSize) {
143 (
int) std::ceil(size.x() / (
float) blockSize),
144 (
int) std::ceil(size.y() / (
float) blockSize));
149 m_blocksLeft = m_numBlocks.x() * m_numBlocks.y();
150 m_direction = ERight;
151 m_block =
Point2i(m_numBlocks / 2);
157 tbb::mutex::scoped_lock lock(m_mutex);
159 if (m_blocksLeft == 0)
162 Point2i pos = m_block * m_blockSize;
164 block.
setSize((m_size - pos).cwiseMin(Vector2i::Constant(m_blockSize)));
165 block.setBlockId(m_block.y() * m_numBlocks.x() + m_block.x());
167 if (--m_blocksLeft == 0)
171 switch (m_direction) {
172 case ERight: ++m_block.x();
break;
173 case EDown: ++m_block.y();
break;
174 case ELeft: --m_block.x();
break;
175 case EUp: --m_block.y();
break;
178 if (--m_stepsLeft == 0) {
179 m_direction = (m_direction + 1) % 4;
180 if (m_direction == ELeft || m_direction == ERight)
182 m_stepsLeft = m_numSteps;
184 }
while ((m_block.array() < 0).any() ||
185 (m_block.array() >= m_numBlocks.array()).any());
Stores a RGB high dynamic-range bitmap.
BlockGenerator(const Vector2i &size, int blockSize)
Create a block generator with.
void reset()
Reset to the first block.
bool next(ImageBlock &block)
Return the next block to be rendered.
Weighted pixel storage for a rectangular subregion of an image.
void put(const Point2f &pos, const Color3f &value)
Record a sample with the given position and radiance value.
ImageBlock(const Vector2i &size, const ReconstructionFilter *filter)
const Vector2i & getSize() const
Return the size of the block within the main image.
void fromBitmap(const Bitmap &bitmap)
Convert a bitmap into an image block.
int getBorderSize() const
Return the border size in pixels.
~ImageBlock()
Release all memory.
void lock() const
Lock the image block (using an internal mutex)
std::string toString() const
Return a human-readable string summary.
void setSize(const Point2i &size)
Configure the size of the block within the main image.
Bitmap * toBitmap() const
Turn the block into a proper bitmap.
void setOffset(const Point2i &offset)
Configure the offset of the block within the main image.
const Point2i & getOffset() const
Return the offset of the block within the main image.
Simple exception class, which stores a human-readable error description.
Generic radially symmetric image reconstruction filter.
virtual float eval(float x) const =0
Evaluate the filter function.
float getRadius() const
Return the filter radius in fractional pixels.
Represents a linear RGB color value.
bool isValid() const
Check if the color vector contains a NaN/Inf/negative value.
std::string toString() const
Return a human-readable string summary.
Represents a linear RGB color and a weight.
Generic n-dimensional bounding box data structure.
void clip(const TBoundingBox &bbox)
Clip to another bounding box.
PointType max
Component-wise maximum.
PointType min
Component-wise minimum.
std::string toString() const
Return a human-readable string summary.
std::string toString() const
Return a human-readable string summary.