19 #include <nori/render.h>
20 #include <nori/parser.h>
21 #include <nori/scene.h>
22 #include <nori/camera.h>
23 #include <nori/block.h>
24 #include <nori/timer.h>
25 #include <nori/bitmap.h>
26 #include <nori/sampler.h>
27 #include <nori/integrator.h>
29 #include <tbb/parallel_for.h>
30 #include <tbb/blocked_range.h>
31 #include <tbb/task_scheduler_init.h>
32 #include <filesystem/resolver.h>
33 #include <tbb/concurrent_vector.h>
38 RenderThread::RenderThread(
ImageBlock & block) :
44 RenderThread::~RenderThread() {
48 bool RenderThread::isBusy() {
49 if(m_render_status == 3) {
50 m_render_thread.join();
53 return m_render_status != 0;
56 void RenderThread::stopRendering() {
58 cout <<
"Requesting interruption of the current rendering" << endl;
60 m_render_thread.join();
62 cout <<
"Rendering successfully aborted" << endl;
66 float RenderThread::getProgress() {
84 for (
int y=0; y<size.y(); ++y) {
85 for (
int x=0; x<size.x(); ++x) {
86 Point2f pixelSample =
Point2f((
float) (x + offset.x()), (
float) (y + offset.y())) + sampler->
next2D();
94 value *= integrator->
Li(scene, sampler, ray);
97 block.
put(pixelSample, value);
104 filesystem::path path(filename);
109 getFileResolver()->prepend(path.parent_path());
115 m_scene =
static_cast<Scene *
>(root);
125 std::string outputNameStem = filename;
126 size_t lastdot = outputNameStem.find_last_of(
".");
127 if (lastdot != std::string::npos)
128 outputNameStem.erase(lastdot, std::string::npos);
133 int n_threads = tbb::task_scheduler_init::automatic;
134 m_render_thread = std::thread([
this, outputNameStem] {
135 tbb::task_scheduler_init init;
142 cout <<
"Rendering .. ";
149 tbb::concurrent_vector< std::unique_ptr<Sampler> > samplers;
150 samplers.resize(numBlocks);
152 for (uint32_t k = 0; k < numSamples ; ++k) {
153 m_progress = k/float(numSamples);
154 if(m_render_status == 2)
157 tbb::blocked_range<int> range(0, numBlocks);
159 auto map = [&](
const tbb::blocked_range<int> &range) {
164 for (
int i = range.begin(); i < range.end(); ++i) {
166 blockGenerator.
next(block);
169 auto blockId = block.getBlockId();
172 sampler->prepare(block);
173 samplers.at(blockId) = std::move(sampler);
177 renderBlock(m_scene, samplers.at(blockId).get(), block);
188 tbb::parallel_for(range, map);
190 blockGenerator.
reset();
193 cout <<
"done. (took " << timer.
elapsedString() <<
")" << endl;
198 std::unique_ptr<Bitmap> bitmap(m_block.
toBitmap());
202 bitmap->save(outputNameStem);
Spiraling block generator.
int getBlockCount() const
Return the total number of blocks.
void reset()
Reset to the first block.
bool next(ImageBlock &block)
Return the next block to be rendered.
Generic camera interface.
const Vector2i & getOutputSize() const
Return the size of the output image in pixels.
virtual Color3f sampleRay(Ray3f &ray, const Point2f &samplePosition, const Point2f &apertureSample) const =0
Importance sample a ray according to the camera's response function.
const ReconstructionFilter * getReconstructionFilter() const
Return the camera's reconstruction filter in image space.
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.
void unlock() const
Unlock the image block.
const Vector2i & getSize() const
Return the size of the block within the main image.
void clear()
Clear all contents.
void lock() const
Lock the image block (using an internal mutex)
Bitmap * toBitmap() const
Turn the block into a proper bitmap.
const Point2i & getOffset() const
Return the offset of the block within the main image.
Abstract integrator (i.e. a rendering technique)
virtual Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &ray) const =0
Sample the incident radiance along a ray.
virtual void preprocess(const Scene *scene)
Perform an (optional) preprocess step.
Base class of all objects.
virtual EClassType getClassType() const =0
Return the type of object (i.e. Mesh/BSDF/etc.) provided by this instance.
void renderScene(const std::string &filename)
Abstract sample generator.
virtual std::unique_ptr< Sampler > clone() const =0
Create an exact clone of the current instance.
virtual Point2f next2D()=0
Retrieve the next two component values from the current sample.
virtual size_t getSampleCount() const
Return the number of configured pixel samples.
Main scene data structure.
const Camera * getCamera() const
Return a pointer to the scene's camera.
const Integrator * getIntegrator() const
Return a pointer to the scene's integrator.
const Sampler * getSampler() const
Return a pointer to the scene's sample generator (const version)
Simple timer with millisecond precision.
std::string elapsedString(bool precise=false) const
Like elapsed(), but return a human-readable string.
Represents a linear RGB color value.