Commit d9cedca6 authored by Lukas Werner's avatar Lukas Werner
Browse files

Added tbuffer output functionality to raytracer

parent a787d527
Pipeline #6888 failed with stage
in 4 minutes and 5 seconds
......@@ -19,6 +19,7 @@
//======================================================================================================================
#include "Raytracer.h"
#include <boost/filesystem.hpp>
using namespace walberla;
......@@ -41,13 +42,14 @@ namespace raytracing {
* \param upVector Vector indicating the upwards direction of the camera.
*/
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
uint8_t pixelsHorizontal, uint8_t pixelsVertical,
size_t pixelsHorizontal, size_t pixelsVertical,
real_t fov_vertical,
const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector)
: forest_(forest), storageID_(storageID),
pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical),
fov_vertical_(fov_vertical),
cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector)
cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector),
tBufferOutputEnabled_(false)
{
setupView_();
}
......@@ -58,16 +60,21 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
* \param storageID Storage ID of the block data storage the raytracer operates on.
* \param config Config block for the raytracer.
*
* The config block has to contain image_x (int), image_y (int) and fov_vertical (real, in degrees)
* parameters, additionally one block with x, y and z values (real) for each of camera,
* lookAt and the upVector.
* The config block has to contain image_x (int), image_y (int), fov_vertical (real, in degrees)
* and tbuffer_output_directory (string) parameters. Additionally one block with x, y and z values (real)
* for each of camera, lookAt and the upVector.
*/
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const Config::BlockHandle& config) : forest_(forest), storageID_(storageID) {
WALBERLA_CHECK(config.isValid(), "No valid config passed to raytracer");
pixelsHorizontal_ = config.getParameter<uint8_t>("image_x");
pixelsVertical_ = config.getParameter<uint8_t>("image_y");
pixelsHorizontal_ = config.getParameter<size_t>("image_x");
pixelsVertical_ = config.getParameter<size_t>("image_y");
fov_vertical_ = config.getParameter<real_t>("fov_vertical");
if (config.isDefined("tbuffer_output_directory")) {
setTBufferOutputEnabled(true);
setTBufferOutputDirectory(config.getParameter<std::string>("tbuffer_output_directory"));
WALBERLA_LOG_INFO_ON_ROOT("t buffers will be written to " << getTBufferOutputDirectory() << ".");
}
const Config::BlockHandle cameraConf = config.getBlock("camera");
WALBERLA_CHECK(cameraConf.isValid(), "No camera block found in config");
......@@ -109,6 +116,62 @@ void Raytracer::setupView_() {
pixelHeight = viewingPlaneHeight / real_c(pixelsVertical_);
}
/*!\brief Writes the tBuffer to a file in the tBuffer output directory.
* \param tBuffer Buffer with t values as generated in rayTrace(...).
*/
void Raytracer::writeTBufferToFile(const std::map<Coordinates, real_t, CoordinatesComparator>& tBuffer) const {
mpi::MPIRank rank = mpi::MPIManager::instance()->rank();
std::string fileName = "tbuffer_" + std::to_string(rank) + ".ppm";
writeTBufferToFile(tBuffer, fileName);
}
/*!\brief Writes the tBuffer to a file in the tBuffer output directory.
* \param tBuffer Buffer with t values as generated in rayTrace(...).
* \param fileName Name of the output file.
*/
void Raytracer::writeTBufferToFile(const std::map<Coordinates, real_t, CoordinatesComparator>& tBuffer, const std::string& fileName) const {
namespace fs = boost::filesystem;
real_t t_max = 1;
real_t t_min = INFINITY;
for (size_t x = 0; x < pixelsHorizontal_; x++) {
for (size_t y = 0; y < pixelsVertical_; y++) {
Coordinates c = {x, y};
real_t t = tBuffer.at(c);
if (t > t_max && !realIsIdentical(t, INFINITY)) {
t_max = t;
}
if (t < t_min) {
t_min = t;
}
}
}
if (realIsIdentical(t_min, INFINITY)) t_min = 0;
fs::path dir (getTBufferOutputDirectory());
WALBERLA_CHECK(fs::exists(dir) && fs::is_directory(dir), "Tbuffer output directory is invalid.");
fs::path file (fileName);
fs::path fullPath = dir / file;
std::ofstream ofs(fullPath.string<std::string>(), std::ios::out | std::ios::binary);
ofs << "P6\n" << pixelsHorizontal_ << " " << pixelsVertical_ << "\n255\n";
for (size_t y = pixelsVertical_-1; y > 0; y--) {
for (size_t x = 0; x < pixelsHorizontal_; x++) {
Coordinates c = {x, y};
char r = 0, g = 0, b = 0;
real_t t = tBuffer.at(c);
if (realIsIdentical(t, INFINITY)) {
r = g = b = (char)255;
} else {
r = g = b = (char)(200 * ((t-t_min)/(t_max-t_min)));
}
ofs << r << g << b;
}
}
ofs.close();
}
}
}
}
......@@ -61,7 +61,7 @@ public:
/*!\name Constructors */
//@{
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
uint8_t pixelsHorizontal, uint8_t pixelsVertical,
size_t pixelsHorizontal, size_t pixelsVertical,
real_t fov_vertical,
const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector);
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
......@@ -74,13 +74,15 @@ private:
const shared_ptr<BlockStorage> forest_; //!< The BlockForest the raytracer operates on.
BlockDataID storageID_; /*!< The storage ID of the block data storage the raytracer operates
on.*/
uint8_t pixelsHorizontal_; //!< The horizontal amount of pixels of the generated image.
uint8_t pixelsVertical_; //!< The vertical amount of pixels of the generated image.
size_t pixelsHorizontal_; //!< The horizontal amount of pixels of the generated image.
size_t pixelsVertical_; //!< The vertical amount of pixels of the generated image.
real_t fov_vertical_; //!< The vertical field-of-view of the camera.
Vec3 cameraPosition_; //!< The position of the camera in the global world frame.
Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame,
marks the center of the view plane.*/
Vec3 upVector_; //!< The vector indicating the upwards direction of the camera.
bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to a file
std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory
//@}
Vec3 n; // normal vector of viewing plane
......@@ -97,19 +99,31 @@ private:
public:
/*!\name Get functions */
//@{
inline uint8_t getPixelsHorizontal() const;
inline uint8_t getPixelsVertical() const;
inline real_t getFOVVertical() const;
inline const Vec3& getCameraPosition() const;
inline const Vec3& getLookAtPoint() const;
inline const Vec3& getUpVector() const;
inline size_t getPixelsHorizontal() const;
inline size_t getPixelsVertical() const;
inline real_t getFOVVertical() const;
inline const Vec3& getCameraPosition() const;
inline const Vec3& getLookAtPoint() const;
inline const Vec3& getUpVector() const;
inline const bool getTBufferOutputEnabled() const;
inline const std::string& getTBufferOutputDirectory() const;
//@}
/*!\name Set functions */
//@{
inline void setTBufferOutputEnabled(const bool enabled);
inline void setTBufferOutputDirectory(const std::string& path);
//@}
/*!\name Functions */
//@{
void setupView_();
template <typename BodyTypeTuple>
void rayTrace(const size_t timestep) const;
void rayTrace(const size_t timestep) const;
private:
void writeTBufferToFile(const std::map<Coordinates, real_t, CoordinatesComparator>& tBuffer) const;
void writeTBufferToFile(const std::map<Coordinates, real_t, CoordinatesComparator>& tBuffer, const std::string& fileName) const;
//@}
};
......@@ -117,7 +131,7 @@ public:
*
* \return The horizontal amount of pixels of the generated image.
*/
inline uint8_t Raytracer::getPixelsHorizontal() const {
inline size_t Raytracer::getPixelsHorizontal() const {
return pixelsHorizontal_;
}
......@@ -125,7 +139,7 @@ inline uint8_t Raytracer::getPixelsHorizontal() const {
*
* \return The vertical amount of pixels of the generated image.
*/
inline uint8_t Raytracer::getPixelsVertical() const {
inline size_t Raytracer::getPixelsVertical() const {
return pixelsVertical_;
}
......@@ -168,6 +182,36 @@ inline const Vec3& Raytracer::getUpVector() const {
return upVector_;
}
/*!\brief Returns true if tbuffer output to a file is enabled.
*
* \return True if tbuffer output enabled, otherwise false.
*/
inline const bool Raytracer::getTBufferOutputEnabled() const {
return tBufferOutputEnabled_;
}
/*!\brief Returns the directory where the tbuffer output file will be saved in.
*
* \return Path to the tbuffer output directory.
*/
inline const std::string& Raytracer::getTBufferOutputDirectory() const {
return tBufferOutputDirectory_;
}
/*!\brief Enabled / disable outputting the tBuffer to a file in the specified directory.
* \param enabled Set to true / false to enable / disable tbuffer output.
*/
inline void Raytracer::setTBufferOutputEnabled(const bool enabled) {
tBufferOutputEnabled_ = enabled;
}
/*!\brief Enabled / disable outputting the tBuffer to a file in the specified directory.
* \param enabled Set to true / false to enable / disable tbuffer output.
*/
inline void Raytracer::setTBufferOutputDirectory(const std::string& path) {
tBufferOutputDirectory_ = path;
}
/*!\brief Does one raytracing step.
*
* \param timestep The timestep after which the raytracing starts.
......@@ -293,10 +337,9 @@ void Raytracer::rayTrace(const size_t timestep) const {
WALBERLA_LOG_INFO("#particles visible: " << visibleBodyIDs.size());
//WALBERLA_LOG_INFO_ON_ROOT("#gatheredIntersections: " << gatheredIntersections.size());
#ifdef __APPLE__
//mpi::MPIRank rank = mpi::MPIManager::instance()->rank();
//writeTBufferToFile(tBuffer, idBuffer, pixelsHorizontal_, pixelsVertical_, "/Users/ng/Desktop/walberla/tbuffer_" + std::to_string(rank) + ".ppm");
#endif
if (getTBufferOutputEnabled()) {
writeTBufferToFile(tBuffer);
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment