diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp index 49e7ecc228963a2c2bef3278ca43e0ba6f41e1e0..ac75c6f930ffaf2803bd706e4839cafa9b79f02f 100644 --- a/src/pe/raytracing/Raytracer.cpp +++ b/src/pe/raytracing/Raytracer.cpp @@ -271,20 +271,22 @@ std::string Raytracer::getOutputFilename(const std::string& base, size_t timeste return fileNameStream.str(); } -/*!\brief Writes the tBuffer to a file in the tBuffer output directory. - * \param tBuffer Buffer with t values as generated in generateImage(...). +/*!\brief Writes the depth values of the intersections buffer to an image file in the tBuffer output directory. + * \param intersectionsBuffer Buffer with intersection info for each pixel. * \param timestep Timestep this image is from. * \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 { - writeTBufferToFile(tBuffer, getOutputFilename("tbuffer", timestep, isGlobalImage)); +void Raytracer::writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, + size_t timestep, bool isGlobalImage) const { + writeDepthsToFile(intersectionsBuffer, getOutputFilename("tbuffer", timestep, isGlobalImage)); } -/*!\brief Writes the tBuffer to a file in the tBuffer output directory. - * \param tBuffer Buffer with t values as generated in generateImage(...). +/*!\brief Writes the depth values of the intersections buffer to an image file in the tBuffer output directory. + * \param intersectionsBuffer Buffer with intersection info for each pixel. * \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; real_t inf = std::numeric_limits<real_t>::max(); @@ -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 y = 0; y < pixelsVertical_; y++) { size_t i = coordinateToArrayIndex(x, y); - real_t t = tBuffer[i]; - //if (t > t_max && !realIsIdentical(t, inf)) { - // t_max = t; - //} + real_t t = intersectionsBuffer[i].t; if (t < t_min) { t_min = t; } @@ -318,7 +317,7 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std for (size_t x = 0; x < pixelsHorizontal_; x++) { size_t i = coordinateToArrayIndex(x, y); u_char g = 0; - real_t t = tBuffer[i]; + real_t t = intersectionsBuffer[i].t; if (realIsIdentical(t, inf)) { g = (u_char)0; } else { @@ -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. - * \param imageBuffer Buffer with color vectors. +/*!\brief Writes the image of the current intersection buffer to a file in the image output directory. + * \param intersectionsBuffer Buffer with intersection info for each pixel. * \param timestep Timestep this image is from. * \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 { - writeImageBufferToFile(imageBuffer, getOutputFilename("image", timestep, isGlobalImage)); +void Raytracer::writeImageToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, size_t timestep, + bool isGlobalImage) const { + writeImageToFile(intersectionsBuffer, getOutputFilename("image", timestep, isGlobalImage)); } -/*!\brief Writes the image buffer to a file in the image output directory. - * \param imageBuffer Buffer with color vectors. +/*!\brief Writes the image of the current intersection buffer to a file in the image output directory. + * \param intersectionsBuffer Buffer with intersection info for each pixel. * \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; - - fs::path dir (getImageOutputDirectory()); + + fs::path dir = getImageOutputDirectory(); fs::path file (fileName); fs::path fullPath = dir / file; std::vector<u_char> lodeImageBuffer(pixelsHorizontal_*pixelsVertical_*3); 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++) { - size_t i = coordinateToArrayIndex(x, y); - const Color& color = imageBuffer[i]; - u_char r = (u_char)(255 * color[0]); - u_char g = (u_char)(255 * color[1]); - u_char b = (u_char)(255 * color[2]); + size_t i = coordinateToArrayIndex(x, uint_c(y)); + u_char r = (u_char)(255 * intersectionsBuffer[i].r); + u_char g = (u_char)(255 * intersectionsBuffer[i].g); + u_char b = (u_char)(255 * intersectionsBuffer[i].b); lodeImageBuffer[l] = r; lodeImageBuffer[l+1] = g; lodeImageBuffer[l+2] = b; @@ -460,6 +460,35 @@ void Raytracer::syncImageUsingMPIGather(std::vector<BodyIntersectionInfo>& inter 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; } diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h index 3b64bf17c1d2c7a30c5219b85c8926e721d15c6b..377f37ad2c9d49fcf4678974d4bfeae03db5d9a9 100644 --- a/src/pe/raytracing/Raytracer.h +++ b/src/pe/raytracing/Raytracer.h @@ -102,7 +102,7 @@ private: Lighting lighting_; //!< The lighting of the scene. Color backgroundColor_; //!< Background color of the scene. 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. std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory. @@ -184,14 +184,24 @@ public: void setupMPI_(); 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; - void writeTBufferToFile(const std::vector<real_t>& tBuffer, size_t timestep, bool isGlobalImage = false) const; - void writeTBufferToFile(const std::vector<real_t>& tBuffer, const std::string& fileName) const; - void writeImageBufferToFile(const std::vector<Color>& imageBuffer, size_t timestep, bool isGlobalImage = false) const; - void writeImageBufferToFile(const std::vector<Color>& imageBuffer, const std::string& fileName) const; + void writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, + size_t timestep, bool isGlobalImage = false) const; + void writeDepthsToFile(const std::vector<BodyIntersectionInfo>& intersectionsBuffer, + 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 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 size_t coordinateToArrayIndex(size_t x, size_t y) const; @@ -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. // Besides that, the MPI reduce routine does not compile without MPI. WALBERLA_MPI_SECTION() { @@ -695,36 +707,8 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) { syncImageUsingMPIGather(intersections, intersectionsBuffer, tt); } - if (tt != NULL) tt->start("Output"); - 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); - } - } + output(intersectionsBuffer, timestep, tt); - if (tt != NULL) tt->stop("Output"); if (tt != NULL) tt->stop("Raytracing"); }