diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp index c055804824c423d3c4eeca5ee174f98018c7c9c3..d4c85b5d2e5e72b6c6d6c296ebf2921a7d13c636 100644 --- a/applications/gui/src/camera.cpp +++ b/applications/gui/src/camera.cpp @@ -235,6 +235,7 @@ void ftl::gui::Camera::setChannel(Channel c) { channel_ = c; switch (c) { case Channel::Energy: + case Channel::Density: case Channel::Flow: case Channel::Confidence: case Channel::Normals: diff --git a/components/common/cpp/include/ftl/exception.hpp b/components/common/cpp/include/ftl/exception.hpp index 6719158bba5f5f53abfcdeb0fb39a5b5dda0d5f2..921e53493eda023a35af6f4c53b43ca2e26125d9 100644 --- a/components/common/cpp/include/ftl/exception.hpp +++ b/components/common/cpp/include/ftl/exception.hpp @@ -1,18 +1,49 @@ #ifndef _FTL_EXCEPTION_HPP_ #define _FTL_EXCEPTION_HPP_ +#include <sstream> + namespace ftl { +class Formatter { + public: + Formatter() {} + ~Formatter() {} + + template <typename Type> + inline Formatter & operator << (const Type & value) + { + stream_ << value; + return *this; + } + + inline std::string str() const { return stream_.str(); } + inline operator std::string () const { return stream_.str(); } + + enum ConvertToString + { + to_str + }; + inline std::string operator >> (ConvertToString) { return stream_.str(); } + +private: + std::stringstream stream_; + + Formatter(const Formatter &); + Formatter & operator = (Formatter &); +}; + class exception : public std::exception { public: - explicit exception(const char *msg) : msg_(msg) {}; + explicit exception(const char *msg) : msg_(msg) {} + explicit exception(const Formatter &msg) : msg_(msg.str()) {} const char * what () const throw () { - return msg_; + return msg_.c_str(); } private: - const char *msg_; + std::string msg_; }; } diff --git a/components/renderers/cpp/include/ftl/render/splat_render.hpp b/components/renderers/cpp/include/ftl/render/splat_render.hpp index 4de9ec491974b2a780b9c3f5616218d3e102e340..8fc0e10311668c3938b77c835ef31f8100905f64 100644 --- a/components/renderers/cpp/include/ftl/render/splat_render.hpp +++ b/components/renderers/cpp/include/ftl/render/splat_render.hpp @@ -26,7 +26,7 @@ class Splatter : public ftl::render::Renderer { //void setOutputDevice(int); protected: - void _renderChannel(ftl::rgbd::Frame &out, const ftl::rgbd::Channel &channel, cudaStream_t stream); + void _renderChannel(ftl::rgbd::Frame &out, ftl::rgbd::Channel channel_in, ftl::rgbd::Channel channel_out, cudaStream_t stream); private: int device_; @@ -40,6 +40,7 @@ class Splatter : public ftl::render::Renderer { //SplatParams params_; ftl::rgbd::Frame temp_; + ftl::rgbd::Frame accum_; ftl::rgbd::FrameSet *scene_; ftl::cuda::ClipSpace clip_; bool clipping_; diff --git a/components/renderers/cpp/src/splat_render.cpp b/components/renderers/cpp/src/splat_render.cpp index 6aaaebb75f9659ad7d9fa132111ee37ba05192f7..f766fa1e385c9e74be3bded23e2377d4c1ddcede 100644 --- a/components/renderers/cpp/src/splat_render.cpp +++ b/components/renderers/cpp/src/splat_render.cpp @@ -214,76 +214,78 @@ void Splatter::_dibr(cudaStream_t stream) { } void Splatter::_renderChannel( - ftl::rgbd::Frame &out, - const Channel &channel, cudaStream_t stream) + ftl::rgbd::Frame &out, + Channel channel_in, Channel channel_out, cudaStream_t stream) { - if (channel == Channel::None) return; + if (channel_out == Channel::None || channel_in == Channel::None) return; cv::cuda::Stream cvstream = cv::cuda::StreamAccessor::wrapStream(stream); if (scene_->frames.size() < 1) return; - bool is_float = out.get<GpuMat>(channel).type() == CV_32F; //ftl::rgbd::isFloatChannel(channel); - bool is_4chan = out.get<GpuMat>(channel).type() == CV_32FC4; + bool is_float = out.get<GpuMat>(channel_out).type() == CV_32F; //ftl::rgbd::isFloatChannel(channel); + bool is_4chan = out.get<GpuMat>(channel_out).type() == CV_32FC4; temp_.createTexture<float4>(Channel::Colour); temp_.createTexture<float>(Channel::Contribution); // Generate initial normals for the splats - out.create<GpuMat>(Channel::Normals, Format<float4>(params_.camera.width, params_.camera.height)); - _blendChannel(out, Channel::Normals, Channel::Normals, stream); + accum_.create<GpuMat>(Channel::Normals, Format<float4>(params_.camera.width, params_.camera.height)); + _blendChannel(accum_, Channel::Normals, Channel::Normals, stream); // Estimate point density - out.create<GpuMat>(Channel::Density, Format<float>(params_.camera.width, params_.camera.height)); - _blendChannel(out, Channel::Depth, Channel::Density, stream); + accum_.create<GpuMat>(Channel::Density, Format<float>(params_.camera.width, params_.camera.height)); + _blendChannel(accum_, Channel::Depth, Channel::Density, stream); // FIXME: Using colour 2 in this way seems broken since it is already used if (is_4chan) { - temp_.create<GpuMat>(Channel::Colour2, Format<float4>(params_.camera.width, params_.camera.height)); - temp_.get<GpuMat>(Channel::Colour2).setTo(cv::Scalar(0.0f,0.0f,0.0f,0.0f), cvstream); + accum_.create<GpuMat>(channel_out, Format<float4>(params_.camera.width, params_.camera.height)); + accum_.get<GpuMat>(channel_out).setTo(cv::Scalar(0.0f,0.0f,0.0f,0.0f), cvstream); } else if (is_float) { - temp_.create<GpuMat>(Channel::Colour2, Format<float>(params_.camera.width, params_.camera.height)); - temp_.get<GpuMat>(Channel::Colour2).setTo(cv::Scalar(0.0f), cvstream); + accum_.create<GpuMat>(channel_out, Format<float>(params_.camera.width, params_.camera.height)); + accum_.get<GpuMat>(channel_out).setTo(cv::Scalar(0.0f), cvstream); } else { - temp_.create<GpuMat>(Channel::Colour2, Format<uchar4>(params_.camera.width, params_.camera.height)); - temp_.get<GpuMat>(Channel::Colour2).setTo(cv::Scalar(0,0,0,0), cvstream); + accum_.create<GpuMat>(channel_out, Format<uchar4>(params_.camera.width, params_.camera.height)); + accum_.get<GpuMat>(channel_out).setTo(cv::Scalar(0,0,0,0), cvstream); } - if (splat_) { - _blendChannel(temp_, channel, Channel::Colour2, stream); - } else { - _blendChannel(out, channel, channel, stream); - } + //if (splat_) { + _blendChannel(accum_, channel_in, channel_out, stream); + //} else { + // _blendChannel(out, channel, channel, stream); + //} // Now splat the points if (splat_) { if (is_4chan) { ftl::cuda::splat( - out.getTexture<float4>(Channel::Normals), - temp_.getTexture<float4>(Channel::Colour2), + accum_.getTexture<float4>(Channel::Normals), + accum_.getTexture<float4>(channel_out), temp_.getTexture<int>(Channel::Depth2), out.createTexture<float>(Channel::Depth), - out.createTexture<float4>(channel), + out.createTexture<float4>(channel_out), params_, stream ); } else if (is_float) { ftl::cuda::splat( - out.getTexture<float4>(Channel::Normals), - temp_.getTexture<float>(Channel::Colour2), + accum_.getTexture<float4>(Channel::Normals), + accum_.getTexture<float>(channel_out), temp_.getTexture<int>(Channel::Depth2), out.createTexture<float>(Channel::Depth), - out.createTexture<float>(channel), + out.createTexture<float>(channel_out), params_, stream ); } else { ftl::cuda::splat( - out.getTexture<float4>(Channel::Normals), - temp_.getTexture<uchar4>(Channel::Colour2), + accum_.getTexture<float4>(Channel::Normals), + accum_.getTexture<uchar4>(channel_out), temp_.getTexture<int>(Channel::Depth2), out.createTexture<float>(Channel::Depth), - out.createTexture<uchar4>(channel), + out.createTexture<uchar4>(channel_out), params_, stream ); } + } else { + // Swap accum frames directly to output. } } @@ -367,7 +369,7 @@ bool Splatter::render(ftl::rgbd::VirtualSource *src, ftl::rgbd::Frame &out, cuda } _dibr(stream); - _renderChannel(out, Channel::Colour, stream); + _renderChannel(out, Channel::Colour, Channel::Colour, stream); Channel chan = src->getChannel(); if (chan == Channel::Depth) @@ -377,7 +379,7 @@ bool Splatter::render(ftl::rgbd::VirtualSource *src, ftl::rgbd::Frame &out, cuda out.create<GpuMat>(Channel::Normals, Format<float4>(camera.width, camera.height)); // Render normal attribute - _renderChannel(out, Channel::Normals, stream); + _renderChannel(out, Channel::Normals, Channel::Normals, stream); // Convert normal to single float value temp_.create<GpuMat>(Channel::Colour, Format<uchar4>(camera.width, camera.height)); @@ -394,6 +396,11 @@ bool Splatter::render(ftl::rgbd::VirtualSource *src, ftl::rgbd::Frame &out, cuda //{ // cv::cuda::swap(temp_.get<GpuMat>(Channel::Contribution), out.create<GpuMat>(Channel::Contribution)); //} + else if (chan == Channel::Density) { + out.create<GpuMat>(chan, Format<float>(camera.width, camera.height)); + out.get<GpuMat>(chan).setTo(cv::Scalar(0.0f), cvstream); + _renderChannel(out, Channel::Depth, Channel::Density, stream); + } else if (chan == Channel::Right) { Eigen::Affine3f transform(Eigen::Translation3f(camera.baseline,0.0f,0.0f)); @@ -405,7 +412,7 @@ bool Splatter::render(ftl::rgbd::VirtualSource *src, ftl::rgbd::Frame &out, cuda out.get<GpuMat>(Channel::Right).setTo(background_, cvstream); _dibr(stream); // Need to re-dibr due to pose change - _renderChannel(out, Channel::Right, stream); + _renderChannel(out, Channel::Right, Channel::Right, stream); } else if (chan != Channel::None) { if (ftl::rgbd::isFloatChannel(chan)) { out.create<GpuMat>(chan, Format<float>(camera.width, camera.height)); @@ -414,7 +421,7 @@ bool Splatter::render(ftl::rgbd::VirtualSource *src, ftl::rgbd::Frame &out, cuda out.create<GpuMat>(chan, Format<uchar4>(camera.width, camera.height)); out.get<GpuMat>(chan).setTo(background_, cvstream); } - _renderChannel(out, chan, stream); + _renderChannel(out, chan, chan, stream); } return true; diff --git a/components/rgbd-sources/include/ftl/rgbd/frame.hpp b/components/rgbd-sources/include/ftl/rgbd/frame.hpp index e9036fd6cad9ddf50d96dd96956d99a920c6abb0..45bf3f4a9b8f862e3d70c22abfcddb096855d7c2 100644 --- a/components/rgbd-sources/include/ftl/rgbd/frame.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/frame.hpp @@ -181,7 +181,7 @@ template <> cv::cuda::GpuMat &Frame::create(ftl::rgbd::Channel c); template <typename T> ftl::cuda::TextureObject<T> &Frame::getTexture(ftl::rgbd::Channel c) { - if (!channels_.has(c)) throw ftl::exception("Texture channel does not exist"); + if (!channels_.has(c)) throw ftl::exception(ftl::Formatter() << "Texture channel does not exist: " << (int)c); if (!gpu_.has(c)) throw ftl::exception("Texture channel is not on GPU"); auto &m = _get(c);