Skip to content
Snippets Groups Projects
Commit e46b4c94 authored by Lukas Werner's avatar Lukas Werner
Browse files

Cleaned up image output logic

parent b45c0c49
Branches
Tags
No related merge requests found
...@@ -271,20 +271,22 @@ std::string Raytracer::getOutputFilename(const std::string& base, size_t timeste ...@@ -271,20 +271,22 @@ std::string Raytracer::getOutputFilename(const std::string& base, size_t timeste
return fileNameStream.str(); return fileNameStream.str();
} }
/*!\brief Writes the tBuffer to a file in the tBuffer output directory. /*!\brief Writes the depth values of the intersections buffer to an image file in the tBuffer output directory.
* \param tBuffer Buffer with t values as generated in generateImage(...). * \param intersectionsBuffer Buffer with intersection info for each pixel.
* \param timestep Timestep this image is from. * \param timestep Timestep this image is from.
* \param isGlobalImage Whether this image is the fully stitched together one. * \param isGlobalImage Whether this image is the fully stitched together one.
*/ */
void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, size_t timestep, bool isGlobalImage) const { void Raytracer::writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
writeTBufferToFile(tBuffer, getOutputFilename("tbuffer", timestep, isGlobalImage)); size_t timestep, bool isGlobalImage) const {
writeDepthsToFile(intersectionsBuffer, getOutputFilename("tbuffer", timestep, isGlobalImage));
} }
/*!\brief Writes the tBuffer to a file in the tBuffer output directory. /*!\brief Writes the depth values of the intersections buffer to an image file in the tBuffer output directory.
* \param tBuffer Buffer with t values as generated in generateImage(...). * \param intersectionsBuffer Buffer with intersection info for each pixel.
* \param fileName Name of the output file. * \param fileName Name of the output file.
*/ */
void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std::string& fileName) const { void Raytracer::writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
const std::string& fileName) const {
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
real_t inf = std::numeric_limits<real_t>::max(); real_t inf = std::numeric_limits<real_t>::max();
...@@ -294,10 +296,7 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std ...@@ -294,10 +296,7 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std
for (size_t x = 0; x < pixelsHorizontal_; x++) { for (size_t x = 0; x < pixelsHorizontal_; x++) {
for (size_t y = 0; y < pixelsVertical_; y++) { for (size_t y = 0; y < pixelsVertical_; y++) {
size_t i = coordinateToArrayIndex(x, y); size_t i = coordinateToArrayIndex(x, y);
real_t t = tBuffer[i]; real_t t = intersectionsBuffer[i].t;
//if (t > t_max && !realIsIdentical(t, inf)) {
// t_max = t;
//}
if (t < t_min) { if (t < t_min) {
t_min = t; t_min = t;
} }
...@@ -318,7 +317,7 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std ...@@ -318,7 +317,7 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std
for (size_t x = 0; x < pixelsHorizontal_; x++) { for (size_t x = 0; x < pixelsHorizontal_; x++) {
size_t i = coordinateToArrayIndex(x, y); size_t i = coordinateToArrayIndex(x, y);
u_char g = 0; u_char g = 0;
real_t t = tBuffer[i]; real_t t = intersectionsBuffer[i].t;
if (realIsIdentical(t, inf)) { if (realIsIdentical(t, inf)) {
g = (u_char)0; g = (u_char)0;
} else { } else {
...@@ -336,36 +335,37 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std ...@@ -336,36 +335,37 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std
} }
} }
/*!\brief Writes a image buffer to a file in the image output directory. /*!\brief Writes the image of the current intersection buffer to a file in the image output directory.
* \param imageBuffer Buffer with color vectors. * \param intersectionsBuffer Buffer with intersection info for each pixel.
* \param timestep Timestep this image is from. * \param timestep Timestep this image is from.
* \param isGlobalImage Whether this image is the fully stitched together one. * \param isGlobalImage Whether this image is the fully stitched together one.
*/ */
void Raytracer::writeImageBufferToFile(const std::vector<Color>& imageBuffer, size_t timestep, bool isGlobalImage) const { void Raytracer::writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep,
writeImageBufferToFile(imageBuffer, getOutputFilename("image", timestep, isGlobalImage)); bool isGlobalImage) const {
writeImageToFile(intersectionsBuffer, getOutputFilename("image", timestep, isGlobalImage));
} }
/*!\brief Writes the image buffer to a file in the image output directory. /*!\brief Writes the image of the current intersection buffer to a file in the image output directory.
* \param imageBuffer Buffer with color vectors. * \param intersectionsBuffer Buffer with intersection info for each pixel.
* \param fileName Name of the output file. * \param fileName Name of the output file.
*/ */
void Raytracer::writeImageBufferToFile(const std::vector<Color>& imageBuffer, const std::string& fileName) const { void Raytracer::writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
const std::string& fileName) const {
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
fs::path dir (getImageOutputDirectory()); fs::path dir = getImageOutputDirectory();
fs::path file (fileName); fs::path file (fileName);
fs::path fullPath = dir / file; fs::path fullPath = dir / file;
std::vector<u_char> lodeImageBuffer(pixelsHorizontal_*pixelsVertical_*3); std::vector<u_char> lodeImageBuffer(pixelsHorizontal_*pixelsVertical_*3);
uint32_t l = 0; uint32_t l = 0;
for (size_t y = pixelsVertical_-1; y > 0; y--) { for (int y = pixelsVertical_-1; y >= 0; y--) {
for (size_t x = 0; x < pixelsHorizontal_; x++) { for (size_t x = 0; x < pixelsHorizontal_; x++) {
size_t i = coordinateToArrayIndex(x, y); size_t i = coordinateToArrayIndex(x, uint_c(y));
const Color& color = imageBuffer[i]; u_char r = (u_char)(255 * intersectionsBuffer[i].r);
u_char r = (u_char)(255 * color[0]); u_char g = (u_char)(255 * intersectionsBuffer[i].g);
u_char g = (u_char)(255 * color[1]); u_char b = (u_char)(255 * intersectionsBuffer[i].b);
u_char b = (u_char)(255 * color[2]);
lodeImageBuffer[l] = r; lodeImageBuffer[l] = r;
lodeImageBuffer[l+1] = g; lodeImageBuffer[l+1] = g;
lodeImageBuffer[l+2] = b; lodeImageBuffer[l+2] = b;
...@@ -460,6 +460,35 @@ void Raytracer::syncImageUsingMPIGather(std::vector<BodyIntersectionInfo>& inter ...@@ -460,6 +460,35 @@ void Raytracer::syncImageUsingMPIGather(std::vector<BodyIntersectionInfo>& inter
if (tt != NULL) tt->stop("Reduction"); if (tt != NULL) tt->stop("Reduction");
} }
void Raytracer::localOutput(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep, WcTimingTree* tt) {
if (getImageOutputEnabled()) {
if (getLocalImageOutputEnabled()) {
if (tt != NULL) tt->start("Local Output");
writeImageToFile(intersectionsBuffer, timestep);
if (tt != NULL) tt->stop("Local Output");
}
}
if (getTBufferOutputEnabled()) {
if (tt != NULL) tt->start("Local Output");
writeDepthsToFile(intersectionsBuffer, timestep);
if (tt != NULL) tt->stop("Local Output");
}
}
void Raytracer::output(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep, WcTimingTree* tt) {
WALBERLA_ROOT_SECTION() {
if (tt != NULL) tt->start("Output");
if (getImageOutputEnabled()) {
writeImageToFile(intersectionsBuffer, timestep, true);
}
if (getTBufferOutputEnabled()) {
writeDepthsToFile(intersectionsBuffer, timestep, true);
}
if (tt != NULL) tt->stop("Output");
}
}
uint64_t Raytracer::naiveIntersectionTestCount = 0; uint64_t Raytracer::naiveIntersectionTestCount = 0;
} }
......
...@@ -102,7 +102,7 @@ private: ...@@ -102,7 +102,7 @@ private:
Lighting lighting_; //!< The lighting of the scene. Lighting lighting_; //!< The lighting of the scene.
Color backgroundColor_; //!< Background color of the scene. Color backgroundColor_; //!< Background color of the scene.
real_t blockAABBIntersectionPadding_; /*!< The padding applied in block AABB intersection pretesting, as real_t blockAABBIntersectionPadding_; /*!< The padding applied in block AABB intersection pretesting, as
some objects within a block might protrude from the block's AABB.*/ * some objects within a block might protrude from the block's AABB.*/
bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to file. bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to file.
std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory. std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory.
...@@ -184,14 +184,24 @@ public: ...@@ -184,14 +184,24 @@ public:
void setupMPI_(); void setupMPI_();
private: private:
void localOutput(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep,
WcTimingTree* tt = NULL);
void output(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep,
WcTimingTree* tt = NULL);
std::string getOutputFilename(const std::string& base, size_t timestep, bool isGlobalImage) const; std::string getOutputFilename(const std::string& base, size_t timestep, bool isGlobalImage) const;
void writeTBufferToFile(const std::vector<real_t>& tBuffer, size_t timestep, bool isGlobalImage = false) const; void writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
void writeTBufferToFile(const std::vector<real_t>& tBuffer, const std::string& fileName) const; size_t timestep, bool isGlobalImage = false) const;
void writeImageBufferToFile(const std::vector<Color>& imageBuffer, size_t timestep, bool isGlobalImage = false) const; void writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
void writeImageBufferToFile(const std::vector<Color>& imageBuffer, const std::string& fileName) const; const std::string& fileName) const;
void writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
size_t timestep, bool isGlobalImage = false) const;
void writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer,
const std::string& fileName) const;
void syncImageUsingMPIReduce(std::vector<BodyIntersectionInfo>& intersectionsBuffer, WcTimingTree* tt = NULL); void syncImageUsingMPIReduce(std::vector<BodyIntersectionInfo>& intersectionsBuffer, WcTimingTree* tt = NULL);
void syncImageUsingMPIGather(std::vector<BodyIntersectionInfo>& intersections, std::vector<BodyIntersectionInfo>& intersectionsBuffer, WcTimingTree* tt); void syncImageUsingMPIGather(std::vector<BodyIntersectionInfo>& intersections,
std::vector<BodyIntersectionInfo>& intersectionsBuffer, WcTimingTree* tt);
inline bool isPlaneVisible(const PlaneID plane, const Ray& ray) const; inline bool isPlaneVisible(const PlaneID plane, const Ray& ray) const;
inline size_t coordinateToArrayIndex(size_t x, size_t y) const; inline size_t coordinateToArrayIndex(size_t x, size_t y) const;
...@@ -679,6 +689,8 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { ...@@ -679,6 +689,8 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) {
} }
} }
localOutput(intersectionsBuffer, timestep, tt);
// Reduction with different methods only makes sense if actually using MPI. // Reduction with different methods only makes sense if actually using MPI.
// Besides that, the MPI reduce routine does not compile without MPI. // Besides that, the MPI reduce routine does not compile without MPI.
WALBERLA_MPI_SECTION() { WALBERLA_MPI_SECTION() {
...@@ -695,36 +707,8 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { ...@@ -695,36 +707,8 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) {
syncImageUsingMPIGather(intersections, intersectionsBuffer, tt); syncImageUsingMPIGather(intersections, intersectionsBuffer, tt);
} }
if (tt != NULL) tt->start("Output"); output(intersectionsBuffer, timestep, tt);
if (getImageOutputEnabled()) {
if (getLocalImageOutputEnabled()) {
writeImageBufferToFile(imageBuffer, timestep);
}
WALBERLA_ROOT_SECTION() {
std::vector<Color> fullImageBuffer(pixelsHorizontal_ * pixelsVertical_, backgroundColor_);
for (auto& info: intersectionsBuffer) {
fullImageBuffer[coordinateToArrayIndex(info.imageX, info.imageY)] = Color(real_c(info.r), real_c(info.g), real_c(info.b));
}
writeImageBufferToFile(fullImageBuffer, timestep, true);
}
}
if (getTBufferOutputEnabled()) {
writeTBufferToFile(tBuffer, timestep);
WALBERLA_ROOT_SECTION() {
std::vector<real_t> fullTBuffer(pixelsHorizontal_ * pixelsVertical_, inf);
for (auto& info: intersectionsBuffer) {
fullTBuffer[coordinateToArrayIndex(info.imageX, info.imageY)] = real_c(info.t);
}
writeTBufferToFile(fullTBuffer, timestep, true);
}
}
if (tt != NULL) tt->stop("Output");
if (tt != NULL) tt->stop("Raytracing"); if (tt != NULL) tt->stop("Raytracing");
} }
......
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